diff --git a/source/pr_load.c b/source/pr_load.c index 26dd9ef..e2022fc 100644 --- a/source/pr_load.c +++ b/source/pr_load.c @@ -37,36 +37,156 @@ cvar_t saved2 = {"saved2", "0", CVAR_ARCHIVE}; cvar_t saved3 = {"saved3", "0", CVAR_ARCHIVE}; cvar_t saved4 = {"saved4", "0", CVAR_ARCHIVE}; -static void PR_LoadProgHeader(byte *prog_data) +static void PR_LoadProgHeader(byte const *data) { - progs.version = ReadLittleLong(&prog_data[4 * 0]); - progs.crc = ReadLittleLong(&prog_data[4 * 1]); + progs.version = ReadLittleLong(&data); + progs.crc = ReadLittleLong(&data); - progs.ofs_statements = ReadLittleLong(&prog_data[4 * 2]); - progs.numstatements = ReadLittleLong(&prog_data[4 * 3]); + progs.ofs_statements = ReadLittleLong(&data); + progs.numstatements = ReadLittleLong(&data); - progs.ofs_globaldefs = ReadLittleLong(&prog_data[4 * 4]); - progs.numglobaldefs = ReadLittleLong(&prog_data[4 * 5]); + progs.ofs_globaldefs = ReadLittleLong(&data); + progs.numglobaldefs = ReadLittleLong(&data); - progs.ofs_fielddefs = ReadLittleLong(&prog_data[4 * 6]); - progs.numfielddefs = ReadLittleLong(&prog_data[4 * 7]); + progs.ofs_fielddefs = ReadLittleLong(&data); + progs.numfielddefs = ReadLittleLong(&data); - progs.ofs_functions = ReadLittleLong(&prog_data[4 * 8]); - progs.numfunctions = ReadLittleLong(&prog_data[4 * 9]); + progs.ofs_functions = ReadLittleLong(&data); + progs.numfunctions = ReadLittleLong(&data); - progs.ofs_strings = ReadLittleLong(&prog_data[4 * 10]); - progs.numstrings = ReadLittleLong(&prog_data[4 * 11]); + progs.ofs_strings = ReadLittleLong(&data); + progs.numstrings = ReadLittleLong(&data); - progs.ofs_globals = ReadLittleLong(&prog_data[4 * 12]); - progs.numglobals = ReadLittleLong(&prog_data[4 * 13]); + progs.ofs_globals = ReadLittleLong(&data); + progs.numglobals = ReadLittleLong(&data); - progs.entityfields = ReadLittleLong(&prog_data[4 * 14]); + progs.entityfields = ReadLittleLong(&data); + + /* round off to next highest whole word address (esp for Alpha) this ensures + * that pointers in the engine data area are always properly aligned + */ + pr_edict_size = progs.entityfields * 4 + sizeof(edict_t) - sizeof(entvars_t); + pr_edict_size += sizeof(void *) - 1; + pr_edict_size &= ~(sizeof(void *) - 1); if(progs.version != PROG_VERSION) - Host_Error("progs.dat has wrong version number (%" PRIi32 " should be %" PRIi32 ")", progs.version, PROG_VERSION); + Host_Error("PR_LoadProgHeader: has wrong version number (%" PRIi32 " should be %" PRIi32 ")", progs.version, PROG_VERSION); if(progs.crc != PROGHEADER_CRC) - Host_Error("progs.dat system vars have been modified, progdefs.h is out of date"); + Host_Error("PR_LoadProgHeader: system vars have been modified, progdefs.h is out of date"); + + if(progs.ofs_strings + progs.numstrings >= com_filesize) + Host_Error("PR_LoadProgHeader: strings go past end of file\n"); +} + +static void PR_LoadFunctions(byte const *data) +{ + int32_t i; + + pr_functions = Hunk_AllocName(sizeof(*pr_functions) * progs.numfunctions, + "pr_functions"); + + for(i = 0; i < progs.numfunctions; i++) + { + pr_functions[i].first_statement = ReadLittleLong(&data); + pr_functions[i].parm_start = ReadLittleLong(&data); + pr_functions[i].locals = ReadLittleLong(&data); + pr_functions[i].profile = 0; ReadSkip(&data, 4); + pr_functions[i].s_name = ReadLittleLong(&data); + pr_functions[i].s_file = ReadLittleLong(&data); + pr_functions[i].numparms = ReadLittleLong(&data); + ReadCopy(pr_functions[i].parm_size, &data, 8); + } +} + +static void PR_LoadStrings(byte const *data) +{ + pr_strings = Hunk_Memdup(data, progs.numstrings, "pr_strings"); + + // initialize the strings + pr_numknownstrings = 0; + pr_maxknownstrings = 0; + if(pr_knownstrings) + Z_Free(pr_knownstrings); + pr_knownstrings = NULL; + PR_SetEngineString(""); +} + +static void PR_LoadDef(ddef_t *def, byte const **data) +{ + def->type = ReadLittleShort(data); + def->ofs = ReadLittleShort(data); + def->s_name = ReadLittleLong(data); +} + +static void PR_LoadGlobalDefs(byte const *data) +{ + int32_t i; + + pr_globaldefs = Hunk_AllocName(sizeof(*pr_globaldefs) * progs.numglobaldefs, + "pr_globaldefs"); + + for(i = 0; i < progs.numglobaldefs; i++) + { + PR_LoadDef(&pr_globaldefs[i], &data); + } +} + +static void PR_LoadFieldDefs(byte const *data) +{ + int32_t i; + + pr_fielddefs = Hunk_AllocName(sizeof(*pr_fielddefs) * progs.numfielddefs, + "pr_fielddefs"); + + pr_alpha_supported = false; //johnfitz + + for(i = 0; i < progs.numfielddefs; i++) + { + PR_LoadDef(&pr_fielddefs[i], &data); + + if(pr_fielddefs[i].type & DEF_SAVEGLOBAL) + Host_Error("PR_LoadProgs: field defs cannot have DEF_SAVEGLOBAL"); + + //johnfitz -- detect alpha support + if(!strcmp(&pr_strings[pr_fielddefs[i].s_name], "alpha")) + pr_alpha_supported = true; + //johnfitz + } +} + +static void PR_LoadStatements(byte const *data) +{ + int32_t i; + + pr_statements = Hunk_AllocName(sizeof(*pr_statements) * progs.numstatements, + "pr_statements"); + + for(i = 0; i < progs.numstatements; i++) + { + pr_statements[i].op = ReadLittleShort(&data); + pr_statements[i].a = ReadLittleShort(&data); + pr_statements[i].b = ReadLittleShort(&data); + pr_statements[i].c = ReadLittleShort(&data); + } +} + +static void PR_LoadGlobals(byte const *data) +{ + int32_t i; + + // HACK + pr_global_struct = Hunk_Memdup(data, progs.numglobals * 4, "pr_global_struct"); + + /* + pr_global_struct = Hunk_AllocName(sizeof(*pr_global_struct), + "pr_global_struct"); + */ + + pr_globals = (float *)pr_global_struct; + + for(i = 0; i < progs.numglobals; i++) + pr_globals[i] = LittleFloat(pr_globals[i]); } /* @@ -83,87 +203,21 @@ void PR_LoadProgs(void) CRC_Init(&pr_crc); - prog_data = COM_LoadHunkFile("progs.dat", NULL); + prog_data = COM_LoadTempFile("progs.dat", NULL); if(!prog_data) Host_Error("PR_LoadProgs: couldn't load progs.dat"); - Con_DPrintf("Programs occupy %" PRIi32 "K.\n", com_filesize / 1024); + Con_DPrintf("Programs occupy %" PRIi32 "K\n", com_filesize / 1024); for(i = 0; i < com_filesize; i++) CRC_ProcessByte(&pr_crc, prog_data[i]); PR_LoadProgHeader(prog_data); - - pr_functions = (dfunction_t *)&prog_data[progs.ofs_functions]; - pr_strings = (char const *)&prog_data[progs.ofs_strings]; - if(progs.ofs_strings + progs.numstrings >= com_filesize) - Host_Error("progs.dat strings go past end of file\n"); - - // initialize the strings - pr_numknownstrings = 0; - pr_maxknownstrings = 0; - if(pr_knownstrings) - Z_Free(pr_knownstrings); - pr_knownstrings = NULL; - PR_SetEngineString(""); - - pr_globaldefs = (ddef_t *)&prog_data[progs.ofs_globaldefs]; - pr_fielddefs = (ddef_t *)&prog_data[progs.ofs_fielddefs]; - pr_statements = (dstatement_t *)&prog_data[progs.ofs_statements]; - - pr_global_struct = (globalvars_t *)&prog_data[progs.ofs_globals]; - pr_globals = (float *)pr_global_struct; - - // byte swap the lumps - for(i = 0; i < progs.numstatements; i++) - { - pr_statements[i].op = LittleShort(pr_statements[i].op); - pr_statements[i].a = LittleShort(pr_statements[i].a); - pr_statements[i].b = LittleShort(pr_statements[i].b); - pr_statements[i].c = LittleShort(pr_statements[i].c); - } - - for(i = 0; i < progs.numfunctions; i++) - { - pr_functions[i].first_statement = LittleLong(pr_functions[i].first_statement); - pr_functions[i].parm_start = LittleLong(pr_functions[i].parm_start); - pr_functions[i].s_name = LittleLong(pr_functions[i].s_name); - pr_functions[i].s_file = LittleLong(pr_functions[i].s_file); - pr_functions[i].numparms = LittleLong(pr_functions[i].numparms); - pr_functions[i].locals = LittleLong(pr_functions[i].locals); - } - - for(i = 0; i < progs.numglobaldefs; i++) - { - pr_globaldefs[i].type = LittleShort(pr_globaldefs[i].type); - pr_globaldefs[i].ofs = LittleShort(pr_globaldefs[i].ofs); - pr_globaldefs[i].s_name = LittleLong(pr_globaldefs[i].s_name); - } - - pr_alpha_supported = false; //johnfitz - - for(i = 0; i < progs.numfielddefs; i++) - { - pr_fielddefs[i].type = LittleShort(pr_fielddefs[i].type); - if(pr_fielddefs[i].type & DEF_SAVEGLOBAL) - Host_Error("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL"); - pr_fielddefs[i].ofs = LittleShort(pr_fielddefs[i].ofs); - pr_fielddefs[i].s_name = LittleLong(pr_fielddefs[i].s_name); - - //johnfitz -- detect alpha support - if(!strcmp(pr_strings + pr_fielddefs[i].s_name, "alpha")) - pr_alpha_supported = true; - //johnfitz - } - - for(i = 0; i < progs.numglobals; i++) - ((int32_t *)pr_globals)[i] = LittleLong(((int32_t *)pr_globals)[i]); - - pr_edict_size = progs.entityfields * 4 + sizeof(edict_t) - sizeof(entvars_t); - // round off to next highest whole word address (esp for Alpha) - // this ensures that pointers in the engine data area are always - // properly aligned - pr_edict_size += sizeof(void *) - 1; - pr_edict_size &= ~(sizeof(void *) - 1); + PR_LoadStrings(&prog_data[progs.ofs_strings]); + PR_LoadStatements(&prog_data[progs.ofs_statements]); + PR_LoadFunctions(&prog_data[progs.ofs_functions]); + PR_LoadGlobalDefs(&prog_data[progs.ofs_globaldefs]); + PR_LoadFieldDefs(&prog_data[progs.ofs_fielddefs]); + PR_LoadGlobals(&prog_data[progs.ofs_globals]); } diff --git a/source/pr_string.c b/source/pr_string.c index 2d5e85e..12178d5 100644 --- a/source/pr_string.c +++ b/source/pr_string.c @@ -189,13 +189,11 @@ const char *PR_GlobalStringNoContents(int32_t ofs) //=========================================================================== -#define PR_STRING_ALLOCSLOTS 256 - static void PR_AllocStringSlots(void) { - pr_maxknownstrings += PR_STRING_ALLOCSLOTS; + pr_maxknownstrings += 256; Con_DPrintf2("PR_AllocStringSlots: realloc'ing for %" PRIi32 " slots\n", pr_maxknownstrings); - pr_knownstrings = (const char **) Z_Realloc(pr_knownstrings, pr_maxknownstrings * sizeof(char *)); + pr_knownstrings = Z_Realloc(pr_knownstrings, pr_maxknownstrings * sizeof(*pr_knownstrings)); } const char *PR_GetString(int32_t num) @@ -206,7 +204,7 @@ const char *PR_GetString(int32_t num) { if(!pr_knownstrings[-1 - num]) { - Host_Error("PR_GetString: attempt to get a non-existant string %" PRIi32 "\n", num); + Host_Error("PR_GetString: attempt to get a non-existent string %" PRIi32 "\n", num); return ""; } return pr_knownstrings[-1 - num]; @@ -220,7 +218,7 @@ const char *PR_GetString(int32_t num) int32_t PR_SetEngineString(const char *s) { - int32_t i; + int32_t i; if(!s) return 0;