sunder pr_edict/pr_load/pr_string
parent
61fa56b316
commit
654fe5af8a
|
@ -95,6 +95,8 @@ set(srcs
|
|||
source/pr_comp.h
|
||||
source/pr_edict.c
|
||||
source/pr_exec.c
|
||||
source/pr_load.c
|
||||
source/pr_string.c
|
||||
source/progdefs.h
|
||||
source/progs.h
|
||||
source/protocol.h
|
||||
|
|
|
@ -63,16 +63,19 @@ interface from being ambiguous.
|
|||
|
||||
*/
|
||||
|
||||
#define CVAR_NONE 0
|
||||
#define CVAR_ARCHIVE (1U << 0) // if set, causes it to be saved to config
|
||||
#define CVAR_NOTIFY (1U << 1) // changes will be broadcasted to all players (q1)
|
||||
#define CVAR_SERVERINFO (1U << 2) // added to serverinfo will be sent to clients (q1/net_dgrm.c and qwsv)
|
||||
#define CVAR_USERINFO (1U << 3) // added to userinfo, will be sent to server (qwcl)
|
||||
#define CVAR_CHANGED (1U << 4)
|
||||
#define CVAR_ROM (1U << 6)
|
||||
#define CVAR_LOCKED (1U << 8) // locked temporarily
|
||||
#define CVAR_REGISTERED (1U << 10) // the var is added to the list of variables
|
||||
#define CVAR_CALLBACK (1U << 16) // var has a callback
|
||||
enum
|
||||
{
|
||||
CVAR_NONE = 0,
|
||||
CVAR_ARCHIVE = 1 << 0, // if set, causes it to be saved to config
|
||||
CVAR_NOTIFY = 1 << 1, // changes will be broadcasted to all players (q1)
|
||||
CVAR_SERVERINFO = 1 << 2, // added to serverinfo will be sent to clients (q1/net_dgrm.c and qwsv)
|
||||
CVAR_USERINFO = 1 << 3, // added to userinfo, will be sent to server (qwcl)
|
||||
CVAR_CHANGED = 1 << 4,
|
||||
CVAR_ROM = 1 << 6,
|
||||
CVAR_LOCKED = 1 << 8, // locked temporarily
|
||||
CVAR_REGISTERED = 1 << 10, // the var is added to the list of variables
|
||||
CVAR_CALLBACK = 1 << 16, // var has a callback
|
||||
};
|
||||
|
||||
|
||||
typedef void (*cvarcallback_t)(struct cvar_s *);
|
||||
|
|
|
@ -26,13 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
dprograms_t progs;
|
||||
dfunction_t *pr_functions;
|
||||
|
||||
static char *pr_strings;
|
||||
static int32_t pr_stringssize;
|
||||
static const char **pr_knownstrings;
|
||||
static int32_t pr_maxknownstrings;
|
||||
static int32_t pr_numknownstrings;
|
||||
static ddef_t *pr_fielddefs;
|
||||
static ddef_t *pr_globaldefs;
|
||||
ddef_t *pr_fielddefs;
|
||||
|
||||
bool pr_alpha_supported; //johnfitz
|
||||
|
||||
|
@ -55,9 +49,6 @@ static int32_t type_size[] =
|
|||
[ev_pointer] = 1,
|
||||
};
|
||||
|
||||
static ddef_t *ED_FieldAtOfs(int32_t ofs);
|
||||
static bool ED_ParseEpair(void *base, ddef_t *key, const char *s);
|
||||
|
||||
#define MAX_FIELD_LEN 64
|
||||
#define GEFV_CACHESIZE 2
|
||||
|
||||
|
@ -73,18 +64,6 @@ static gefv_cache gefvCache[GEFV_CACHESIZE] =
|
|||
{ NULL, "" }
|
||||
};
|
||||
|
||||
cvar_t nomonsters = {"nomonsters", "0", CVAR_NONE};
|
||||
cvar_t gamecfg = {"gamecfg", "0", CVAR_NONE};
|
||||
cvar_t scratch1 = {"scratch1", "0", CVAR_NONE};
|
||||
cvar_t scratch2 = {"scratch2", "0", CVAR_NONE};
|
||||
cvar_t scratch3 = {"scratch3", "0", CVAR_NONE};
|
||||
cvar_t scratch4 = {"scratch4", "0", CVAR_NONE};
|
||||
cvar_t savedgamecfg = {"savedgamecfg", "0", CVAR_ARCHIVE};
|
||||
cvar_t saved1 = {"saved1", "0", CVAR_ARCHIVE};
|
||||
cvar_t saved2 = {"saved2", "0", CVAR_ARCHIVE};
|
||||
cvar_t saved3 = {"saved3", "0", CVAR_ARCHIVE};
|
||||
cvar_t saved4 = {"saved4", "0", CVAR_ARCHIVE};
|
||||
|
||||
/*
|
||||
=================
|
||||
ED_ClearEdict
|
||||
|
@ -171,7 +150,7 @@ void ED_Free(edict_t *ed)
|
|||
ED_GlobalAtOfs
|
||||
============
|
||||
*/
|
||||
static ddef_t *ED_GlobalAtOfs(int32_t ofs)
|
||||
ddef_t *ED_GlobalAtOfs(int32_t ofs)
|
||||
{
|
||||
ddef_t *def;
|
||||
int32_t i;
|
||||
|
@ -190,7 +169,7 @@ static ddef_t *ED_GlobalAtOfs(int32_t ofs)
|
|||
ED_FieldAtOfs
|
||||
============
|
||||
*/
|
||||
static ddef_t *ED_FieldAtOfs(int32_t ofs)
|
||||
ddef_t *ED_FieldAtOfs(int32_t ofs)
|
||||
{
|
||||
ddef_t *def;
|
||||
int32_t i;
|
||||
|
@ -300,163 +279,6 @@ Done:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
PR_ValueString
|
||||
(etype_t type, eval_t *val)
|
||||
|
||||
Returns a string describing *data in a type specific manner
|
||||
=============
|
||||
*/
|
||||
static const char *PR_ValueString(int32_t type, eval_t *val)
|
||||
{
|
||||
static char line[512];
|
||||
ddef_t *def;
|
||||
dfunction_t *f;
|
||||
|
||||
type &= ~DEF_SAVEGLOBAL;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case ev_string:
|
||||
sprintf(line, "%s", PR_GetString(val->string));
|
||||
break;
|
||||
case ev_entity:
|
||||
sprintf(line, "entity %" PRIi32 "", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
|
||||
break;
|
||||
case ev_function:
|
||||
f = pr_functions + val->function;
|
||||
sprintf(line, "%s()", PR_GetString(f->s_name));
|
||||
break;
|
||||
case ev_field:
|
||||
def = ED_FieldAtOfs(val->_int);
|
||||
sprintf(line, ".%s", PR_GetString(def->s_name));
|
||||
break;
|
||||
case ev_void:
|
||||
sprintf(line, "void");
|
||||
break;
|
||||
case ev_float:
|
||||
sprintf(line, "%5.1f", val->_float);
|
||||
break;
|
||||
case ev_vector:
|
||||
sprintf(line, "'%5.1f %5.1f %5.1f'", val->vector[0], val->vector[1], val->vector[2]);
|
||||
break;
|
||||
case ev_pointer:
|
||||
sprintf(line, "pointer");
|
||||
break;
|
||||
default:
|
||||
sprintf(line, "bad type %" PRIi32 "", type);
|
||||
break;
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
PR_UglyValueString
|
||||
(etype_t type, eval_t *val)
|
||||
|
||||
Returns a string describing *data in a type specific manner
|
||||
Easier to parse than PR_ValueString
|
||||
=============
|
||||
*/
|
||||
static const char *PR_UglyValueString(int32_t type, eval_t *val)
|
||||
{
|
||||
static char line[512];
|
||||
ddef_t *def;
|
||||
dfunction_t *f;
|
||||
|
||||
type &= ~DEF_SAVEGLOBAL;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case ev_string:
|
||||
sprintf(line, "%s", PR_GetString(val->string));
|
||||
break;
|
||||
case ev_entity:
|
||||
sprintf(line, "%" PRIi32 "", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
|
||||
break;
|
||||
case ev_function:
|
||||
f = pr_functions + val->function;
|
||||
sprintf(line, "%s", PR_GetString(f->s_name));
|
||||
break;
|
||||
case ev_field:
|
||||
def = ED_FieldAtOfs(val->_int);
|
||||
sprintf(line, "%s", PR_GetString(def->s_name));
|
||||
break;
|
||||
case ev_void:
|
||||
sprintf(line, "void");
|
||||
break;
|
||||
case ev_float:
|
||||
sprintf(line, "%f", val->_float);
|
||||
break;
|
||||
case ev_vector:
|
||||
sprintf(line, "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
|
||||
break;
|
||||
default:
|
||||
sprintf(line, "bad type %" PRIi32 "", type);
|
||||
break;
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
PR_GlobalString
|
||||
|
||||
Returns a string with a description and the contents of a global,
|
||||
padded to 20 field width
|
||||
============
|
||||
*/
|
||||
const char *PR_GlobalString(int32_t ofs)
|
||||
{
|
||||
static char line[512];
|
||||
const char *s;
|
||||
int32_t i;
|
||||
ddef_t *def;
|
||||
void *val;
|
||||
|
||||
val = &pr_globals[ofs];
|
||||
def = ED_GlobalAtOfs(ofs);
|
||||
if(!def)
|
||||
sprintf(line, "%" PRIi32 "(?)", ofs);
|
||||
else
|
||||
{
|
||||
s = PR_ValueString(def->type, (eval_t *)val);
|
||||
sprintf(line, "%" PRIi32 "(%s)%s", ofs, PR_GetString(def->s_name), s);
|
||||
}
|
||||
|
||||
i = strlen(line);
|
||||
for(; i < 20; i++)
|
||||
strcat(line, " ");
|
||||
strcat(line, " ");
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
const char *PR_GlobalStringNoContents(int32_t ofs)
|
||||
{
|
||||
static char line[512];
|
||||
int32_t i;
|
||||
ddef_t *def;
|
||||
|
||||
def = ED_GlobalAtOfs(ofs);
|
||||
if(!def)
|
||||
sprintf(line, "%" PRIi32 "(?)", ofs);
|
||||
else
|
||||
sprintf(line, "%" PRIi32 "(%s)", ofs, PR_GetString(def->s_name));
|
||||
|
||||
i = strlen(line);
|
||||
for(; i < 20; i++)
|
||||
strcat(line, " ");
|
||||
strcat(line, " ");
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
ED_Print
|
||||
|
@ -773,7 +595,7 @@ Can parse either fields or globals
|
|||
returns false if error
|
||||
=============
|
||||
*/
|
||||
static bool ED_ParseEpair(void *base, ddef_t *key, const char *s)
|
||||
bool ED_ParseEpair(void *base, ddef_t *key, const char *s)
|
||||
{
|
||||
int32_t i;
|
||||
char string[128];
|
||||
|
@ -1042,164 +864,22 @@ void ED_LoadFromFile(const char *data)
|
|||
Con_DPrintf("%" PRIi32 " entities inhibited\n", inhibit);
|
||||
}
|
||||
|
||||
static void PR_LoadProgHeader(byte *prog_data)
|
||||
void ED_Load(void)
|
||||
{
|
||||
progs.version = ReadLittleLong(&prog_data[4 * 0]);
|
||||
progs.crc = ReadLittleLong(&prog_data[4 * 1]);
|
||||
|
||||
progs.ofs_statements = ReadLittleLong(&prog_data[4 * 2]);
|
||||
progs.numstatements = ReadLittleLong(&prog_data[4 * 3]);
|
||||
|
||||
progs.ofs_globaldefs = ReadLittleLong(&prog_data[4 * 4]);
|
||||
progs.numglobaldefs = ReadLittleLong(&prog_data[4 * 5]);
|
||||
|
||||
progs.ofs_fielddefs = ReadLittleLong(&prog_data[4 * 6]);
|
||||
progs.numfielddefs = ReadLittleLong(&prog_data[4 * 7]);
|
||||
|
||||
progs.ofs_functions = ReadLittleLong(&prog_data[4 * 8]);
|
||||
progs.numfunctions = ReadLittleLong(&prog_data[4 * 9]);
|
||||
|
||||
progs.ofs_strings = ReadLittleLong(&prog_data[4 * 10]);
|
||||
progs.numstrings = ReadLittleLong(&prog_data[4 * 11]);
|
||||
|
||||
progs.ofs_globals = ReadLittleLong(&prog_data[4 * 12]);
|
||||
progs.numglobals = ReadLittleLong(&prog_data[4 * 13]);
|
||||
|
||||
progs.entityfields = ReadLittleLong(&prog_data[4 * 14]);
|
||||
|
||||
if(progs.version != PROG_VERSION)
|
||||
Host_Error("progs.dat 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");
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
PR_LoadProgs
|
||||
===============
|
||||
*/
|
||||
void PR_LoadProgs(void)
|
||||
{
|
||||
byte *prog_data;
|
||||
int32_t i;
|
||||
|
||||
// flush the non-C variable lookup cache
|
||||
for(i = 0; i < GEFV_CACHESIZE; i++)
|
||||
gefvCache[i].field[0] = 0;
|
||||
|
||||
CRC_Init(&pr_crc);
|
||||
|
||||
prog_data = COM_LoadHunkFile("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);
|
||||
|
||||
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 *)&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;
|
||||
pr_stringssize = progs.numstrings;
|
||||
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_Init
|
||||
===============
|
||||
*/
|
||||
void PR_Init(void)
|
||||
void ED_Init(void)
|
||||
{
|
||||
Cmd_AddCommand("edict", ED_PrintEdict_f);
|
||||
Cmd_AddCommand("edicts", ED_PrintEdicts);
|
||||
Cmd_AddCommand("edictcount", ED_Count);
|
||||
Cmd_AddCommand("profile", PR_Profile_f);
|
||||
Cvar_RegisterVariable(&nomonsters);
|
||||
Cvar_RegisterVariable(&gamecfg);
|
||||
Cvar_RegisterVariable(&scratch1);
|
||||
Cvar_RegisterVariable(&scratch2);
|
||||
Cvar_RegisterVariable(&scratch3);
|
||||
Cvar_RegisterVariable(&scratch4);
|
||||
Cvar_RegisterVariable(&savedgamecfg);
|
||||
Cvar_RegisterVariable(&saved1);
|
||||
Cvar_RegisterVariable(&saved2);
|
||||
Cvar_RegisterVariable(&saved3);
|
||||
Cvar_RegisterVariable(&saved4);
|
||||
}
|
||||
|
||||
|
||||
edict_t *EDICT_NUM(int32_t n)
|
||||
{
|
||||
if(n < 0 || n >= sv.max_edicts)
|
||||
|
@ -1218,79 +898,3 @@ int32_t NUM_FOR_EDICT(edict_t *e)
|
|||
Host_Error("NUM_FOR_EDICT: bad pointer");
|
||||
return b;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
|
||||
#define PR_STRING_ALLOCSLOTS 256
|
||||
|
||||
static void PR_AllocStringSlots(void)
|
||||
{
|
||||
pr_maxknownstrings += PR_STRING_ALLOCSLOTS;
|
||||
Con_DPrintf2("PR_AllocStringSlots: realloc'ing for %" PRIi32 " slots\n", pr_maxknownstrings);
|
||||
pr_knownstrings = (const char **) Z_Realloc(pr_knownstrings, pr_maxknownstrings * sizeof(char *));
|
||||
}
|
||||
|
||||
const char *PR_GetString(int32_t num)
|
||||
{
|
||||
if(num >= 0 && num < pr_stringssize)
|
||||
return pr_strings + num;
|
||||
else if(num < 0 && num >= -pr_numknownstrings)
|
||||
{
|
||||
if(!pr_knownstrings[-1 - num])
|
||||
{
|
||||
Host_Error("PR_GetString: attempt to get a non-existant string %" PRIi32 "\n", num);
|
||||
return "";
|
||||
}
|
||||
return pr_knownstrings[-1 - num];
|
||||
}
|
||||
else
|
||||
{
|
||||
Host_Error("PR_GetString: invalid string offset %" PRIi32 "\n", num);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
int32_t PR_SetEngineString(const char *s)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
if(!s)
|
||||
return 0;
|
||||
if(s >= pr_strings && s <= pr_strings + pr_stringssize - 2)
|
||||
return (int32_t)(s - pr_strings);
|
||||
for(i = 0; i < pr_numknownstrings; i++)
|
||||
{
|
||||
if(pr_knownstrings[i] == s)
|
||||
return -1 - i;
|
||||
}
|
||||
if(i >= pr_maxknownstrings)
|
||||
PR_AllocStringSlots();
|
||||
pr_numknownstrings++;
|
||||
pr_knownstrings[i] = s;
|
||||
return -1 - i;
|
||||
}
|
||||
|
||||
int32_t PR_AllocString(int32_t size, char **ptr)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
if(!size)
|
||||
return 0;
|
||||
for(i = 0; i < pr_numknownstrings; i++)
|
||||
{
|
||||
if(!pr_knownstrings[i])
|
||||
break;
|
||||
}
|
||||
// if (i >= pr_numknownstrings)
|
||||
// {
|
||||
if(i >= pr_maxknownstrings)
|
||||
PR_AllocStringSlots();
|
||||
pr_numknownstrings++;
|
||||
// }
|
||||
pr_knownstrings[i] = (char *)Hunk_AllocName(size, "string");
|
||||
if(ptr)
|
||||
*ptr = (char *) pr_knownstrings[i];
|
||||
return -1 - i;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
Copyright (C) 1996-2001 Id Software, Inc.
|
||||
Copyright (C) 2002-2009 John Fitzgibbons and others
|
||||
Copyright (C) 2010-2014 QuakeSpasm developers
|
||||
Copyright (C) 2019 Alison G. Watson
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "q_defs.h"
|
||||
|
||||
ddef_t *pr_globaldefs;
|
||||
|
||||
cvar_t nomonsters = {"nomonsters", "0", CVAR_NONE};
|
||||
cvar_t gamecfg = {"gamecfg", "0", CVAR_NONE};
|
||||
cvar_t scratch1 = {"scratch1", "0", CVAR_NONE};
|
||||
cvar_t scratch2 = {"scratch2", "0", CVAR_NONE};
|
||||
cvar_t scratch3 = {"scratch3", "0", CVAR_NONE};
|
||||
cvar_t scratch4 = {"scratch4", "0", CVAR_NONE};
|
||||
cvar_t savedgamecfg = {"savedgamecfg", "0", CVAR_ARCHIVE};
|
||||
cvar_t saved1 = {"saved1", "0", CVAR_ARCHIVE};
|
||||
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)
|
||||
{
|
||||
progs.version = ReadLittleLong(&prog_data[4 * 0]);
|
||||
progs.crc = ReadLittleLong(&prog_data[4 * 1]);
|
||||
|
||||
progs.ofs_statements = ReadLittleLong(&prog_data[4 * 2]);
|
||||
progs.numstatements = ReadLittleLong(&prog_data[4 * 3]);
|
||||
|
||||
progs.ofs_globaldefs = ReadLittleLong(&prog_data[4 * 4]);
|
||||
progs.numglobaldefs = ReadLittleLong(&prog_data[4 * 5]);
|
||||
|
||||
progs.ofs_fielddefs = ReadLittleLong(&prog_data[4 * 6]);
|
||||
progs.numfielddefs = ReadLittleLong(&prog_data[4 * 7]);
|
||||
|
||||
progs.ofs_functions = ReadLittleLong(&prog_data[4 * 8]);
|
||||
progs.numfunctions = ReadLittleLong(&prog_data[4 * 9]);
|
||||
|
||||
progs.ofs_strings = ReadLittleLong(&prog_data[4 * 10]);
|
||||
progs.numstrings = ReadLittleLong(&prog_data[4 * 11]);
|
||||
|
||||
progs.ofs_globals = ReadLittleLong(&prog_data[4 * 12]);
|
||||
progs.numglobals = ReadLittleLong(&prog_data[4 * 13]);
|
||||
|
||||
progs.entityfields = ReadLittleLong(&prog_data[4 * 14]);
|
||||
|
||||
if(progs.version != PROG_VERSION)
|
||||
Host_Error("progs.dat 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");
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
PR_LoadProgs
|
||||
===============
|
||||
*/
|
||||
void PR_LoadProgs(void)
|
||||
{
|
||||
byte *prog_data;
|
||||
int32_t i;
|
||||
|
||||
ED_Load();
|
||||
|
||||
CRC_Init(&pr_crc);
|
||||
|
||||
prog_data = COM_LoadHunkFile("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);
|
||||
|
||||
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 *)&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_Init
|
||||
===============
|
||||
*/
|
||||
void PR_Init(void)
|
||||
{
|
||||
ED_Init();
|
||||
Cmd_AddCommand("profile", PR_Profile_f);
|
||||
Cvar_RegisterVariable(&nomonsters);
|
||||
Cvar_RegisterVariable(&gamecfg);
|
||||
Cvar_RegisterVariable(&scratch1);
|
||||
Cvar_RegisterVariable(&scratch2);
|
||||
Cvar_RegisterVariable(&scratch3);
|
||||
Cvar_RegisterVariable(&scratch4);
|
||||
Cvar_RegisterVariable(&savedgamecfg);
|
||||
Cvar_RegisterVariable(&saved1);
|
||||
Cvar_RegisterVariable(&saved2);
|
||||
Cvar_RegisterVariable(&saved3);
|
||||
Cvar_RegisterVariable(&saved4);
|
||||
}
|
||||
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
Copyright (C) 1996-2001 Id Software, Inc.
|
||||
Copyright (C) 2002-2009 John Fitzgibbons and others
|
||||
Copyright (C) 2010-2014 QuakeSpasm developers
|
||||
Copyright (C) 2019 Alison G. Watson
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "q_defs.h"
|
||||
|
||||
char *pr_strings;
|
||||
const char **pr_knownstrings;
|
||||
int32_t pr_maxknownstrings;
|
||||
int32_t pr_numknownstrings;
|
||||
|
||||
/*
|
||||
============
|
||||
PR_ValueString
|
||||
(etype_t type, eval_t *val)
|
||||
|
||||
Returns a string describing *data in a type specific manner
|
||||
=============
|
||||
*/
|
||||
const char *PR_ValueString(int32_t type, eval_t *val)
|
||||
{
|
||||
static char line[512];
|
||||
ddef_t *def;
|
||||
dfunction_t *f;
|
||||
|
||||
type &= ~DEF_SAVEGLOBAL;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case ev_string:
|
||||
sprintf(line, "%s", PR_GetString(val->string));
|
||||
break;
|
||||
case ev_entity:
|
||||
sprintf(line, "entity %" PRIi32 "", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
|
||||
break;
|
||||
case ev_function:
|
||||
f = pr_functions + val->function;
|
||||
sprintf(line, "%s()", PR_GetString(f->s_name));
|
||||
break;
|
||||
case ev_field:
|
||||
def = ED_FieldAtOfs(val->_int);
|
||||
sprintf(line, ".%s", PR_GetString(def->s_name));
|
||||
break;
|
||||
case ev_void:
|
||||
sprintf(line, "void");
|
||||
break;
|
||||
case ev_float:
|
||||
sprintf(line, "%5.1f", val->_float);
|
||||
break;
|
||||
case ev_vector:
|
||||
sprintf(line, "'%5.1f %5.1f %5.1f'", val->vector[0], val->vector[1], val->vector[2]);
|
||||
break;
|
||||
case ev_pointer:
|
||||
sprintf(line, "pointer");
|
||||
break;
|
||||
default:
|
||||
sprintf(line, "bad type %" PRIi32 "", type);
|
||||
break;
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
PR_UglyValueString
|
||||
(etype_t type, eval_t *val)
|
||||
|
||||
Returns a string describing *data in a type specific manner
|
||||
Easier to parse than PR_ValueString
|
||||
=============
|
||||
*/
|
||||
const char *PR_UglyValueString(int32_t type, eval_t *val)
|
||||
{
|
||||
static char line[512];
|
||||
ddef_t *def;
|
||||
dfunction_t *f;
|
||||
|
||||
type &= ~DEF_SAVEGLOBAL;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case ev_string:
|
||||
sprintf(line, "%s", PR_GetString(val->string));
|
||||
break;
|
||||
case ev_entity:
|
||||
sprintf(line, "%" PRIi32 "", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
|
||||
break;
|
||||
case ev_function:
|
||||
f = pr_functions + val->function;
|
||||
sprintf(line, "%s", PR_GetString(f->s_name));
|
||||
break;
|
||||
case ev_field:
|
||||
def = ED_FieldAtOfs(val->_int);
|
||||
sprintf(line, "%s", PR_GetString(def->s_name));
|
||||
break;
|
||||
case ev_void:
|
||||
sprintf(line, "void");
|
||||
break;
|
||||
case ev_float:
|
||||
sprintf(line, "%f", val->_float);
|
||||
break;
|
||||
case ev_vector:
|
||||
sprintf(line, "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
|
||||
break;
|
||||
default:
|
||||
sprintf(line, "bad type %" PRIi32 "", type);
|
||||
break;
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
PR_GlobalString
|
||||
|
||||
Returns a string with a description and the contents of a global,
|
||||
padded to 20 field width
|
||||
============
|
||||
*/
|
||||
const char *PR_GlobalString(int32_t ofs)
|
||||
{
|
||||
static char line[512];
|
||||
const char *s;
|
||||
int32_t i;
|
||||
ddef_t *def;
|
||||
void *val;
|
||||
|
||||
val = &pr_globals[ofs];
|
||||
def = ED_GlobalAtOfs(ofs);
|
||||
if(!def)
|
||||
sprintf(line, "%" PRIi32 "(?)", ofs);
|
||||
else
|
||||
{
|
||||
s = PR_ValueString(def->type, (eval_t *)val);
|
||||
sprintf(line, "%" PRIi32 "(%s)%s", ofs, PR_GetString(def->s_name), s);
|
||||
}
|
||||
|
||||
i = strlen(line);
|
||||
for(; i < 20; i++)
|
||||
strcat(line, " ");
|
||||
strcat(line, " ");
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
const char *PR_GlobalStringNoContents(int32_t ofs)
|
||||
{
|
||||
static char line[512];
|
||||
int32_t i;
|
||||
ddef_t *def;
|
||||
|
||||
def = ED_GlobalAtOfs(ofs);
|
||||
if(!def)
|
||||
sprintf(line, "%" PRIi32 "(?)", ofs);
|
||||
else
|
||||
sprintf(line, "%" PRIi32 "(%s)", ofs, PR_GetString(def->s_name));
|
||||
|
||||
i = strlen(line);
|
||||
for(; i < 20; i++)
|
||||
strcat(line, " ");
|
||||
strcat(line, " ");
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
|
||||
|
||||
#define PR_STRING_ALLOCSLOTS 256
|
||||
|
||||
static void PR_AllocStringSlots(void)
|
||||
{
|
||||
pr_maxknownstrings += PR_STRING_ALLOCSLOTS;
|
||||
Con_DPrintf2("PR_AllocStringSlots: realloc'ing for %" PRIi32 " slots\n", pr_maxknownstrings);
|
||||
pr_knownstrings = (const char **) Z_Realloc(pr_knownstrings, pr_maxknownstrings * sizeof(char *));
|
||||
}
|
||||
|
||||
const char *PR_GetString(int32_t num)
|
||||
{
|
||||
if(num >= 0 && num < progs.numstrings)
|
||||
return pr_strings + num;
|
||||
else if(num < 0 && num >= -pr_numknownstrings)
|
||||
{
|
||||
if(!pr_knownstrings[-1 - num])
|
||||
{
|
||||
Host_Error("PR_GetString: attempt to get a non-existant string %" PRIi32 "\n", num);
|
||||
return "";
|
||||
}
|
||||
return pr_knownstrings[-1 - num];
|
||||
}
|
||||
else
|
||||
{
|
||||
Host_Error("PR_GetString: invalid string offset %" PRIi32 "\n", num);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
int32_t PR_SetEngineString(const char *s)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
if(!s)
|
||||
return 0;
|
||||
if(s >= pr_strings && s <= pr_strings + progs.numstrings - 2)
|
||||
return (int32_t)(s - pr_strings);
|
||||
for(i = 0; i < pr_numknownstrings; i++)
|
||||
{
|
||||
if(pr_knownstrings[i] == s)
|
||||
return -1 - i;
|
||||
}
|
||||
if(i >= pr_maxknownstrings)
|
||||
PR_AllocStringSlots();
|
||||
pr_numknownstrings++;
|
||||
pr_knownstrings[i] = s;
|
||||
return -1 - i;
|
||||
}
|
||||
|
||||
int32_t PR_AllocString(int32_t size, char **ptr)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
if(!size)
|
||||
return 0;
|
||||
for(i = 0; i < pr_numknownstrings; i++)
|
||||
{
|
||||
if(!pr_knownstrings[i])
|
||||
break;
|
||||
}
|
||||
if(i >= pr_maxknownstrings)
|
||||
PR_AllocStringSlots();
|
||||
pr_numknownstrings++;
|
||||
pr_knownstrings[i] = (char *)Hunk_AllocName(size, "string");
|
||||
if(ptr)
|
||||
*ptr = (char *) pr_knownstrings[i];
|
||||
return -1 - i;
|
||||
}
|
||||
|
|
@ -65,8 +65,18 @@ extern dstatement_t *pr_statements;
|
|||
extern globalvars_t *pr_global_struct;
|
||||
extern float *pr_globals;
|
||||
|
||||
extern ddef_t *pr_fielddefs;
|
||||
extern int32_t pr_edict_size;
|
||||
|
||||
extern char *pr_strings;
|
||||
extern const char **pr_knownstrings;
|
||||
extern int32_t pr_maxknownstrings;
|
||||
extern int32_t pr_numknownstrings;
|
||||
|
||||
extern ddef_t *pr_globaldefs;
|
||||
|
||||
const char *PR_ValueString(int32_t type, eval_t *val);
|
||||
const char *PR_UglyValueString(int32_t type, eval_t *val);
|
||||
|
||||
void PR_Init(void);
|
||||
|
||||
|
@ -91,6 +101,13 @@ const char *ED_ParseGlobals(const char *data);
|
|||
|
||||
void ED_LoadFromFile(const char *data);
|
||||
|
||||
ddef_t *ED_GlobalAtOfs(int32_t ofs);
|
||||
ddef_t *ED_FieldAtOfs(int32_t ofs);
|
||||
bool ED_ParseEpair(void *base, ddef_t *key, const char *s);
|
||||
|
||||
void ED_Init(void);
|
||||
void ED_Load(void);
|
||||
|
||||
edict_t *EDICT_NUM(int32_t n);
|
||||
int32_t NUM_FOR_EDICT(edict_t *e);
|
||||
|
||||
|
@ -120,6 +137,8 @@ extern int32_t pr_xstatement;
|
|||
|
||||
extern uint16_t pr_crc;
|
||||
|
||||
extern bool pr_alpha_supported; //johnfitz
|
||||
|
||||
noreturn void PR_RunError(const char *error, ...) FUNC_PRINTF(1, 2);
|
||||
|
||||
void ED_PrintEdicts(void);
|
||||
|
|
|
@ -29,13 +29,7 @@
|
|||
#include "snd_vorbis.h"
|
||||
|
||||
#define OV_EXCLUDE_STATIC_CALLBACKS
|
||||
#if defined(VORBIS_USE_TREMOR)
|
||||
/* for Tremor / Vorbisfile api differences,
|
||||
* see doc/diff.html in the Tremor package. */
|
||||
#include <tremor/ivorbisfile.h>
|
||||
#else
|
||||
#include <vorbis/vorbisfile.h>
|
||||
#endif
|
||||
|
||||
/* Vorbis codec can return the samples in a number of different
|
||||
* formats, we use the standard int16_t format. */
|
||||
|
@ -161,11 +155,9 @@ static int32_t S_VORBIS_CodecReadStream(snd_stream_t *stream, int32_t bytes, voi
|
|||
* the channels are interleaved in the output buffer.
|
||||
*/
|
||||
res = ov_read((OggVorbis_File *)stream->priv, ptr, rem,
|
||||
#if !defined(VORBIS_USE_TREMOR)
|
||||
host_bigendian,
|
||||
VORBIS_SAMPLEWIDTH,
|
||||
VORBIS_SIGNED_DATA,
|
||||
#endif
|
||||
& section);
|
||||
if(res <= 0)
|
||||
break;
|
||||
|
|
|
@ -30,8 +30,6 @@ static char localmodels[MAX_MODELS][8]; // inline model names for precac
|
|||
|
||||
int32_t sv_protocol = PROTOCOL_FITZQUAKE; //johnfitz
|
||||
|
||||
extern bool pr_alpha_supported; //johnfitz
|
||||
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue