sanitize the progs.dat loader
parent
163560269a
commit
9ba9da23f0
238
source/pr_load.c
238
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]);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue