Exemplo n.º 1
0
//
// D_OpenDiskFile
//
// Opens and reads a disk file.
//
diskfile_t *D_OpenDiskFile(const char *filename)
{
   diskfile_t *df;
   diskfileint_t *dfi;
   uint32_t temp;

   // allocate a diskfile structure and internal fields
   df  = estructalloc(diskfile_t,    1);
   dfi = estructalloc(diskfileint_t, 1);

   df->opaque = dfi;

   // open the physical file
   if(!(dfi->f = fopen(filename, "rb")))
      I_Error("D_OpenDiskFile: couldn't open file %s\n", filename);

   // read number of files in the directory
   if(fread(&temp, sizeof(temp), 1, dfi->f) < 1)
      I_Error("D_OpenDiskFile: couldn't read number of entries\n");

   // make big-endian file value host-endian
   dfi->numfiles = SwapBigULong(temp);

   // allocate directory
   dfi->entries = estructalloc(diskentry_t, dfi->numfiles);

   // read directory entries
   if(!D_readDiskFileDirectory(dfi))
      I_Error("D_OpenDiskFile: failed reading directory\n");

   return df;
}
Exemplo n.º 2
0
//
// PushRange
//
// Pushes the current palette translation range into the parser state object's
// list of ranges.
//
static void PushRange(tr_pstate_t *pstate)
{
   tr_range_t *newrange = estructalloc(tr_range_t, 1);

   newrange->srcbegin = eclamp(pstate->srcbegin, 0, 255);
   newrange->srcend   = eclamp(pstate->srcend,   0, 255);
   newrange->dstbegin = eclamp(pstate->dstbegin, 0, 255);
   newrange->dstend   = eclamp(pstate->dstend,   0, 255);

   // normalize ranges
   if(newrange->srcbegin > newrange->srcend)
   {
      int temp = newrange->srcbegin;
      newrange->srcbegin = newrange->srcend;
      newrange->srcend   = temp;
   }

   if(newrange->dstbegin > newrange->dstend)
   {
      int temp = newrange->dstbegin;
      newrange->dstbegin = newrange->dstend;
      newrange->dstend   = temp;
   }

   newrange->next = pstate->ranges;
   pstate->ranges = newrange;
};
Exemplo n.º 3
0
//
// W_FindAllMapsInLevelWad
//
// haleyjd 10/23/10: Finds all valid maps in a wad directory and returns them
// as a sorted set of wadlevel_t's.
//
wadlevel_t *W_FindAllMapsInLevelWad(WadDirectory *dir)
{
    int i, format;
    wadlevel_t *levels = NULL;
    int numlevels;
    int numlevelsalloc;
    int          numlumps = dir->getNumLumps();
    lumpinfo_t **lumpinfo = dir->getLumpInfo();

    // start out with a small set of levels
    numlevels = 0;
    numlevelsalloc = 8;
    levels = estructalloc(wadlevel_t, numlevelsalloc);

    // find all the lumps
    for(i = 0; i < numlumps; i++)
    {
        if((format = P_CheckLevel(dir, i)) != LEVEL_FORMAT_INVALID)
        {
            // grow the array if needed, leaving one at the end
            if(numlevels + 1 >= numlevelsalloc)
            {
                numlevelsalloc *= 2;
                levels = erealloc(wadlevel_t *, levels, numlevelsalloc * sizeof(wadlevel_t));
            }
            memset(&levels[numlevels], 0, sizeof(wadlevel_t));
            levels[numlevels].dir = dir;
            levels[numlevels].lumpnum = i;
            strncpy(levels[numlevels].header, lumpinfo[i]->name, 9);
            ++numlevels;

            // skip past the level's directory entries
            i += (format == LEVEL_FORMAT_HEXEN ? 11 : 10);
        }
    }
Exemplo n.º 4
0
//
// P_AddActiveCeiling()
//
// Adds a ceiling to the head of the list of active ceilings
//
// Passed the ceiling motion structure
// Returns nothing
//
void P_AddActiveCeiling(CeilingThinker *ceiling)
{
   // ioanch 20160306
   if(demo_compatibility || P_LevelIsVanillaHexen())
   {
      for(int i = 0; i < vanilla_MAXCEILINGS; ++i)
      {
         if(!vanilla_activeceilings[i])
         {
            vanilla_activeceilings[i] = ceiling;
            break;
         }
      }
      return;
   }

   // ioanch: normal setup
   ceilinglist_t *list = estructalloc(ceilinglist_t, 1);
   list->ceiling = ceiling;
   ceiling->list = list;
   if((list->next = activeceilings))
      list->next->prev = &list->next;
   list->prev = &activeceilings;
   activeceilings = list;

}
Exemplo n.º 5
0
//
// Adds a scroll thinker to the list
//
void ScrollThinker::addScroller()
{
   list = estructalloc(scrollerlist_t, 1);
   list->scroller = this;
   if((list->next = scrollers))
      list->next->prev = &list->next;
   list->prev = &scrollers;
   scrollers = list;
}
Exemplo n.º 6
0
//
// E_CreateString
//
// Creates an EDF string object with the given value which is hashable
// by one or two different keys. The mnemonic key is required and must
// be 128 or fewer characters long. The numeric key is optional. If a
// negative value is passed as the numeric key, the object will not be 
// added to the numeric hash table.
//
edf_string_t *E_CreateString(const char *value, const char *key, int num)
{
   int keyval;
   edf_string_t *newStr;

   if((newStr = E_StringForName(key)))
   {
      // Modify existing object.
      E_ReplaceString(newStr->string, estrdup(value));

      // Modify numeric id and rehash object if necessary
      if(num != newStr->numkey)
      {
         // If old key is >= 0, must remove from hash first
         if(newStr->numkey >= 0)
            E_DelStringFromNumHash(newStr);
         
         // Set new key
         newStr->numkey = num;
         
         // If new key >= 0, add back to hash
         if(newStr->numkey >= 0)
            E_AddStringToNumHash(newStr);
      }
   }
   else
   {
      // Create a new string object
      newStr = estructalloc(edf_string_t, 1);
      
      // copy keys into string object
      if(strlen(key) >= sizeof(newStr->key))
      {
         E_EDFLoggedErr(2, 
            "E_CreateString: invalid string mnemonic '%s'\n", key);
      }
      strncpy(newStr->key, key, sizeof(newStr->key));
      
      newStr->numkey = num;
      
      // duplicate value
      newStr->string = estrdup(value);
      
      // add to hash tables
      
      keyval = D_HashTableKey(newStr->key) % NUM_EDFSTR_CHAINS;
      newStr->next = edf_str_chains[keyval];
      edf_str_chains[keyval] = newStr;
      
      // numeric key is not required
      if(num >= 0)
         E_AddStringToNumHash(newStr);
   }

   return newStr;
}
Exemplo n.º 7
0
//
// G_CreateAxisActionVars
//
// Build console variables for all axis action bindings.
//
void G_CreateAxisActionVars()
{
   for(int i = 0; i < HALGamePad::MAXAXES; i++)
   {
      qstring     name;
      variable_t *variable;
      command_t  *command;

      variable = estructalloc(variable_t, 1);
      variable->variable  = &axisActions[i];
      variable->v_default = NULL;
      variable->type      = vt_int;
      variable->min       = axis_none;
      variable->max       = axis_max - 1;
      variable->defines   = axisActionNames;

      command = estructalloc(command_t, 1);
      name << "g_axisaction" << i+1;
      command->name     = name.duplicate();
      command->type     = ct_variable;
      command->variable = variable;

      C_AddCommand(command);

      variable = estructalloc(variable_t, 1);
      variable->variable  = &axisOrientation[i];
      variable->v_default = NULL;
      variable->type      = vt_int;
      variable->min       = -1;
      variable->max       =  1;

      command = estructalloc(command_t, 1);
      name.clear() << "g_axisorientation" << i+1;
      command->name     = name.duplicate();
      command->type     = ct_variable;
      command->variable = variable;

      C_AddCommand(command);
   }
}
Exemplo n.º 8
0
//
// E_CollectInventory
//
// Pre-creates and hashes by name the inventory definitions, for purpose 
// of mutual and forward references.
//
void E_CollectInventory(cfg_t *cfg)
{
   static int currentID = 1;
   unsigned int i;
   unsigned int numInventory;    // number of inventory defs defined by the cfg
   inventory_t *newInvDefs  = NULL;

   // get number of inventory definitions defined by the cfg
   numInventory = cfg_size(cfg, EDF_SEC_INVENTORY);

   // echo counts
   E_EDFLogPrintf("\t\t%u inventory items defined\n", numInventory);

   if(numInventory)
   {
      // allocate inventory structures for the new thingtypes
      newInvDefs = estructalloc(inventory_t, numInventory);

      numInventoryDefs += numInventory;

      // create metatables
      for(i = 0; i < numInventory; i++)
         newInvDefs[i].meta = new MetaTable("inventory");
   }

   // build hash tables
   E_EDFLogPuts("\t\tBuilding inventory hash tables\n");
   
   // cycle through the thingtypes defined in the cfg
   for(i = 0; i < numInventory; i++)
   {
      cfg_t *invcfg = cfg_getnsec(cfg, EDF_SEC_INVENTORY, i);
      const char *name = cfg_title(invcfg);

      // This is a new inventory, whether or not one already exists by this name
      // in the hash table. For subsequent addition of EDF inventory defs at 
      // runtime, the hash table semantics of "find newest first" take care of 
      // overriding, while not breaking objects that depend on the original 
      // definition of the inventory type for inheritance purposes.
      inventory_t *inv = &newInvDefs[i];

      // initialize name
      inv->name = estrdup(name);

      // add to name hash
      inv_namehash.addObject(inv);

      // create ID number and add to hash table
      inv->numkey = currentID++;
      inv_numhash.addObject(inv);
   }
}
Exemplo n.º 9
0
//
// INStatsManager::addScore
//
// Add a new score to the table.
//
void INStatsManager::addScore(const char *levelkey, int score, int maxscore, 
                              int scoretype, int pnum)
{
   in_stat_t *newStat = estructalloc(in_stat_t, 1);

   newStat->levelkey   = estrdup(levelkey);
   newStat->value      = score;
   newStat->maxValue   = maxscore;
   newStat->recordType = scoretype;
   newStat->skill      = gameskill;
   newStat->playername = estrdup(players[pnum].name);
   
   pImpl->statsByLevelKey.addObject(newStat);
}
Exemplo n.º 10
0
//
// R_GetFreePolyNode
//
// Gets a node from the free list or allocates a new one.
//
static rpolynode_t *R_GetFreePolyNode()
{
   rpolynode_t *ret = NULL;

   if(polyNodeFreeList)
   {
      ret = polyNodeFreeList;
      polyNodeFreeList = polyNodeFreeList->children[0];
      memset(ret, 0, sizeof(*ret));
   }
   else
      ret = estructalloc(rpolynode_t, 1);

   return ret;
}
Exemplo n.º 11
0
//
// I_AddDeferredEvent
//
// haleyjd 03/06/13: Some received input events need to be deferred until at
// least one tic has passed before they are posted to the event queue.
// "Trigger" style keys such as mousewheel up and down are the chief offenders.
// Rather than shoehorning a bunch of code for this into I_GetEvent, it is
// now handled here uniformly for all event types.
//
static void I_AddDeferredEvent(const event_t &ev, int tic)
{
   deferredevent_t *de;

   if(i_deferredfreelist.head)
   {
      de = *i_deferredfreelist.head;
      i_deferredfreelist.remove(de);
   }
   else
      de = estructalloc(deferredevent_t, 1);

   de->ev  = ev;
   de->tic = tic;
   i_deferredevents.insert(de);
}
Exemplo n.º 12
0
//
// WadDirectory::reAllocLumpInfo
//
// Reallocate the lumpinfo array to contain the indicated number of pointers,
// and, if makelumps is true, will also allocate that number of new lumpinfo_t
// structures and return them.
//
lumpinfo_t *WadDirectory::reAllocLumpInfo(int numnew, int startlump)
{
    lumpinfo_t *newlumps = NULL;

    numlumps += numnew;

    // Fill in lumpinfo
    lumpinfo = erealloc(lumpinfo_t **, lumpinfo, numlumps * sizeof(lumpinfo_t *));

    // space for new lumps
    newlumps = estructalloc(lumpinfo_t, numlumps - startlump);

    // haleyjd: keep track of this allocation of lumps
    addInfoPtr(newlumps);

    // haleyjd: fill in new pointers here, instead of everywhere this is used.
    for(int i = startlump; i < numlumps; i++)
        lumpinfo[i] = newlumps + (i - startlump);

    return newlumps;
}
Exemplo n.º 13
0
//
// MetaKey
//
// If the given key string is already interned, the metakey_t structure that
// stores it will be returned. If not, it will be added to the collection of
// keys and hashed by name.
//
static metakey_t &MetaKey(const char *key)
{
   metakey_t *keyObj;
   unsigned int unmodHC = ENCStringHashKey::HashCode(key);

   // Do we already have this key?
   if(!(keyObj = metaKeyHash.objectForKey(key, unmodHC)))
   {
      keyObj = estructalloc(metakey_t, 1);

      // add it to the list
      metaKeys.add(keyObj);

      keyObj->key     = estrdup(key);
      keyObj->index   = metaKeys.getLength() - 1;
      keyObj->unmodHC = unmodHC;

      // check for table overload, and hash it
      MetaHashRebuild<>(metaKeyHash);
      metaKeyHash.addObject(keyObj, keyObj->unmodHC);
   }

   return *keyObj;
}
Exemplo n.º 14
0
//
// INStatsMgrPimpl::parseCSVScores
//
// Parse the CSV input file used to save top scores.
//
void INStatsMgrPimpl::parseCSVScores(char *input)
{
   Collection<qstring> fields;

   // Go past the first line of input, which consists of column headers
   while(*input && *input != '\n')
      ++input;

   // Parse each remaining line
   while(*input)
   {
      parseCSVLine(input, fields);

      if(fields.getLength() >= FIELD_NUMFIELDS)
      {
         int recordType = E_StrToNumLinear(recordTypeNames, INSTAT_NUMTYPES, 
                                           fields[FIELD_RECORDTYPE].constPtr());

         if(recordType < INSTAT_NUMTYPES)
         {
            in_stat_t *newStats = estructalloc(in_stat_t, 1);

            newStats->levelkey   = fields[FIELD_LEVELKEY  ].duplicate(PU_STATIC);
            newStats->playername = fields[FIELD_PLAYERNAME].duplicate(PU_STATIC);
            newStats->skill      = fields[FIELD_SKILL     ].toInt();
            newStats->value      = fields[FIELD_VALUE     ].toInt();
            newStats->maxValue   = fields[FIELD_MAXVALUE  ].toInt();

            newStats->recordType = recordType;

            // add to hash tables
            statsByLevelKey.addObject(newStats);
         }
      }
   }
}
Exemplo n.º 15
0
//
// E_ProcessCast
//
// Creates the DOOM II cast call information
//
static void E_ProcessCast(cfg_t *cfg)
{
   static bool firsttime = true;
   int i, numcastorder = 0, numcastsections = 0;
   cfg_t **ci_order;

   E_EDFLogPuts("\t* Processing cast call\n");
   
   // get number of cast sections
   numcastsections = cfg_size(cfg, SEC_CAST);

   if(firsttime && !numcastsections) // on main parse, at least one is required.
      E_EDFLoggedErr(2, "E_ProcessCast: no cast members defined.\n");

   firsttime = false;

   E_EDFLogPrintf("\t\t%d cast member(s) defined\n", numcastsections);

   // haleyjd 11/21/11: allow multiple runs
   if(castorder)
   {
      int i;

      // free names
      for(i = 0; i < max_castorder; i++)
      {
         if(castorder[i].name)
            efree(castorder[i].name);
      }
      // free castorder
      efree(castorder);
      castorder = NULL;
      max_castorder = 0;
   }

   // check if the "castorder" array is defined for imposing an
   // order on the castinfo sections
   numcastorder = cfg_size(cfg, SEC_CASTORDER);

   E_EDFLogPrintf("\t\t%d cast member(s) in castorder\n", numcastorder);

   // determine size of castorder
   max_castorder = (numcastorder > 0) ? numcastorder : numcastsections;

   // allocate with size+1 for an end marker
   castorder = estructalloc(castinfo_t, max_castorder + 1);
   ci_order  = ecalloc(cfg_t **, sizeof(cfg_t *), max_castorder);

   if(numcastorder > 0)
   {
      for(i = 0; i < numcastorder; ++i)
      {
         const char *title = cfg_getnstr(cfg, SEC_CASTORDER, i);         
         cfg_t *section    = cfg_gettsec(cfg, SEC_CAST, title);

         if(!section)
         {
            E_EDFLoggedErr(2, 
               "E_ProcessCast: unknown cast member '%s' in castorder\n", 
               title);
         }

         ci_order[i] = section;
      }
   }
   else
   {
      // no castorder array is defined, so use the cast members
      // in the order they are encountered (for backward compatibility)
      for(i = 0; i < numcastsections; ++i)
         ci_order[i] = cfg_getnsec(cfg, SEC_CAST, i);
   }


   for(i = 0; i < max_castorder; ++i)
   {
      int j;
      const char *tempstr;
      int tempint = 0;
      cfg_t *castsec = ci_order[i];

      // resolve thing type
      tempstr = cfg_getstr(castsec, ITEM_CAST_TYPE);
      if(!tempstr || 
         (tempint = E_ThingNumForName(tempstr)) == -1)
      {
         E_EDFLoggedWarning(2, "Warning: cast %d: unknown thing type %s\n",
                            i, tempstr);

         tempint = UnknownThingType;
      }
      castorder[i].type = tempint;

      // get cast name, if any -- the first seventeen entries can
      // default to using the internal string editable via BEX strings
      tempstr = cfg_getstr(castsec, ITEM_CAST_NAME);
      if(cfg_size(castsec, ITEM_CAST_NAME) == 0 && i < 17)
         castorder[i].name = NULL; // set from DeHackEd
      else
         castorder[i].name = estrdup(tempstr); // store provided value

      // get stopattack flag (used by player)
      castorder[i].stopattack = cfg_getbool(castsec, ITEM_CAST_SA);

      // process sound blocks (up to four will be processed)
      tempint = cfg_size(castsec, ITEM_CAST_SOUND);
      for(j = 0; j < 4; ++j)
      {
         castorder[i].sounds[j].frame = 0;
         castorder[i].sounds[j].sound = 0;
      }
      for(j = 0; j < tempint && j < 4; ++j)
      {
         int num;
         sfxinfo_t *sfx;
         const char *name;
         cfg_t *soundsec = cfg_getnsec(castsec, ITEM_CAST_SOUND, j);

         // if these are invalid, just fill them with zero rather
         // than causing an error, as they're very unimportant

         // name of sound to play
         name = cfg_getstr(soundsec, ITEM_CAST_SOUNDNAME);
         
         // haleyjd 03/22/06: modified to support dehnum auto-allocation
         if((sfx = E_EDFSoundForName(name)) == NULL)
         {
            E_EDFLoggedWarning(2, "Warning: cast member references invalid sound %s\n",
                               name);
            castorder[i].sounds[j].sound = 0;
         }
         else
         {
            if(sfx->dehackednum != -1 || E_AutoAllocSoundDEHNum(sfx))
               castorder[i].sounds[j].sound = sfx->dehackednum;
            else
            {
               E_EDFLoggedWarning(2, "Warning: could not auto-allocate a DeHackEd number "
                                     "for sound %s\n", name);
               castorder[i].sounds[j].sound = 0;
            }
         }

         // name of frame that triggers sound event
         name = cfg_getstr(soundsec, ITEM_CAST_SOUNDFRAME);
         if((num = E_StateNumForName(name)) < 0)
            num = 0;
         castorder[i].sounds[j].frame = num;
      }
   }

   // initialize the end marker to all zeroes
   memset(&castorder[max_castorder], 0, sizeof(castinfo_t));

   // free the ci_order table
   efree(ci_order);
}
Exemplo n.º 16
0
//
// G_KeyActionForName
//
// Obtain a keyaction from its name
//
static keyaction_t *G_KeyActionForName(const char *name)
{
   static int cons_actionnum = NUMKEYACTIONS;
   keyaction_t *prev, *temp, *newaction;

   // sequential search
   // this is only called every now and then

   for(keyaction_t &keyaction : keyactions)
   {
      if(!keyaction.name)
         continue;
      if(!strcasecmp(name, keyaction.name))
         return &keyaction;
   }

   // check console keyactions
   // haleyjd: TOTALLY rewritten to use linked list

   if(cons_keyactions)
   {
      temp = cons_keyactions;
      while(temp)
      {
         if(!strcasecmp(name, temp->name))
            return temp;

         temp = temp->next;
      }
   }
   else
   {
      // first time only - cons_keyactions was NULL
      cons_keyactions = estructalloc(keyaction_t, 1);
      cons_keyactions->bclass = kac_cmd;
      cons_keyactions->type   = at_conscmd;
      cons_keyactions->name   = Z_Strdup(name, PU_STATIC, 0);
      cons_keyactions->next   = nullptr;
      cons_keyactions->num    = cons_actionnum++;

      return cons_keyactions;
   }

   // not in list -- add
   prev = nullptr;
   temp = cons_keyactions;
   while(temp)
   {
      prev = temp;
      temp = temp->next;
   }
   newaction = estructalloc(keyaction_t, 1);
   newaction->bclass = kac_cmd;
   newaction->type = at_conscmd;
   newaction->name = Z_Strdup(name, PU_STATIC, 0);
   newaction->next = nullptr;
   newaction->num  = cons_actionnum++;

   if(prev) prev->next = newaction;

   return newaction;
}