quakespasm/Quake/pr_edict.c

1574 lines
38 KiB
C
Raw Normal View History

/*
Copyright (C) 1996-2001 Id Software, Inc.
Copyright (C) 2002-2009 John Fitzgibbons and others
Copyright (C) 2010-2014 QuakeSpasm developers
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.
*/
// sv_edict.c -- entity dictionary
#include "quakedef.h"
int type_size[8] = {
1, // ev_void
1, // sizeof(string_t) / 4 // ev_string
1, // ev_float
3, // ev_vector
1, // ev_entity
1, // ev_field
1, // sizeof(func_t) / 4 // ev_function
1 // sizeof(void *) / 4 // ev_pointer
};
static ddef_t *ED_FieldAtOfs (int ofs);
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
Sets everything to NULL
=================
*/
void ED_ClearEdict (edict_t *e)
{
memset (&e->v, 0, qcvm->progs->entityfields * 4);
e->free = false;
}
/*
=================
ED_Alloc
Either finds a free edict, or allocates a new one.
Try to avoid reusing an entity that was recently freed, because it
can cause the client to think the entity morphed into something else
instead of being removed and recreated, which can cause interpolated
angles and bad trails.
=================
*/
edict_t *ED_Alloc (void)
{
int i;
edict_t *e;
for (i = qcvm->reserved_edicts; i < qcvm->num_edicts; i++)
{
e = EDICT_NUM(i);
// the first couple seconds of server time can involve a lot of
// freeing and allocating, so relax the replacement policy
if (e->free && ( e->freetime < 2 || qcvm->time - e->freetime > 0.5 ) )
{
ED_ClearEdict (e);
return e;
}
}
if (i == qcvm->max_edicts) //johnfitz -- use sv.max_edicts instead of MAX_EDICTS
Host_Error ("ED_Alloc: no free edicts (max_edicts is %i)", qcvm->max_edicts);
qcvm->num_edicts++;
e = EDICT_NUM(i);
memset(e, 0, qcvm->edict_size); // ericw -- switched sv.edicts to malloc(), so we are accessing uninitialized memory and must fully zero it, not just ED_ClearEdict
e->baseline = nullentitystate;
return e;
}
/*
=================
ED_Free
Marks the edict as free
FIXME: walk all entities and NULL out references to this entity
=================
*/
void ED_Free (edict_t *ed)
{
SV_UnlinkEdict (ed); // unlink from world bsp
ed->free = true;
ed->v.model = 0;
ed->v.takedamage = 0;
ed->v.modelindex = 0;
ed->v.colormap = 0;
ed->v.skin = 0;
ed->v.frame = 0;
VectorCopy (vec3_origin, ed->v.origin);
VectorCopy (vec3_origin, ed->v.angles);
ed->v.nextthink = -1;
ed->v.solid = 0;
ed->alpha = ENTALPHA_DEFAULT; //johnfitz -- reset alpha for next entity
ed->freetime = qcvm->time;
}
//===========================================================================
/*
============
ED_GlobalAtOfs
============
*/
static ddef_t *ED_GlobalAtOfs (int ofs)
{
ddef_t *def;
int i;
for (i = 0; i < qcvm->progs->numglobaldefs; i++)
{
def = &qcvm->globaldefs[i];
if (def->ofs == ofs)
return def;
}
return NULL;
}
/*
============
ED_FieldAtOfs
============
*/
static ddef_t *ED_FieldAtOfs (int ofs)
{
ddef_t *def;
int i;
for (i = 0; i < qcvm->progs->numfielddefs; i++)
{
def = &qcvm->fielddefs[i];
if (def->ofs == ofs)
return def;
}
return NULL;
}
/*
============
ED_FindField
============
*/
ddef_t *ED_FindField (const char *name)
{
ddef_t *def;
int i;
for (i = 0; i < qcvm->progs->numfielddefs; i++)
{
def = &qcvm->fielddefs[i];
if ( !strcmp(PR_GetString(def->s_name), name) )
return def;
}
return NULL;
}
/*
*/
int ED_FindFieldOffset (const char *name)
{
ddef_t *def = ED_FindField(name);
if (!def)
return -1;
return def->ofs;
}
/*
============
ED_FindGlobal
============
*/
ddef_t *ED_FindGlobal (const char *name)
{
ddef_t *def;
int i;
for (i = 0; i < qcvm->progs->numglobaldefs; i++)
{
def = &qcvm->globaldefs[i];
if ( !strcmp(PR_GetString(def->s_name), name) )
return def;
}
return NULL;
}
/*
============
ED_FindFunction
============
*/
dfunction_t *ED_FindFunction (const char *fn_name)
{
dfunction_t *func;
int i;
for (i = 0; i < qcvm->progs->numfunctions; i++)
{
func = &qcvm->functions[i];
if ( !strcmp(PR_GetString(func->s_name), fn_name) )
return func;
}
return NULL;
}
/*
============
GetEdictFieldValue
============
*/
eval_t *GetEdictFieldValue(edict_t *ed, int fldofs)
{
if (fldofs < 0)
return NULL;
return (eval_t *)((char *)&ed->v + fldofs*4);
}
/*
============
PR_ValueString
(etype_t type, eval_t *val)
Returns a string describing *data in a type specific manner
=============
*/
static const char *PR_ValueString (int type, eval_t *val)
{
static char line[512];
ddef_t *def;
dfunction_t *f;
type &= ~DEF_SAVEGLOBAL;
switch (type)
{
case ev_string:
q_snprintf (line, sizeof(line), "%s", PR_GetString(val->string));
break;
case ev_entity:
q_snprintf (line, sizeof(line), "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) );
break;
case ev_function:
f = qcvm->functions + val->function;
q_snprintf (line, sizeof(line), "%s()", PR_GetString(f->s_name));
break;
case ev_field:
def = ED_FieldAtOfs ( val->_int );
q_snprintf (line, sizeof(line), ".%s", PR_GetString(def->s_name));
break;
case ev_void:
q_snprintf (line, sizeof(line), "void");
break;
case ev_float:
q_snprintf (line, sizeof(line), "%5.1f", val->_float);
break;
case ev_ext_double:
q_snprintf (line, sizeof(line), "%5.1f", val->_double);
break;
case ev_ext_integer:
sprintf (line, "%i", val->_int);
break;
case ev_ext_uint32:
sprintf (line, "%u", val->_uint32);
break;
case ev_ext_sint64:
sprintf (line, "%"PRIi64, val->_sint64);
break;
case ev_ext_uint64:
sprintf (line, "%"PRIu64, val->_uint64);
break;
case ev_vector:
q_snprintf (line, sizeof(line), "'%5.1f %5.1f %5.1f'", val->vector[0], val->vector[1], val->vector[2]);
break;
case ev_pointer:
q_snprintf (line, sizeof(line), "pointer");
break;
default:
q_snprintf (line, sizeof(line), "bad type %i", 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 (int type, eval_t *val)
{
static char line[1024];
ddef_t *def;
dfunction_t *f;
type &= ~DEF_SAVEGLOBAL;
switch (type)
{
case ev_string:
q_snprintf (line, sizeof(line), "%s", PR_GetString(val->string));
break;
case ev_entity:
q_snprintf (line, sizeof(line), "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
break;
case ev_function:
f = qcvm->functions + val->function;
q_snprintf (line, sizeof(line), "%s", PR_GetString(f->s_name));
break;
case ev_field:
def = ED_FieldAtOfs ( val->_int );
q_snprintf (line, sizeof(line), "%s", PR_GetString(def->s_name));
break;
case ev_void:
q_snprintf (line, sizeof(line), "void");
break;
case ev_float:
q_snprintf (line, sizeof(line), "%f", val->_float);
break;
case ev_ext_integer:
sprintf (line, "%i", val->_int);
break;
case ev_ext_uint32:
sprintf (line, "%u", val->_uint32);
break;
case ev_ext_sint64:
sprintf (line, "%"PRIi64, val->_sint64);
break;
case ev_ext_uint64:
sprintf (line, "%"PRIu64, val->_uint64);
break;
case ev_ext_double:
q_snprintf (line, sizeof(line), "%f", val->_double);
break;
case ev_vector:
q_snprintf (line, sizeof(line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
break;
default:
q_snprintf (line, sizeof(line), "bad type %i", 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 (int ofs)
{
static char line[512];
const char *s;
int i;
ddef_t *def;
void *val;
val = (void *)&qcvm->globals[ofs];
def = ED_GlobalAtOfs(ofs);
if (!def)
q_snprintf (line, sizeof(line), "%i(?)", ofs);
else
{
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
s = PR_ValueString (def->type, (eval_t *)val);
q_snprintf (line, sizeof(line), "%i(%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 (int ofs)
{
static char line[512];
int i;
ddef_t *def;
def = ED_GlobalAtOfs(ofs);
if (!def)
q_snprintf (line, sizeof(line), "%i(?)", ofs);
else
q_snprintf (line, sizeof(line), "%i(%s)", ofs, PR_GetString(def->s_name));
i = strlen(line);
for ( ; i < 20; i++)
strcat (line, " ");
strcat (line, " ");
return line;
}
/*
=============
ED_Print
For debugging
=============
*/
void ED_Print (edict_t *ed)
{
ddef_t *d;
int *v;
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
int i, j, l;
const char *name;
int type;
if (ed->free)
{
Con_Printf ("FREE\n");
return;
}
Con_SafePrintf("\nEDICT %i:\n", NUM_FOR_EDICT(ed)); //johnfitz -- was Con_Printf
for (i = 1; i < qcvm->progs->numfielddefs; i++)
{
d = &qcvm->fielddefs[i];
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
name = PR_GetString(d->s_name);
l = strlen (name);
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
if (l > 1 && name[l - 2] == '_')
continue; // skip _x, _y, _z vars
v = (int *)((char *)&ed->v + d->ofs*4);
// if the value is still all 0, skip the field
type = d->type & ~DEF_SAVEGLOBAL;
for (j = 0; j < type_size[type]; j++)
{
if (v[j])
break;
}
if (j == type_size[type])
continue;
Con_SafePrintf ("%s", name); //johnfitz -- was Con_Printf
while (l++ < 15)
Con_SafePrintf (" "); //johnfitz -- was Con_Printf
Con_SafePrintf ("%s\n", PR_ValueString(d->type, (eval_t *)v)); //johnfitz -- was Con_Printf
}
}
/*
=============
ED_Write
For savegames
=============
*/
void ED_Write (FILE *f, edict_t *ed)
{
ddef_t *d;
int *v;
int i, j;
const char *name;
int type;
fprintf (f, "{\n");
if (ed->free)
{
fprintf (f, "}\n");
return;
}
for (i = 1; i < qcvm->progs->numfielddefs; i++)
{
d = &qcvm->fielddefs[i];
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
name = PR_GetString(d->s_name);
j = strlen (name);
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
if (j > 1 && name[j - 2] == '_')
continue; // skip _x, _y, _z vars
v = (int *)((char *)&ed->v + d->ofs*4);
// if the value is still all 0, skip the field
type = d->type & ~DEF_SAVEGLOBAL;
for (j = 0; j < type_size[type]; j++)
{
if (v[j])
break;
}
if (j == type_size[type])
continue;
fprintf (f, "\"%s\" ", name);
fprintf (f, "\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
}
//johnfitz -- save entity alpha manually when progs.dat doesn't know about alpha
if (qcvm->extfields.alpha<0 && ed->alpha != ENTALPHA_DEFAULT)
fprintf (f, "\"alpha\" \"%f\"\n", ENTALPHA_TOSAVE(ed->alpha));
//johnfitz
fprintf (f, "}\n");
}
void ED_PrintNum (int ent)
{
ED_Print (EDICT_NUM(ent));
}
/*
=============
ED_PrintEdicts
For debugging, prints all the entities in the current server
=============
*/
void ED_PrintEdicts (void)
{
int i;
if (!sv.active)
return;
PR_SwitchQCVM(&sv.qcvm);
Con_Printf ("%i entities\n", qcvm->num_edicts);
for (i = 0; i < qcvm->num_edicts; i++)
ED_PrintNum (i);
PR_SwitchQCVM(NULL);
}
/*
=============
ED_PrintEdict_f
For debugging, prints a single edicy
=============
*/
static void ED_PrintEdict_f (void)
{
int i;
if (!sv.active)
return;
i = Q_atoi (Cmd_Argv(1));
PR_SwitchQCVM(&sv.qcvm);
if (i < 0 || i >= qcvm->num_edicts)
Con_Printf("Bad edict number\n");
else
{
if (Cmd_Argc() == 2 || svs.maxclients != 1) //edict N
ED_PrintNum (i);
else //edict N FLD ...
{
ddef_t *def = ED_FindField(Cmd_Argv(2));
if (!def)
Con_Printf("Field %s not defined\n", Cmd_Argv(2));
else if (Cmd_Argc() < 4)
Con_Printf("Edict %u.%s==%s\n", i, PR_GetString(def->s_name), PR_UglyValueString(def->type&~DEF_SAVEGLOBAL, (eval_t *)((char *)&EDICT_NUM(i)->v + def->ofs*4)));
else
2020-07-19 00:47:06 +00:00
ED_ParseEpair((void *)&EDICT_NUM(i)->v, def, Cmd_Argv(3), false);
}
}
PR_SwitchQCVM(NULL);
}
/*
=============
ED_Count
For debugging
=============
*/
static void ED_Count (void)
{
edict_t *ent;
int i, active, models, solid, step;
if (!sv.active)
return;
PR_SwitchQCVM(&sv.qcvm);
active = models = solid = step = 0;
for (i = 0; i < qcvm->num_edicts; i++)
{
ent = EDICT_NUM(i);
if (ent->free)
continue;
active++;
if (ent->v.solid)
solid++;
if (ent->v.model)
models++;
if (ent->v.movetype == MOVETYPE_STEP)
step++;
}
Con_Printf ("num_edicts:%3i\n", qcvm->num_edicts);
Con_Printf ("active :%3i\n", active);
Con_Printf ("view :%3i\n", models);
Con_Printf ("touch :%3i\n", solid);
Con_Printf ("step :%3i\n", step);
PR_SwitchQCVM(NULL);
}
/*
==============================================================================
ARCHIVING GLOBALS
FIXME: need to tag constants, doesn't really work
==============================================================================
*/
/*
=============
ED_WriteGlobals
=============
*/
void ED_WriteGlobals (FILE *f)
{
ddef_t *def;
int i;
const char *name;
int type;
fprintf (f, "{\n");
for (i = 0; i < qcvm->progs->numglobaldefs; i++)
{
def = &qcvm->globaldefs[i];
type = def->type;
if ( !(def->type & DEF_SAVEGLOBAL) )
continue;
type &= ~DEF_SAVEGLOBAL;
if (type != ev_string && type != ev_float && type != ev_ext_double && type != ev_ext_integer && type != ev_ext_uint32 && type != ev_ext_sint64 && type != ev_ext_uint64 && type != ev_entity)
continue;
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
name = PR_GetString(def->s_name);
fprintf (f, "\"%s\" ", name);
fprintf (f, "\"%s\"\n", PR_UglyValueString(type, (eval_t *)&qcvm->globals[def->ofs]));
}
fprintf (f, "}\n");
}
/*
=============
ED_ParseGlobals
=============
*/
const char *ED_ParseGlobals (const char *data)
{
char keyname[64];
ddef_t *key;
while (1)
{
// parse key
data = COM_Parse (data);
if (com_token[0] == '}')
break;
if (!data)
Host_Error ("ED_ParseEntity: EOF without closing brace");
q_strlcpy (keyname, com_token, sizeof(keyname));
// parse value
data = COM_Parse (data);
if (!data)
Host_Error ("ED_ParseEntity: EOF without closing brace");
if (com_token[0] == '}')
Host_Error ("ED_ParseEntity: closing brace without data");
key = ED_FindGlobal (keyname);
if (!key)
{
Con_Printf ("'%s' is not a global\n", keyname);
continue;
}
2020-07-19 00:47:06 +00:00
if (!ED_ParseEpair ((void *)qcvm->globals, key, com_token, false))
Host_Error ("ED_ParseGlobals: parse error");
}
return data;
}
//============================================================================
/*
=============
ED_NewString
=============
*/
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
static string_t ED_NewString (const char *string)
{
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
char *new_p;
int i, l;
string_t num;
l = strlen(string) + 1;
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
num = PR_AllocString (l, &new_p);
for (i = 0; i < l; i++)
{
if (string[i] == '\\' && i < l-1)
{
i++;
if (string[i] == 'n')
*new_p++ = '\n';
else
*new_p++ = '\\';
}
else
*new_p++ = string[i];
}
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
return num;
}
2020-07-19 00:47:06 +00:00
static void ED_RezoneString (string_t *ref, const char *str)
{
char *buf;
size_t len = strlen(str)+1;
size_t id;
if (*ref)
{ //if the reference is already a zoned string then free it first.
id = -1-*ref;
if (id < qcvm->knownzonesize && (qcvm->knownzone[id>>3] & (1u<<(id&7))))
{ //okay, it was zoned.
qcvm->knownzone[id>>3] &= ~(1u<<(id&7));
buf = (char*)PR_GetString(*ref);
PR_ClearEngineString(*ref);
Z_Free(buf);
}
// else
// Con_Warning("ED_RezoneString: string wasn't strzoned\n"); //warnings would trigger from the default cvar value that autocvars are initialised with
}
2020-07-19 00:47:06 +00:00
buf = Z_Malloc(len);
memcpy(buf, str, len);
id = -1-(*ref = PR_SetEngineString(buf));
//make sure its flagged as zoned so we can clean up properly after.
if (id >= qcvm->knownzonesize)
{
qcvm->knownzonesize = (id+32)&~7;
qcvm->knownzone = Z_Realloc(qcvm->knownzone, (qcvm->knownzonesize+7)>>3);
}
qcvm->knownzone[id>>3] |= 1u<<(id&7);
}
/*
=============
ED_ParseEval
Can parse either fields or globals
returns false if error
=============
*/
2020-07-19 00:47:06 +00:00
qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s, qboolean zoned)
{
int i;
char string[128];
ddef_t *def;
char *v, *w;
char *end;
void *d;
dfunction_t *func;
d = (void *)((int *)base + key->ofs);
switch (key->type & ~DEF_SAVEGLOBAL)
{
case ev_string:
2020-07-19 00:47:06 +00:00
if (zoned) //zoned version allows us to change the strings more freely
ED_RezoneString((string_t *)d, s);
else
*(string_t *)d = ED_NewString(s);
break;
case ev_float:
*(float *)d = atof (s);
break;
case ev_ext_double:
*(qcdouble_t *)d = atof (s);
break;
case ev_ext_integer:
*(int32_t *)d = atoi (s);
break;
case ev_ext_uint32:
*(uint32_t *)d = atoi (s);
break;
case ev_ext_sint64:
*(qcsint64_t *)d = strtoll(s, NULL, 0); //if longlong is 128bit then no real harm done for 64bit quantities...
break;
case ev_ext_uint64:
*(qcuint64_t *)d = strtoull(s, NULL, 0);
break;
case ev_vector:
q_strlcpy (string, s, sizeof(string));
end = (char *)string + strlen(string);
v = string;
w = string;
for (i = 0; i < 3 && (w <= end); i++) // ericw -- added (w <= end) check
{
// set v to the next space (or 0 byte), and change that char to a 0 byte
while (*v && *v != ' ')
v++;
*v = 0;
((float *)d)[i] = atof (w);
w = v = v+1;
}
// ericw -- fill remaining elements to 0 in case we hit the end of string
// before reading 3 floats.
if (i < 3)
{
Con_DWarning ("Avoided reading garbage for \"%s\" \"%s\"\n", PR_GetString(key->s_name), s);
for (; i < 3; i++)
((float *)d)[i] = 0.0f;
}
break;
case ev_entity:
2018-05-05 15:18:07 +00:00
if (!strncmp(s, "entity ", 7)) //Spike: putentityfieldstring/etc should be able to cope with etos's weirdness.
s += 7;
*(int *)d = EDICT_TO_PROG(EDICT_NUM(atoi (s)));
break;
case ev_field:
def = ED_FindField (s);
if (!def)
{
//johnfitz -- HACK -- suppress error becuase fog/sky fields might not be mentioned in defs.qc
if (strncmp(s, "sky", 3) && strcmp(s, "fog"))
Con_DPrintf ("Can't find field %s\n", s);
return false;
}
*(int *)d = G_INT(def->ofs);
break;
case ev_function:
func = ED_FindFunction (s);
if (!func)
{
Con_Printf ("Can't find function %s\n", s);
return false;
}
*(func_t *)d = func - qcvm->functions;
break;
default:
break;
}
return true;
}
/*
====================
ED_ParseEdict
Parses an edict out of the given string, returning the new position
ed should be a properly initialized empty edict.
Used for initial level load and for savegames.
====================
*/
const char *ED_ParseEdict (const char *data, edict_t *ent)
{
ddef_t *key;
char keyname[256];
qboolean anglehack, init;
int n;
init = false;
// clear it
if (ent != qcvm->edicts) // hack
memset (&ent->v, 0, qcvm->progs->entityfields * 4);
// go through all the dictionary pairs
while (1)
{
// parse key
data = COM_Parse (data);
if (com_token[0] == '}')
break;
if (!data)
Host_Error ("ED_ParseEntity: EOF without closing brace");
// anglehack is to allow QuakeEd to write single scalar angles
// and allow them to be turned into vectors. (FIXME...)
if (!strcmp(com_token, "angle"))
{
strcpy (com_token, "angles");
anglehack = true;
}
else
anglehack = false;
// FIXME: change light to _light to get rid of this hack
if (!strcmp(com_token, "light"))
strcpy (com_token, "light_lev"); // hack for single light def
q_strlcpy (keyname, com_token, sizeof(keyname));
// another hack to fix keynames with trailing spaces
n = strlen(keyname);
while (n && keyname[n-1] == ' ')
{
keyname[n-1] = 0;
n--;
}
// parse value
data = COM_Parse (data);
if (!data)
Host_Error ("ED_ParseEntity: EOF without closing brace");
if (com_token[0] == '}')
Host_Error ("ED_ParseEntity: closing brace without data");
init = true;
// keynames with a leading underscore are used for utility comments,
// and are immediately discarded by quake
if (keyname[0] == '_')
{
//spike -- hacks to support func_illusionary with all sorts of mdls, and various particle effects
if (qcvm == &sv.qcvm)
{
if (!strcmp(keyname, "_precache_model") && sv.state == ss_loading)
SV_Precache_Model(PR_GetString(ED_NewString(com_token)));
else if (!strcmp(keyname, "_precache_sound") && sv.state == ss_loading)
SV_Precache_Sound(PR_GetString(ED_NewString(com_token)));
}
//spike
continue;
}
//johnfitz -- hack to support .alpha even when progs.dat doesn't know about it
if (!strcmp(keyname, "alpha"))
ent->alpha = ENTALPHA_ENCODE(Q_atof(com_token));
//johnfitz
//spike -- hacks to support func_illusionary/info_notnull with all sorts of mdls, and various particle effects
if (!strcmp(keyname, "modelindex") && qcvm == &sv.qcvm && sv.state == ss_loading)
{
//"model" "progs/foobar.mdl"
//"modelindex" "progs/foobar.mdl"
//"mins" "-16 -16 -16"
//"maxs" "16 16 16"
char *e;
strtol(com_token, &e, 0);
if (e != com_token && *e)
ent->v.modelindex = SV_Precache_Model(PR_GetString(ED_NewString(com_token)));
}
//spike
key = ED_FindField (keyname);
if (!key)
{
#ifdef PSET_SCRIPT
eval_t *val;
if (!strcmp(keyname, "traileffect") && qcvm == &sv.qcvm && sv.state == ss_loading)
{
if ((val = GetEdictFieldValue(ent, qcvm->extfields.traileffectnum)))
val->_float = PF_SV_ForceParticlePrecache(com_token);
}
else if (!strcmp(keyname, "emiteffect") && qcvm == &sv.qcvm && sv.state == ss_loading)
{
if ((val = GetEdictFieldValue(ent, qcvm->extfields.emiteffectnum)))
val->_float = PF_SV_ForceParticlePrecache(com_token);
}
//johnfitz -- HACK -- suppress error becuase fog/sky/alpha fields might not be mentioned in defs.qc
else
#endif
if (strncmp(keyname, "sky", 3) && strcmp(keyname, "fog") && strcmp(keyname, "alpha"))
Con_DPrintf ("\"%s\" is not a field\n", keyname); //johnfitz -- was Con_Printf
continue;
}
if (anglehack)
{
char temp[32];
strcpy (temp, com_token);
sprintf (com_token, "0 %s 0", temp);
}
if (!ED_ParseEpair ((void *)&ent->v, key, com_token, qcvm != &sv.qcvm))
Host_Error ("ED_ParseEdict: parse error");
}
if (!init)
ent->free = true;
return data;
}
/*
================
ED_LoadFromFile
The entities are directly placed in the array, rather than allocated with
ED_Alloc, because otherwise an error loading the map would have entity
number references out of order.
Creates a server's entity / program execution context by
parsing textual entity definitions out of an ent file.
Used for both fresh maps and savegame loads. A fresh map would also need
to call ED_CallSpawnFunctions () to let the objects initialize themselves.
================
*/
void ED_LoadFromFile (const char *data)
{
dfunction_t *func;
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
edict_t *ent = NULL;
int inhibit = 0;
int usingspawnfunc = 0;
pr_global_struct->time = qcvm->time;
// parse ents
while (1)
{
// parse the opening brace
data = COM_Parse (data);
if (!data)
break;
if (com_token[0] != '{')
Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
if (!ent)
ent = EDICT_NUM(0);
else
ent = ED_Alloc ();
data = ED_ParseEdict (data, ent);
// remove things from different skill levels or deathmatch
if (deathmatch.value)
{
if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
{
ED_Free (ent);
inhibit++;
continue;
}
}
else if ((current_skill == 0 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_EASY))
|| (current_skill == 1 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_MEDIUM))
|| (current_skill >= 2 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_HARD)) )
{
ED_Free (ent);
inhibit++;
continue;
}
//
// immediately call spawn function
//
if (!ent->v.classname)
{
Con_SafePrintf ("No classname for:\n"); //johnfitz -- was Con_Printf
ED_Print (ent);
ED_Free (ent);
continue;
}
// look for the spawn function
//
func = ED_FindFunction (va("spawnfunc_%s", PR_GetString(ent->v.classname)));
if (func)
{
if (!usingspawnfunc++)
Con_DPrintf2 ("Using DP_SV_SPAWNFUNC_PREFIX\n");
}
else
func = ED_FindFunction ( PR_GetString(ent->v.classname) );
if (!func)
{
const char *classname = PR_GetString(ent->v.classname);
if (!strcmp(classname, "misc_model"))
PR_spawnfunc_misc_model(ent);
else
{
Con_SafePrintf ("No spawn function for:\n"); //johnfitz -- was Con_Printf
ED_Print (ent);
ED_Free (ent);
}
continue;
}
pr_global_struct->self = EDICT_TO_PROG(ent);
PR_ExecuteProgram (func - qcvm->functions);
}
Con_DPrintf ("%i entities inhibited\n", inhibit);
}
#ifndef PR_SwitchQCVM
qcvm_t *qcvm;
globalvars_t *pr_global_struct;
void PR_SwitchQCVM(qcvm_t *nvm)
{
if (qcvm && nvm)
Sys_Error("PR_SwitchQCVM: A qcvm was already active");
qcvm = nvm;
if (qcvm)
pr_global_struct = (globalvars_t*)qcvm->globals;
else
pr_global_struct = NULL;
}
#endif
void PR_ClearProgs(qcvm_t *vm)
{
qcvm_t *oldvm = qcvm;
if (!vm->progs)
return; //wasn't loaded.
qcvm = NULL;
PR_SwitchQCVM(vm);
PR_ShutdownExtensions();
if (qcvm->knownstrings)
Z_Free ((void *)qcvm->knownstrings);
free(qcvm->edicts); // ericw -- sv.edicts switched to use malloc()
if (qcvm->fielddefs != (ddef_t *)((byte *)qcvm->progs + qcvm->progs->ofs_fielddefs))
free(qcvm->fielddefs);
free(qcvm->progs); // spike -- pr_progs switched to use malloc (so menuqc doesn't end up stuck on the early hunk nor wiped on every map change)
memset(qcvm, 0, sizeof(*qcvm));
qcvm = NULL;
PR_SwitchQCVM(oldvm);
}
//makes sure extension fields are actually registered so they can be used for mappers without qc changes. eg so scale can be used.
static void PR_MergeEngineFieldDefs (void)
{
struct {
const char *fname;
etype_t type;
int newidx;
} extrafields[] =
{ //table of engine fields to add. we'll be using ED_FindFieldOffset for these later.
//this is useful for fields that should be defined for mappers which are not defined by the mod.
//future note: mutators will need to edit the mutator's globaldefs table too. remember to handle vectors and their 3 globals too.
{"alpha", ev_float}, //just because we can (though its already handled in a weird hacky way)
{"scale", ev_float}, //hurrah for being able to rescale entities.
{"emiteffectnum", ev_float}, //constantly emitting particles, even without moving.
{"traileffectnum", ev_float}, //custom effect for trails
//{"glow_size", ev_float}, //deprecated particle trail rubbish
//{"glow_color", ev_float}, //deprecated particle trail rubbish
{"tag_entity", ev_float}, //for setattachment to not bug out when omitted.
{"tag_index", ev_float}, //for setattachment to not bug out when omitted.
{"modelflags", ev_float}, //deprecated rubbish to fill the high 8 bits of effects.
//{"vw_index", ev_float}, //modelindex2
//{"pflags", ev_float}, //for rtlights
//{"drawflags", ev_float}, //hexen2 compat
//{"abslight", ev_float}, //hexen2 compat
{"colormod", ev_vector}, //lighting tints
//{"glowmod", ev_vector}, //fullbright tints
//{"fatness", ev_float}, //bloated rendering...
//{"gravitydir", ev_vector}, //says which direction gravity should act for this ent...
{"pmove_flags", ev_float}, //if runstandardplayerphysics is to work, it needs somewhere to track a couple of flags.
};
int maxofs = qcvm->progs->entityfields;
int maxdefs = qcvm->progs->numfielddefs;
unsigned int j, a;
//figure out where stuff goes
for (j = 0; j < countof(extrafields); j++)
{
extrafields[j].newidx = ED_FindFieldOffset(extrafields[j].fname);
if (extrafields[j].newidx < 0)
{
extrafields[j].newidx = maxofs;
maxdefs++;
if (extrafields[j].type == ev_vector)
maxdefs+=3;
maxofs+=type_size[extrafields[j].type];
}
}
if (maxdefs != qcvm->progs->numfielddefs)
{ //we now know how many entries we need to add...
ddef_t *olddefs = qcvm->fielddefs;
qcvm->fielddefs = malloc(maxdefs * sizeof(*qcvm->fielddefs));
memcpy(qcvm->fielddefs, olddefs, qcvm->progs->numfielddefs*sizeof(*qcvm->fielddefs));
if (olddefs != (ddef_t *)((byte *)qcvm->progs + qcvm->progs->ofs_fielddefs))
free(olddefs);
//allocate the extra defs
for (j = 0; j < countof(extrafields); j++)
{
if (extrafields[j].newidx >= qcvm->progs->entityfields && extrafields[j].newidx < maxofs)
{ //looks like its new. make sure ED_FindField can find it.
qcvm->fielddefs[qcvm->progs->numfielddefs].ofs = extrafields[j].newidx;
qcvm->fielddefs[qcvm->progs->numfielddefs].type = extrafields[j].type;
qcvm->fielddefs[qcvm->progs->numfielddefs].s_name = ED_NewString(extrafields[j].fname);
qcvm->progs->numfielddefs++;
if (extrafields[j].type == ev_vector)
{ //vectors are weird and annoying.
for (a = 0; a < 3; a++)
{
qcvm->fielddefs[qcvm->progs->numfielddefs].ofs = extrafields[j].newidx+a;
qcvm->fielddefs[qcvm->progs->numfielddefs].type = ev_float;
qcvm->fielddefs[qcvm->progs->numfielddefs].s_name = ED_NewString(va("%s_%c", extrafields[j].fname, 'x'+a));
qcvm->progs->numfielddefs++;
}
}
}
}
qcvm->progs->entityfields = maxofs;
}
}
/*
===============
PR_LoadProgs
===============
*/
2022-07-15 12:24:04 +00:00
qboolean PR_LoadProgs (const char *filename, qboolean fatal, unsigned int needcrc, const builtin_t *builtins, size_t numbuiltins)
{
int i;
PR_ClearProgs(qcvm); //just in case.
qcvm->progs = (dprograms_t *)COM_LoadMallocFile(filename, NULL);
if (!qcvm->progs)
return false;
qcvm->progssize = com_filesize;
CRC_Init (&qcvm->progscrc);
for (i = 0; i < com_filesize; i++)
CRC_ProcessByte (&qcvm->progscrc, ((byte *)qcvm->progs)[i]);
qcvm->progshash = Com_BlockChecksum(qcvm->progs, com_filesize);
// byte swap the header
for (i = 0; i < (int) sizeof(*qcvm->progs) / 4; i++)
((int *)qcvm->progs)[i] = LittleLong ( ((int *)qcvm->progs)[i] );
if (qcvm->progs->version != PROG_VERSION)
{
if (fatal)
Host_Error ("%s has wrong version number (%i should be %i)", filename, qcvm->progs->version, PROG_VERSION);
else
{
2018-07-07 14:05:34 +00:00
Con_Printf("%s ABI set not supported\n", filename);
qcvm->progs = NULL;
return false;
}
}
if (qcvm->progs->crc != needcrc)
{
if (fatal)
Host_Error ("%s system vars have been modified, progdefs.h is out of date", filename);
else
{
2018-07-07 14:05:34 +00:00
switch(qcvm->progs->crc)
{
case 22390: //full csqc
Con_Printf("%s - full csqc is not supported\n", filename);
break;
case 52195: //dp csqc
Con_Printf("%s - obsolete csqc is not supported\n", filename);
break;
case 54730: //quakeworld
Con_Printf("%s - quakeworld gamecode is not supported\n", filename);
break;
case 26940: //prerelease
Con_Printf("%s - prerelease gamecode is not supported\n", filename);
break;
case 32401: //tenebrae
Con_Printf("%s - tenebrae gamecode is not supported\n", filename);
break;
case 38488: //hexen2 release
case 26905: //hexen2 mission pack
case 14046: //hexen2 demo
Con_Printf("%s - hexen2 gamecode is not supported\n", filename);
break;
//case 5927: //nq PROGHEADER_CRC as above. shouldn't happen, obviously.
default:
Con_Printf("%s system vars are not supported\n", filename);
break;
}
qcvm->progs = NULL;
return false;
}
}
Con_DPrintf ("%s occupies %uK.\n", filename, (unsigned)(com_filesize/1024u));
qcvm->functions = (dfunction_t *)((byte *)qcvm->progs + qcvm->progs->ofs_functions);
qcvm->strings = (char *)qcvm->progs + qcvm->progs->ofs_strings;
if (qcvm->progs->ofs_strings + qcvm->progs->numstrings >= com_filesize)
Host_Error ("%s strings go past end of file\n", filename);
qcvm->globaldefs = (ddef_t *)((byte *)qcvm->progs + qcvm->progs->ofs_globaldefs);
qcvm->fielddefs = (ddef_t *)((byte *)qcvm->progs + qcvm->progs->ofs_fielddefs);
qcvm->statements = (dstatement_t *)((byte *)qcvm->progs + qcvm->progs->ofs_statements);
qcvm->globals = (float *)((byte *)qcvm->progs + qcvm->progs->ofs_globals);
pr_global_struct = (globalvars_t*)qcvm->globals;
qcvm->stringssize = qcvm->progs->numstrings;
// byte swap the lumps
for (i = 0; i < qcvm->progs->numstatements; i++)
{
qcvm->statements[i].op = LittleShort(qcvm->statements[i].op);
qcvm->statements[i].a = LittleShort(qcvm->statements[i].a);
qcvm->statements[i].b = LittleShort(qcvm->statements[i].b);
qcvm->statements[i].c = LittleShort(qcvm->statements[i].c);
}
for (i = 0; i < qcvm->progs->numfunctions; i++)
{
qcvm->functions[i].first_statement = LittleLong (qcvm->functions[i].first_statement);
qcvm->functions[i].parm_start = LittleLong (qcvm->functions[i].parm_start);
qcvm->functions[i].s_name = LittleLong (qcvm->functions[i].s_name);
qcvm->functions[i].s_file = LittleLong (qcvm->functions[i].s_file);
qcvm->functions[i].numparms = LittleLong (qcvm->functions[i].numparms);
qcvm->functions[i].locals = LittleLong (qcvm->functions[i].locals);
}
for (i = 0; i < qcvm->progs->numglobaldefs; i++)
{
qcvm->globaldefs[i].type = LittleShort (qcvm->globaldefs[i].type);
qcvm->globaldefs[i].ofs = LittleShort (qcvm->globaldefs[i].ofs);
qcvm->globaldefs[i].s_name = LittleLong (qcvm->globaldefs[i].s_name);
}
for (i = 0; i < qcvm->progs->numfielddefs; i++)
{
qcvm->fielddefs[i].type = LittleShort (qcvm->fielddefs[i].type);
if (qcvm->fielddefs[i].type & DEF_SAVEGLOBAL)
Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
qcvm->fielddefs[i].ofs = LittleShort (qcvm->fielddefs[i].ofs);
qcvm->fielddefs[i].s_name = LittleLong (qcvm->fielddefs[i].s_name);
}
for (i = 0; i < qcvm->progs->numglobals; i++)
((int *)qcvm->globals)[i] = LittleLong (((int *)qcvm->globals)[i]);
memcpy(qcvm->builtins, builtins, numbuiltins*sizeof(qcvm->builtins[0]));
qcvm->numbuiltins = numbuiltins;
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
//spike: detect extended fields from progs
PR_MergeEngineFieldDefs();
#define QCEXTFIELD(n,t) qcvm->extfields.n = ED_FindFieldOffset(#n);
QCEXTFIELDS_ALL
QCEXTFIELDS_GAME
QCEXTFIELDS_CL
QCEXTFIELDS_CS
QCEXTFIELDS_SS
#undef QCEXTFIELD
qcvm->edict_size = qcvm->progs->entityfields * 4 + sizeof(edict_t) - sizeof(entvars_t);
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
// round off to next highest whole word address (esp for Alpha)
// this ensures that pointers in the engine data area are always
// properly aligned
qcvm->edict_size += sizeof(void *) - 1;
qcvm->edict_size &= ~(sizeof(void *) - 1);
PR_SetEngineString("");
PR_EnableExtensions(qcvm->globaldefs);
return true;
}
/*
===============
PR_Init
===============
*/
void PR_Init (void)
{
Cmd_AddCommand ("edict", ED_PrintEdict_f);
Cmd_AddCommand ("edicts", ED_PrintEdicts);
Cmd_AddCommand ("edictcount", ED_Count);
Cmd_AddCommand ("profile", PR_Profile_f);
Cmd_AddCommand ("pr_dumpplatform", PR_DumpPlatform_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);
PR_InitExtensions();
}
edict_t *EDICT_NUM(int n)
{
if (n < 0 || n >= qcvm->max_edicts)
Host_Error ("EDICT_NUM: bad number %i", n);
return (edict_t *)((byte *)qcvm->edicts + (n)*qcvm->edict_size);
}
int NUM_FOR_EDICT(edict_t *e)
{
int b;
b = (byte *)e - (byte *)qcvm->edicts;
b = b / qcvm->edict_size;
if (b < 0 || b >= qcvm->num_edicts)
Host_Error ("NUM_FOR_EDICT: bad pointer");
return b;
}
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
//===========================================================================
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
#define PR_STRING_ALLOCSLOTS 256
static void PR_AllocStringSlots (void)
{
qcvm->maxknownstrings += PR_STRING_ALLOCSLOTS;
Con_DPrintf2("PR_AllocStringSlots: realloc'ing for %d slots\n", qcvm->maxknownstrings);
qcvm->knownstrings = (const char **) Z_Realloc ((void *)qcvm->knownstrings, qcvm->maxknownstrings * sizeof(char *));
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
}
const char *PR_GetString (int num)
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
{
if (num >= 0 && num < qcvm->stringssize)
return qcvm->strings + num;
else if (num < 0 && num >= -qcvm->numknownstrings)
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
{
if (!qcvm->knownstrings[-1 - num])
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
{
Host_Error ("PR_GetString: attempt to get a non-existant string %d\n", num);
return "";
}
return qcvm->knownstrings[-1 - num];
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
}
else
{
return qcvm->strings;
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
Host_Error("PR_GetString: invalid string offset %d\n", num);
return "";
}
}
void PR_ClearEngineString(int num)
{
if (num < 0 && num >= -qcvm->numknownstrings)
{
num = -1 - num;
qcvm->knownstrings[num] = NULL;
if (qcvm->freeknownstrings > num)
qcvm->freeknownstrings = num;
}
}
int PR_SetEngineString (const char *s)
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
{
int i;
if (!s)
return 0;
#if 0 /* can't: sv.model_precache & sv.sound_precache points to pr_strings */
if (s >= qcvm->strings && s <= qcvm->strings + qcvm->stringssize)
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
Host_Error("PR_SetEngineString: \"%s\" in pr_strings area\n", s);
#else
if (s >= qcvm->strings && s <= qcvm->strings + qcvm->stringssize - 2)
return (int)(s - qcvm->strings);
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
#endif
for (i = 0; i < qcvm->numknownstrings; i++)
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
{
if (qcvm->knownstrings[i] == s)
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
return -1 - i;
}
// new unknown engine string
//Con_DPrintf ("PR_SetEngineString: new engine string %p\n", s);
for (i = qcvm->freeknownstrings; ; i++)
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
{
if (i < qcvm->numknownstrings)
{
if (qcvm->knownstrings[i])
continue;
}
else
{
if (i >= qcvm->maxknownstrings)
PR_AllocStringSlots();
qcvm->numknownstrings++;
}
break;
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
}
qcvm->freeknownstrings = i+1;
qcvm->knownstrings[i] = s;
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
return -1 - i;
}
int PR_AllocString (int size, char **ptr)
{
int i;
if (!size)
return 0;
for (i = 0; i < qcvm->numknownstrings; i++)
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
{
if (!qcvm->knownstrings[i])
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
break;
}
// if (i >= pr_numknownstrings)
// {
if (i >= qcvm->maxknownstrings)
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
PR_AllocStringSlots();
qcvm->numknownstrings++;
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
// }
qcvm->knownstrings[i] = (char *)Hunk_AllocName(size, "string");
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
if (ptr)
*ptr = (char *) qcvm->knownstrings[i];
64 bit compatibility effort, 4/nn: x86_64 works just fine now, yey! the QuakeC interpreter used to use string pointer offsets from pr_strings even when the pointers lead to engine data which is often well out of 32bit range on a 64bit architecture and they lead to crashes. they now go through the new PR_SetEngineString and PR_GetString functions which turn any address outside the pr_strings area into an index into a table of engine string addresses, adding new string addresses to the table as needed. the engine strings table is allocated with 256 entries at first (see the PR_STRING_ALLOCSLOTS definition in pr_edict.c) and its size is incremented by 256 as needed and re-allocated on the zone. managing that allocation and reallocation is accomplished by the recently added Z_Realloc function. implementation based on the uhexen2 (hexen2: hammer of thyrion) engine which, in turn, is loosely based on twilight and quakeforge engines. pr_strings range check is from tyrquake. pr_edict.c: added the new PR_SetEngineString, PR_GetString, PR_AllocString public functions and the new private PR_AllocStringSlots function. made ED_NewString private to pr_edict.c and reworked it to return an index to a newly allocated string. progs.h: added prototypes for the new public PR_SetEngineString, PR_GetString and PR_AllocString functions. host_cmd.c, pr_cmds.c, pr_edict.c, pr_exec.c, progs.h, sv_main.c, sv_phys.c: modifed to use the new PR_SetEngineString and PR_GetString functions. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@38 af15c1b1-3010-417e-b628-4374ebc0bcbd
2010-02-17 15:04:50 +00:00
return -1 - i;
}