// // E_ProcessStatesAndThings // // E_ProcessEDF now calls this function to accomplish all state // and thing processing. // static void E_ProcessStatesAndThings(cfg_t *cfg) { E_EDFLogPuts("\t* Beginning state and thing processing\n"); // allocate structures, build mnemonic and dehnum hash tables E_CollectNames(cfg); // process states: see e_states.c E_ProcessStates(cfg); // process things: see e_things.c E_ProcessThings(cfg); }
static void E_EchoEnables() { E_Enable_t *enable = edf_enables; E_EDFLogPuts("\t* Final enable values:\n"); while(enable->name) { E_EDFLogPrintf("\t\t%s is %s\n", enable->name, enable->enabled ? "enabled" : "disabled"); ++enable; } }
// // edf_error // // This function is given to all cfg_t structures as the error // callback. // static void edf_error(cfg_t *cfg, const char *fmt, va_list ap) { E_EDFLogPuts("Exiting due to parser error\n"); // 12/16/03: improved error messages if(cfg && cfg->filename) { if(cfg->line) fprintf(stderr, "Error at %s:%d:\n", cfg->filename, cfg->line); else fprintf(stderr, "Error in %s:\n", cfg->filename); } I_ErrorVA(fmt, ap); }
// // E_DoEDFProcessing // // haleyjd 11/21/11: Shared processing phase code, now that all EDF sections // are fully dynamic with repeatable processing. // static void E_DoEDFProcessing(cfg_t *cfg, bool firsttime) { E_EDFLogPuts("\n=================== Processing Phase ====================\n"); // Echo final enable values to the log file for reference. if(firsttime) E_EchoEnables(); // NOTE: The order of most of the following calls is extremely // important and must be preserved, unless the static routines // above and in other files are rewritten accordingly. // process strings E_ProcessStrings(cfg); // process sprites E_ProcessSprites(cfg); // process sounds E_ProcessSounds(cfg); // process ambience information E_ProcessAmbience(cfg); // process sound sequences E_ProcessSndSeqs(cfg); // process reverb definitions (12/22/13) E_ProcessReverbs(cfg); // process damage types E_ProcessDamageTypes(cfg); // process frame and thing definitions (made dynamic 11/06/11) E_ProcessStatesAndThings(cfg); // process sprite-related variables (made dynamic 11/21/11) E_ProcessSpriteVars(cfg); // process inventory E_ProcessInventory(cfg); // process player sections E_ProcessPlayerData(cfg); // process cast call (made dynamic 11/21/11) E_ProcessCast(cfg); // process boss spawn types (made dynamic 11/21/11) E_ProcessBossTypes(cfg); // process TerrainTypes E_ProcessTerrainTypes(cfg); // process dynamic menus MN_ProcessMenus(cfg); // process fonts E_ProcessFonts(cfg); // process misc vars (made dynamic 11/21/11) E_ProcessMiscVars(cfg); // 08/30/03: apply deltas E_ProcessSoundDeltas(cfg, true); // see e_sound.cpp E_ProcessStateDeltas(cfg); // see e_states.cpp E_ProcessThingDeltas(cfg); // see e_things.cpp // 07/19/12: game properties E_ProcessGameProperties(cfg); // see e_gameprops.cpp // post-processing routines E_SetThingDefaultSprites(); }
// // E_ProcessBossTypes // // Gets the thing type entries in the boss_spawner_types list, // for use by the SpawnFly codepointer. // // modified by schepe to remove 11-type limit // static void E_ProcessBossTypes(cfg_t *cfg) { int i, a = 0; int numTypes = cfg_size(cfg, SEC_BOSSTYPES); int numProbs = cfg_size(cfg, SEC_BOSSPROBS); bool useProbs = true; E_EDFLogPuts("\t* Processing boss spawn types\n"); if(!numTypes) { // haleyjd 05/31/06: allow zero boss types E_EDFLogPuts("\t\tNo boss types defined\n"); return; } // haleyjd 11/19/03: allow defaults for boss spawn probs if(!numProbs) useProbs = false; if(useProbs ? numTypes != numProbs : numTypes != 11) { E_EDFLoggedErr(2, "E_ProcessBossTypes: %d boss types, %d boss probs\n", numTypes, useProbs ? numProbs : 11); } // haleyjd 11/21/11: allow multiple runs if(BossSpawnTypes) { efree(BossSpawnTypes); BossSpawnTypes = NULL; } if(BossSpawnProbs) { efree(BossSpawnProbs); BossSpawnProbs = NULL; } NumBossTypes = numTypes; BossSpawnTypes = ecalloc(int *, numTypes, sizeof(int)); BossSpawnProbs = ecalloc(int *, numTypes, sizeof(int)); // load boss spawn probabilities for(i = 0; i < numTypes; ++i) { if(useProbs) { a += cfg_getnint(cfg, SEC_BOSSPROBS, i); BossSpawnProbs[i] = a; } else BossSpawnProbs[i] = BossDefaults[i]; } // check that the probabilities total 256 if(useProbs && a != 256) { E_EDFLoggedErr(2, "E_ProcessBossTypes: boss spawn probs do not total 256\n"); } for(i = 0; i < numTypes; ++i) { const char *typeName = cfg_getnstr(cfg, SEC_BOSSTYPES, i); int typeNum = E_ThingNumForName(typeName); if(typeNum == -1) { E_EDFLoggedWarning(2, "Warning: invalid boss type '%s'\n", typeName); typeNum = UnknownThingType; } BossSpawnTypes[i] = typeNum; E_EDFLogPrintf("\t\tAssigned type %s(#%d) to boss type %d\n", mobjinfo[typeNum]->name, typeNum, i); } }
// // 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); }