mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2024-11-10 07:21:58 +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
This commit is contained in:
parent
90d1f32d75
commit
89e17301c9
7 changed files with 187 additions and 81 deletions
|
@ -1260,7 +1260,7 @@ void Host_Name_f (void)
|
||||||
if (Q_strcmp(host_client->name, newName) != 0)
|
if (Q_strcmp(host_client->name, newName) != 0)
|
||||||
Con_Printf ("%s renamed to %s\n", host_client->name, newName);
|
Con_Printf ("%s renamed to %s\n", host_client->name, newName);
|
||||||
Q_strcpy (host_client->name, newName);
|
Q_strcpy (host_client->name, newName);
|
||||||
host_client->edict->v.netname = host_client->name - pr_strings;
|
host_client->edict->v.netname = PR_SetEngineString(host_client->name);
|
||||||
|
|
||||||
// send notification to all clients
|
// send notification to all clients
|
||||||
|
|
||||||
|
@ -1503,11 +1503,11 @@ void Host_Pause_f (void)
|
||||||
|
|
||||||
if (sv.paused)
|
if (sv.paused)
|
||||||
{
|
{
|
||||||
SV_BroadcastPrintf ("%s paused the game\n", pr_strings + sv_player->v.netname);
|
SV_BroadcastPrintf ("%s paused the game\n", PR_GetString(sv_player->v.netname));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SV_BroadcastPrintf ("%s unpaused the game\n",pr_strings + sv_player->v.netname);
|
SV_BroadcastPrintf ("%s unpaused the game\n",PR_GetString(sv_player->v.netname));
|
||||||
}
|
}
|
||||||
|
|
||||||
// send notification to all clients
|
// send notification to all clients
|
||||||
|
@ -1581,7 +1581,7 @@ void Host_Spawn_f (void)
|
||||||
memset (&ent->v, 0, progs->entityfields * 4);
|
memset (&ent->v, 0, progs->entityfields * 4);
|
||||||
ent->v.colormap = NUM_FOR_EDICT(ent);
|
ent->v.colormap = NUM_FOR_EDICT(ent);
|
||||||
ent->v.team = (host_client->colors & 15) + 1;
|
ent->v.team = (host_client->colors & 15) + 1;
|
||||||
ent->v.netname = host_client->name - pr_strings;
|
ent->v.netname = PR_SetEngineString(host_client->name);
|
||||||
|
|
||||||
// copy spawn parms out of the client_t
|
// copy spawn parms out of the client_t
|
||||||
|
|
||||||
|
@ -2006,7 +2006,7 @@ edict_t *FindViewthing (void)
|
||||||
for (i=0 ; i<sv.num_edicts ; i++)
|
for (i=0 ; i<sv.num_edicts ; i++)
|
||||||
{
|
{
|
||||||
e = EDICT_NUM(i);
|
e = EDICT_NUM(i);
|
||||||
if ( !strcmp (pr_strings + e->v.classname, "viewthing") )
|
if ( !strcmp (PR_GetString(e->v.classname), "viewthing") )
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
Con_Printf ("No viewthing on map\n");
|
Con_Printf ("No viewthing on map\n");
|
||||||
|
|
|
@ -72,8 +72,8 @@ void PF_error (void)
|
||||||
edict_t *ed;
|
edict_t *ed;
|
||||||
|
|
||||||
s = PF_VarString(0);
|
s = PF_VarString(0);
|
||||||
Con_Printf ("======SERVER ERROR in %s:\n%s\n"
|
Con_Printf ("======SERVER ERROR in %s:\n%s\n",
|
||||||
,pr_strings + pr_xfunction->s_name,s);
|
PR_GetString(pr_xfunction->s_name), s);
|
||||||
ed = PROG_TO_EDICT(pr_global_struct->self);
|
ed = PROG_TO_EDICT(pr_global_struct->self);
|
||||||
ED_Print (ed);
|
ED_Print (ed);
|
||||||
|
|
||||||
|
@ -96,8 +96,8 @@ void PF_objerror (void)
|
||||||
edict_t *ed;
|
edict_t *ed;
|
||||||
|
|
||||||
s = PF_VarString(0);
|
s = PF_VarString(0);
|
||||||
Con_Printf ("======OBJECT ERROR in %s:\n%s\n"
|
Con_Printf ("======OBJECT ERROR in %s:\n%s\n",
|
||||||
,pr_strings + pr_xfunction->s_name,s);
|
PR_GetString(pr_xfunction->s_name), s);
|
||||||
ed = PROG_TO_EDICT(pr_global_struct->self);
|
ed = PROG_TO_EDICT(pr_global_struct->self);
|
||||||
ED_Print (ed);
|
ED_Print (ed);
|
||||||
ED_Free (ed);
|
ED_Free (ed);
|
||||||
|
@ -261,7 +261,7 @@ void PF_setmodel (void)
|
||||||
if (!*check)
|
if (!*check)
|
||||||
PR_RunError ("no precache: %s\n", m);
|
PR_RunError ("no precache: %s\n", m);
|
||||||
|
|
||||||
e->v.model = m - pr_strings;
|
e->v.model = PR_SetEngineString(*check);
|
||||||
e->v.modelindex = i; //SV_ModelIndex (m);
|
e->v.modelindex = i; //SV_ModelIndex (m);
|
||||||
|
|
||||||
mod = sv.models[ (int)e->v.modelindex]; // Mod_ForName (m, true);
|
mod = sv.models[ (int)e->v.modelindex]; // Mod_ForName (m, true);
|
||||||
|
@ -940,7 +940,7 @@ void PF_ftos (void)
|
||||||
sprintf (s, "%d",(int)v);
|
sprintf (s, "%d",(int)v);
|
||||||
else
|
else
|
||||||
sprintf (s, "%5.1f",v);
|
sprintf (s, "%5.1f",v);
|
||||||
G_INT(OFS_RETURN) = s - pr_strings;
|
G_INT(OFS_RETURN) = PR_SetEngineString(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PF_fabs (void)
|
void PF_fabs (void)
|
||||||
|
@ -956,7 +956,7 @@ void PF_vtos (void)
|
||||||
|
|
||||||
s = PR_GetTempString();
|
s = PR_GetTempString();
|
||||||
sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
|
sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
|
||||||
G_INT(OFS_RETURN) = s - pr_strings;
|
G_INT(OFS_RETURN) = PR_SetEngineString(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PF_Spawn (void)
|
void PF_Spawn (void)
|
||||||
|
@ -1509,7 +1509,7 @@ void PF_makestatic (void)
|
||||||
//johnfitz -- PROTOCOL_FITZQUAKE
|
//johnfitz -- PROTOCOL_FITZQUAKE
|
||||||
if (sv.protocol == PROTOCOL_NETQUAKE)
|
if (sv.protocol == PROTOCOL_NETQUAKE)
|
||||||
{
|
{
|
||||||
if (SV_ModelIndex(pr_strings + ent->v.model) & 0xFF00 || (int)(ent->v.frame) & 0xFF00)
|
if (SV_ModelIndex(PR_GetString(ent->v.model)) & 0xFF00 || (int)(ent->v.frame) & 0xFF00)
|
||||||
{
|
{
|
||||||
ED_Free (ent);
|
ED_Free (ent);
|
||||||
return; //can't display the correct model & frame, so don't show it at all
|
return; //can't display the correct model & frame, so don't show it at all
|
||||||
|
@ -1517,7 +1517,7 @@ void PF_makestatic (void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (SV_ModelIndex(pr_strings + ent->v.model) & 0xFF00)
|
if (SV_ModelIndex(PR_GetString(ent->v.model)) & 0xFF00)
|
||||||
bits |= B_LARGEMODEL;
|
bits |= B_LARGEMODEL;
|
||||||
if ((int)(ent->v.frame) & 0xFF00)
|
if ((int)(ent->v.frame) & 0xFF00)
|
||||||
bits |= B_LARGEFRAME;
|
bits |= B_LARGEFRAME;
|
||||||
|
@ -1534,9 +1534,9 @@ void PF_makestatic (void)
|
||||||
MSG_WriteByte (&sv.signon, svc_spawnstatic);
|
MSG_WriteByte (&sv.signon, svc_spawnstatic);
|
||||||
|
|
||||||
if (bits & B_LARGEMODEL)
|
if (bits & B_LARGEMODEL)
|
||||||
MSG_WriteShort (&sv.signon, SV_ModelIndex(pr_strings + ent->v.model));
|
MSG_WriteShort (&sv.signon, SV_ModelIndex(PR_GetString(ent->v.model)));
|
||||||
else
|
else
|
||||||
MSG_WriteByte (&sv.signon, SV_ModelIndex(pr_strings + ent->v.model));
|
MSG_WriteByte (&sv.signon, SV_ModelIndex(PR_GetString(ent->v.model)));
|
||||||
|
|
||||||
if (bits & B_LARGEFRAME)
|
if (bits & B_LARGEFRAME)
|
||||||
MSG_WriteShort (&sv.signon, ent->v.frame);
|
MSG_WriteShort (&sv.signon, ent->v.frame);
|
||||||
|
|
188
Quake/pr_edict.c
188
Quake/pr_edict.c
|
@ -26,13 +26,19 @@ qboolean pr_alpha_supported; //johnfitz
|
||||||
|
|
||||||
dprograms_t *progs;
|
dprograms_t *progs;
|
||||||
dfunction_t *pr_functions;
|
dfunction_t *pr_functions;
|
||||||
char *pr_strings;
|
|
||||||
ddef_t *pr_fielddefs;
|
|
||||||
ddef_t *pr_globaldefs;
|
|
||||||
dstatement_t *pr_statements;
|
dstatement_t *pr_statements;
|
||||||
globalvars_t *pr_global_struct;
|
globalvars_t *pr_global_struct;
|
||||||
float *pr_globals; // same as pr_global_struct
|
float *pr_globals; // same as pr_global_struct
|
||||||
int pr_edict_size; // in bytes
|
int pr_edict_size; // in bytes
|
||||||
|
|
||||||
|
char *pr_strings; // no one should access this. not static
|
||||||
|
// only for two stupid sv_main.c uses.
|
||||||
|
static int pr_stringssize;
|
||||||
|
static char **pr_knownstrings;
|
||||||
|
static int pr_maxknownstrings;
|
||||||
|
static int pr_numknownstrings;
|
||||||
|
static ddef_t *pr_fielddefs;
|
||||||
|
static ddef_t *pr_globaldefs;
|
||||||
|
|
||||||
unsigned short pr_crc;
|
unsigned short pr_crc;
|
||||||
|
|
||||||
|
@ -204,7 +210,7 @@ ddef_t *ED_FindField (char *name)
|
||||||
for (i=0 ; i<progs->numfielddefs ; i++)
|
for (i=0 ; i<progs->numfielddefs ; i++)
|
||||||
{
|
{
|
||||||
def = &pr_fielddefs[i];
|
def = &pr_fielddefs[i];
|
||||||
if (!strcmp(pr_strings + def->s_name,name) )
|
if (!strcmp(PR_GetString(def->s_name),name))
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -224,7 +230,7 @@ ddef_t *ED_FindGlobal (char *name)
|
||||||
for (i=0 ; i<progs->numglobaldefs ; i++)
|
for (i=0 ; i<progs->numglobaldefs ; i++)
|
||||||
{
|
{
|
||||||
def = &pr_globaldefs[i];
|
def = &pr_globaldefs[i];
|
||||||
if (!strcmp(pr_strings + def->s_name,name) )
|
if (!strcmp(PR_GetString(def->s_name),name))
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -244,7 +250,7 @@ dfunction_t *ED_FindFunction (char *name)
|
||||||
for (i=0 ; i<progs->numfunctions ; i++)
|
for (i=0 ; i<progs->numfunctions ; i++)
|
||||||
{
|
{
|
||||||
func = &pr_functions[i];
|
func = &pr_functions[i];
|
||||||
if (!strcmp(pr_strings + func->s_name,name) )
|
if (!strcmp(PR_GetString(func->s_name),name))
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -305,18 +311,18 @@ char *PR_ValueString (etype_t type, eval_t *val)
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case ev_string:
|
case ev_string:
|
||||||
sprintf (line, "%s", pr_strings + val->string);
|
sprintf (line, "%s", PR_GetString(val->string));
|
||||||
break;
|
break;
|
||||||
case ev_entity:
|
case ev_entity:
|
||||||
sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) );
|
sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) );
|
||||||
break;
|
break;
|
||||||
case ev_function:
|
case ev_function:
|
||||||
f = pr_functions + val->function;
|
f = pr_functions + val->function;
|
||||||
sprintf (line, "%s()", pr_strings + f->s_name);
|
sprintf (line, "%s()", PR_GetString(f->s_name));
|
||||||
break;
|
break;
|
||||||
case ev_field:
|
case ev_field:
|
||||||
def = ED_FieldAtOfs ( val->_int );
|
def = ED_FieldAtOfs ( val->_int );
|
||||||
sprintf (line, ".%s", pr_strings + def->s_name);
|
sprintf (line, ".%s", PR_GetString(def->s_name));
|
||||||
break;
|
break;
|
||||||
case ev_void:
|
case ev_void:
|
||||||
sprintf (line, "void");
|
sprintf (line, "void");
|
||||||
|
@ -357,18 +363,18 @@ char *PR_UglyValueString (etype_t type, eval_t *val)
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case ev_string:
|
case ev_string:
|
||||||
sprintf (line, "%s", pr_strings + val->string);
|
sprintf (line, "%s", PR_GetString(val->string));
|
||||||
break;
|
break;
|
||||||
case ev_entity:
|
case ev_entity:
|
||||||
sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
|
sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
|
||||||
break;
|
break;
|
||||||
case ev_function:
|
case ev_function:
|
||||||
f = pr_functions + val->function;
|
f = pr_functions + val->function;
|
||||||
sprintf (line, "%s", pr_strings + f->s_name);
|
sprintf (line, "%s", PR_GetString(f->s_name));
|
||||||
break;
|
break;
|
||||||
case ev_field:
|
case ev_field:
|
||||||
def = ED_FieldAtOfs ( val->_int );
|
def = ED_FieldAtOfs ( val->_int );
|
||||||
sprintf (line, "%s", pr_strings + def->s_name);
|
sprintf (line, "%s", PR_GetString(def->s_name));
|
||||||
break;
|
break;
|
||||||
case ev_void:
|
case ev_void:
|
||||||
sprintf (line, "void");
|
sprintf (line, "void");
|
||||||
|
@ -409,8 +415,8 @@ char *PR_GlobalString (int ofs)
|
||||||
sprintf (line,"%i(???)", ofs);
|
sprintf (line,"%i(???)", ofs);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s = PR_ValueString (def->type, val);
|
s = PR_ValueString (def->type, (eval_t *)val);
|
||||||
sprintf (line,"%i(%s)%s", ofs, pr_strings + def->s_name, s);
|
sprintf (line,"%i(%s)%s", ofs, PR_GetString(def->s_name), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = strlen(line);
|
i = strlen(line);
|
||||||
|
@ -431,7 +437,7 @@ char *PR_GlobalStringNoContents (int ofs)
|
||||||
if (!def)
|
if (!def)
|
||||||
sprintf (line,"%i(???)", ofs);
|
sprintf (line,"%i(???)", ofs);
|
||||||
else
|
else
|
||||||
sprintf (line,"%i(%s)", ofs, pr_strings + def->s_name);
|
sprintf (line,"%i(%s)", ofs, PR_GetString(def->s_name));
|
||||||
|
|
||||||
i = strlen(line);
|
i = strlen(line);
|
||||||
for ( ; i<20 ; i++)
|
for ( ; i<20 ; i++)
|
||||||
|
@ -451,10 +457,9 @@ For debugging
|
||||||
*/
|
*/
|
||||||
void ED_Print (edict_t *ed)
|
void ED_Print (edict_t *ed)
|
||||||
{
|
{
|
||||||
int l;
|
|
||||||
ddef_t *d;
|
ddef_t *d;
|
||||||
int *v;
|
int *v;
|
||||||
int i, j;
|
int i, j, l;
|
||||||
char *name;
|
char *name;
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
|
@ -468,8 +473,9 @@ void ED_Print (edict_t *ed)
|
||||||
for (i=1 ; i<progs->numfielddefs ; i++)
|
for (i=1 ; i<progs->numfielddefs ; i++)
|
||||||
{
|
{
|
||||||
d = &pr_fielddefs[i];
|
d = &pr_fielddefs[i];
|
||||||
name = pr_strings + d->s_name;
|
name = PR_GetString(d->s_name);
|
||||||
if (name[strlen(name)-2] == '_')
|
l = strlen(name);
|
||||||
|
if (l > 1 && name[l - 2] == '_')
|
||||||
continue; // skip _x, _y, _z vars
|
continue; // skip _x, _y, _z vars
|
||||||
|
|
||||||
v = (int *)((char *)&ed->v + d->ofs*4);
|
v = (int *)((char *)&ed->v + d->ofs*4);
|
||||||
|
@ -484,7 +490,6 @@ void ED_Print (edict_t *ed)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Con_SafePrintf ("%s",name); //johnfitz -- was Con_Printf
|
Con_SafePrintf ("%s",name); //johnfitz -- was Con_Printf
|
||||||
l = strlen (name);
|
|
||||||
while (l++ < 15)
|
while (l++ < 15)
|
||||||
Con_SafePrintf (" "); //johnfitz -- was Con_Printf
|
Con_SafePrintf (" "); //johnfitz -- was Con_Printf
|
||||||
|
|
||||||
|
@ -518,8 +523,9 @@ void ED_Write (FILE *f, edict_t *ed)
|
||||||
for (i=1 ; i<progs->numfielddefs ; i++)
|
for (i=1 ; i<progs->numfielddefs ; i++)
|
||||||
{
|
{
|
||||||
d = &pr_fielddefs[i];
|
d = &pr_fielddefs[i];
|
||||||
name = pr_strings + d->s_name;
|
name = PR_GetString(d->s_name);
|
||||||
if (name[strlen(name)-2] == '_')
|
j = strlen(name);
|
||||||
|
if (j > 1 && name[j - 2] == '_')
|
||||||
continue; // skip _x, _y, _z vars
|
continue; // skip _x, _y, _z vars
|
||||||
|
|
||||||
v = (int *)((char *)&ed->v + d->ofs*4);
|
v = (int *)((char *)&ed->v + d->ofs*4);
|
||||||
|
@ -656,7 +662,7 @@ void ED_WriteGlobals (FILE *f)
|
||||||
&& type != ev_entity)
|
&& type != ev_entity)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
name = pr_strings + def->s_name;
|
name = PR_GetString(def->s_name);
|
||||||
fprintf (f,"\"%s\" ", name);
|
fprintf (f,"\"%s\" ", name);
|
||||||
fprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
|
fprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
|
||||||
}
|
}
|
||||||
|
@ -712,14 +718,14 @@ void ED_ParseGlobals (char *data)
|
||||||
ED_NewString
|
ED_NewString
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
char *ED_NewString (char *string)
|
static string_t ED_NewString (const char *string)
|
||||||
{
|
{
|
||||||
char *new, *new_p;
|
char *new_p;
|
||||||
int i,l;
|
int i, l;
|
||||||
|
string_t num;
|
||||||
|
|
||||||
l = strlen(string) + 1;
|
l = strlen(string) + 1;
|
||||||
new = Hunk_Alloc (l);
|
num = PR_AllocString (l, &new_p);
|
||||||
new_p = new;
|
|
||||||
|
|
||||||
for (i=0 ; i< l ; i++)
|
for (i=0 ; i< l ; i++)
|
||||||
{
|
{
|
||||||
|
@ -735,7 +741,7 @@ char *ED_NewString (char *string)
|
||||||
*new_p++ = string[i];
|
*new_p++ = string[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return new;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -761,7 +767,7 @@ qboolean ED_ParseEpair (void *base, ddef_t *key, char *s)
|
||||||
switch (key->type & ~DEF_SAVEGLOBAL)
|
switch (key->type & ~DEF_SAVEGLOBAL)
|
||||||
{
|
{
|
||||||
case ev_string:
|
case ev_string:
|
||||||
*(string_t *)d = ED_NewString (s) - pr_strings;
|
*(string_t *)d = ED_NewString (s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_float:
|
case ev_float:
|
||||||
|
@ -935,12 +941,10 @@ to call ED_CallSpawnFunctions () to let the objects initialize themselves.
|
||||||
*/
|
*/
|
||||||
void ED_LoadFromFile (char *data)
|
void ED_LoadFromFile (char *data)
|
||||||
{
|
{
|
||||||
edict_t *ent;
|
edict_t *ent = NULL;
|
||||||
int inhibit;
|
int inhibit = 0;
|
||||||
dfunction_t *func;
|
dfunction_t *func;
|
||||||
|
|
||||||
ent = NULL;
|
|
||||||
inhibit = 0;
|
|
||||||
pr_global_struct->time = sv.time;
|
pr_global_struct->time = sv.time;
|
||||||
|
|
||||||
// parse ents
|
// parse ents
|
||||||
|
@ -990,7 +994,7 @@ void ED_LoadFromFile (char *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// look for the spawn function
|
// look for the spawn function
|
||||||
func = ED_FindFunction ( pr_strings + ent->v.classname );
|
func = ED_FindFunction (PR_GetString(ent->v.classname));
|
||||||
|
|
||||||
if (!func)
|
if (!func)
|
||||||
{
|
{
|
||||||
|
@ -1042,6 +1046,15 @@ void PR_LoadProgs (void)
|
||||||
|
|
||||||
pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions);
|
pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions);
|
||||||
pr_strings = (char *)progs + progs->ofs_strings;
|
pr_strings = (char *)progs + progs->ofs_strings;
|
||||||
|
if (progs->ofs_strings + progs->numstrings >= com_filesize)
|
||||||
|
Host_Error ("progs.dat strings go past end of file\n");
|
||||||
|
pr_numknownstrings = 0;
|
||||||
|
pr_maxknownstrings = 0;
|
||||||
|
pr_stringssize = progs->numstrings;
|
||||||
|
if (pr_knownstrings)
|
||||||
|
Z_Free (pr_knownstrings);
|
||||||
|
pr_knownstrings = NULL;
|
||||||
|
PR_SetEngineString(""); // initialize the strings
|
||||||
pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs);
|
pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs);
|
||||||
pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs);
|
pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs);
|
||||||
pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements);
|
pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements);
|
||||||
|
@ -1049,8 +1062,6 @@ void PR_LoadProgs (void)
|
||||||
pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals);
|
pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals);
|
||||||
pr_globals = (float *)pr_global_struct;
|
pr_globals = (float *)pr_global_struct;
|
||||||
|
|
||||||
pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t);
|
|
||||||
|
|
||||||
// byte swap the lumps
|
// byte swap the lumps
|
||||||
for (i=0 ; i<progs->numstatements ; i++)
|
for (i=0 ; i<progs->numstatements ; i++)
|
||||||
{
|
{
|
||||||
|
@ -1095,6 +1106,13 @@ void PR_LoadProgs (void)
|
||||||
|
|
||||||
for (i=0 ; i<progs->numglobals ; i++)
|
for (i=0 ; i<progs->numglobals ; i++)
|
||||||
((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
|
((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
|
||||||
|
|
||||||
|
pr_edict_size = progs->entityfields * 4 + sizeof(edict_t) - sizeof(entvars_t);
|
||||||
|
// round off to next highest whole word address (esp for Alpha)
|
||||||
|
// this ensures that pointers in the engine data area are always
|
||||||
|
// properly aligned
|
||||||
|
pr_edict_size += sizeof(void *) - 1;
|
||||||
|
pr_edict_size &= ~(sizeof(void *) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1142,3 +1160,95 @@ int NUM_FOR_EDICT(edict_t *e)
|
||||||
Sys_Error ("NUM_FOR_EDICT: bad pointer");
|
Sys_Error ("NUM_FOR_EDICT: bad pointer");
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
#define PR_STRING_ALLOCSLOTS 256
|
||||||
|
|
||||||
|
static void PR_AllocStringSlots (void)
|
||||||
|
{
|
||||||
|
pr_maxknownstrings += PR_STRING_ALLOCSLOTS;
|
||||||
|
Con_DPrintf("PR_AllocStringSlots: realloc'ing for slots\n", pr_maxknownstrings);
|
||||||
|
pr_knownstrings = (char **) Z_Realloc (pr_knownstrings, pr_maxknownstrings * sizeof(char *));
|
||||||
|
}
|
||||||
|
|
||||||
|
char *PR_GetString (int num)
|
||||||
|
{
|
||||||
|
if (num >= 0 && num < pr_stringssize)
|
||||||
|
return pr_strings + num;
|
||||||
|
else if (num < 0 && num >= -pr_numknownstrings)
|
||||||
|
{
|
||||||
|
if (!pr_knownstrings[-1 - num])
|
||||||
|
{
|
||||||
|
Host_Error ("PR_GetString: attempt to get a non-existant string %d\n", num);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return pr_knownstrings[-1 - num];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Host_Error("PR_GetString: invalid string offset %d\n", num);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PR_SetEngineString (char *s)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return 0;
|
||||||
|
#if 0 /* can't: sv.model_precache & sv.sound_precache points to pr_strings */
|
||||||
|
if (s >= pr_strings && s <= pr_strings + pr_stringssize)
|
||||||
|
Host_Error("PR_SetEngineString: \"%s\" in pr_strings area\n", s);
|
||||||
|
#else
|
||||||
|
if (s >= pr_strings && s <= pr_strings + pr_stringssize - 2)
|
||||||
|
return (int)(s - pr_strings);
|
||||||
|
#endif
|
||||||
|
for (i = 0; i < pr_numknownstrings; i++)
|
||||||
|
{
|
||||||
|
if (pr_knownstrings[i] == s)
|
||||||
|
return -1 - i;
|
||||||
|
}
|
||||||
|
// new unknown engine string
|
||||||
|
//Con_DPrintf ("PR_SetEngineString: new engine string %p\n", s);
|
||||||
|
#if 0
|
||||||
|
for (i = 0; i < pr_numknownstrings; i++)
|
||||||
|
{
|
||||||
|
if (!pr_knownstrings[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// if (i >= pr_numknownstrings)
|
||||||
|
// {
|
||||||
|
if (i >= pr_maxknownstrings)
|
||||||
|
PR_AllocStringSlots();
|
||||||
|
pr_numknownstrings++;
|
||||||
|
// }
|
||||||
|
pr_knownstrings[i] = s;
|
||||||
|
return -1 - i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PR_AllocString (int size, char **ptr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!size)
|
||||||
|
return 0;
|
||||||
|
for (i = 0; i < pr_numknownstrings; i++)
|
||||||
|
{
|
||||||
|
if (!pr_knownstrings[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// if (i >= pr_numknownstrings)
|
||||||
|
// {
|
||||||
|
if (i >= pr_maxknownstrings)
|
||||||
|
PR_AllocStringSlots();
|
||||||
|
pr_numknownstrings++;
|
||||||
|
// }
|
||||||
|
pr_knownstrings[i] = (char *)Hunk_AllocName(size, "string");
|
||||||
|
if (ptr)
|
||||||
|
*ptr = pr_knownstrings[i];
|
||||||
|
return -1 - i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,7 @@ void PR_StackTrace (void)
|
||||||
Con_Printf ("<NO FUNCTION>\n");
|
Con_Printf ("<NO FUNCTION>\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Con_Printf ("%12s : %s\n", pr_strings + f->s_file, pr_strings + f->s_name);
|
Con_Printf ("%12s : %s\n", PR_GetString(f->s_file), PR_GetString(f->s_name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ void PR_Profile_f (void)
|
||||||
if (best)
|
if (best)
|
||||||
{
|
{
|
||||||
if (num < 10)
|
if (num < 10)
|
||||||
Con_Printf ("%7i %s\n", best->profile, pr_strings+best->s_name);
|
Con_Printf ("%7i %s\n", best->profile, PR_GetString(best->s_name));
|
||||||
num++;
|
num++;
|
||||||
best->profile = 0;
|
best->profile = 0;
|
||||||
}
|
}
|
||||||
|
@ -484,7 +484,7 @@ while (1)
|
||||||
c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2];
|
c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2];
|
||||||
break;
|
break;
|
||||||
case OP_NOT_S:
|
case OP_NOT_S:
|
||||||
c->_float = !a->string || !pr_strings[a->string];
|
c->_float = !a->string || !*PR_GetString(a->string);
|
||||||
break;
|
break;
|
||||||
case OP_NOT_FNC:
|
case OP_NOT_FNC:
|
||||||
c->_float = !a->function;
|
c->_float = !a->function;
|
||||||
|
@ -502,7 +502,7 @@ while (1)
|
||||||
(a->vector[2] == b->vector[2]);
|
(a->vector[2] == b->vector[2]);
|
||||||
break;
|
break;
|
||||||
case OP_EQ_S:
|
case OP_EQ_S:
|
||||||
c->_float = !strcmp(pr_strings+a->string,pr_strings+b->string);
|
c->_float = !strcmp(PR_GetString(a->string),PR_GetString(b->string));
|
||||||
break;
|
break;
|
||||||
case OP_EQ_E:
|
case OP_EQ_E:
|
||||||
c->_float = a->_int == b->_int;
|
c->_float = a->_int == b->_int;
|
||||||
|
@ -521,7 +521,7 @@ while (1)
|
||||||
(a->vector[2] != b->vector[2]);
|
(a->vector[2] != b->vector[2]);
|
||||||
break;
|
break;
|
||||||
case OP_NE_S:
|
case OP_NE_S:
|
||||||
c->_float = strcmp(pr_strings+a->string,pr_strings+b->string);
|
c->_float = strcmp(PR_GetString(a->string),PR_GetString(b->string));
|
||||||
break;
|
break;
|
||||||
case OP_NE_E:
|
case OP_NE_E:
|
||||||
c->_float = a->_int != b->_int;
|
c->_float = a->_int != b->_int;
|
||||||
|
|
|
@ -53,13 +53,11 @@ typedef struct edict_s
|
||||||
extern dprograms_t *progs;
|
extern dprograms_t *progs;
|
||||||
extern dfunction_t *pr_functions;
|
extern dfunction_t *pr_functions;
|
||||||
extern char *pr_strings;
|
extern char *pr_strings;
|
||||||
extern ddef_t *pr_globaldefs;
|
|
||||||
extern ddef_t *pr_fielddefs;
|
|
||||||
extern dstatement_t *pr_statements;
|
extern dstatement_t *pr_statements;
|
||||||
extern globalvars_t *pr_global_struct;
|
extern globalvars_t *pr_global_struct;
|
||||||
extern float *pr_globals; // same as pr_global_struct
|
extern float *pr_globals; // same as pr_global_struct
|
||||||
|
|
||||||
extern int pr_edict_size; // in bytes
|
extern int pr_edict_size; // in bytes
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
@ -70,12 +68,13 @@ void PR_LoadProgs (void);
|
||||||
|
|
||||||
void PR_Profile_f (void);
|
void PR_Profile_f (void);
|
||||||
|
|
||||||
|
char *PR_GetString (int num);
|
||||||
|
int PR_SetEngineString (char *s);
|
||||||
|
int PR_AllocString (int bufferlength, char **ptr);
|
||||||
|
|
||||||
edict_t *ED_Alloc (void);
|
edict_t *ED_Alloc (void);
|
||||||
void ED_Free (edict_t *ed);
|
void ED_Free (edict_t *ed);
|
||||||
|
|
||||||
char *ED_NewString (char *string);
|
|
||||||
// returns a copy of the string allocated from the server's string heap
|
|
||||||
|
|
||||||
void ED_Print (edict_t *ed);
|
void ED_Print (edict_t *ed);
|
||||||
void ED_Write (FILE *f, edict_t *ed);
|
void ED_Write (FILE *f, edict_t *ed);
|
||||||
char *ED_ParseEdict (char *data, edict_t *ent);
|
char *ED_ParseEdict (char *data, edict_t *ent);
|
||||||
|
@ -103,13 +102,13 @@ int NUM_FOR_EDICT(edict_t *e);
|
||||||
#define G_EDICT(o) ((edict_t *)((byte *)sv.edicts+ *(int *)&pr_globals[o]))
|
#define G_EDICT(o) ((edict_t *)((byte *)sv.edicts+ *(int *)&pr_globals[o]))
|
||||||
#define G_EDICTNUM(o) NUM_FOR_EDICT(G_EDICT(o))
|
#define G_EDICTNUM(o) NUM_FOR_EDICT(G_EDICT(o))
|
||||||
#define G_VECTOR(o) (&pr_globals[o])
|
#define G_VECTOR(o) (&pr_globals[o])
|
||||||
#define G_STRING(o) (pr_strings + *(string_t *)&pr_globals[o])
|
#define G_STRING(o) (PR_GetString(*(string_t *)&pr_globals[o]))
|
||||||
#define G_FUNCTION(o) (*(func_t *)&pr_globals[o])
|
#define G_FUNCTION(o) (*(func_t *)&pr_globals[o])
|
||||||
|
|
||||||
#define E_FLOAT(e,o) (((float*)&e->v)[o])
|
#define E_FLOAT(e,o) (((float*)&e->v)[o])
|
||||||
#define E_INT(e,o) (*(int *)&((float*)&e->v)[o])
|
#define E_INT(e,o) (*(int *)&((float*)&e->v)[o])
|
||||||
#define E_VECTOR(e,o) (&((float*)&e->v)[o])
|
#define E_VECTOR(e,o) (&((float*)&e->v)[o])
|
||||||
#define E_STRING(e,o) (pr_strings + *(string_t *)&((float*)&e->v)[o])
|
#define E_STRING(e,o) (PR_GetString(*(string_t *)&((float*)&e->v)[o]))
|
||||||
|
|
||||||
extern int type_size[8];
|
extern int type_size[8];
|
||||||
|
|
||||||
|
|
|
@ -272,9 +272,7 @@ void SV_SendServerinfo (client_t *client)
|
||||||
else
|
else
|
||||||
MSG_WriteByte (&client->message, GAME_COOP);
|
MSG_WriteByte (&client->message, GAME_COOP);
|
||||||
|
|
||||||
sprintf (message, pr_strings+sv.edicts->v.message);
|
MSG_WriteString (&client->message, PR_GetString(sv.edicts->v.message));
|
||||||
|
|
||||||
MSG_WriteString (&client->message,message);
|
|
||||||
|
|
||||||
//johnfitz -- only send the first 256 model and sound precaches if protocol is 15
|
//johnfitz -- only send the first 256 model and sound precaches if protocol is 15
|
||||||
for (i=0,s = sv.model_precache+1 ; *s; s++,i++)
|
for (i=0,s = sv.model_precache+1 ; *s; s++,i++)
|
||||||
|
@ -534,7 +532,7 @@ void SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg)
|
||||||
if (ent != clent) // clent is ALLWAYS sent
|
if (ent != clent) // clent is ALLWAYS sent
|
||||||
{
|
{
|
||||||
// ignore ents without visible models
|
// ignore ents without visible models
|
||||||
if (!ent->v.modelindex || !pr_strings[ent->v.model])
|
if (!ent->v.modelindex || !PR_GetString(ent->v.model)[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//johnfitz -- don't send model>255 entities if protocol is 15
|
//johnfitz -- don't send model>255 entities if protocol is 15
|
||||||
|
@ -806,7 +804,7 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
|
||||||
//johnfitz -- PROTOCOL_FITZQUAKE
|
//johnfitz -- PROTOCOL_FITZQUAKE
|
||||||
if (sv.protocol != PROTOCOL_NETQUAKE)
|
if (sv.protocol != PROTOCOL_NETQUAKE)
|
||||||
{
|
{
|
||||||
if (bits & SU_WEAPON && SV_ModelIndex(pr_strings+ent->v.weaponmodel) & 0xFF00) bits |= SU_WEAPON2;
|
if (bits & SU_WEAPON && SV_ModelIndex(PR_GetString(ent->v.weaponmodel)) & 0xFF00) bits |= SU_WEAPON2;
|
||||||
if ((int)ent->v.armorvalue & 0xFF00) bits |= SU_ARMOR2;
|
if ((int)ent->v.armorvalue & 0xFF00) bits |= SU_ARMOR2;
|
||||||
if ((int)ent->v.currentammo & 0xFF00) bits |= SU_AMMO2;
|
if ((int)ent->v.currentammo & 0xFF00) bits |= SU_AMMO2;
|
||||||
if ((int)ent->v.ammo_shells & 0xFF00) bits |= SU_SHELLS2;
|
if ((int)ent->v.ammo_shells & 0xFF00) bits |= SU_SHELLS2;
|
||||||
|
@ -852,7 +850,7 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
|
||||||
if (bits & SU_ARMOR)
|
if (bits & SU_ARMOR)
|
||||||
MSG_WriteByte (msg, ent->v.armorvalue);
|
MSG_WriteByte (msg, ent->v.armorvalue);
|
||||||
if (bits & SU_WEAPON)
|
if (bits & SU_WEAPON)
|
||||||
MSG_WriteByte (msg, SV_ModelIndex(pr_strings+ent->v.weaponmodel));
|
MSG_WriteByte (msg, SV_ModelIndex(PR_GetString(ent->v.weaponmodel)));
|
||||||
|
|
||||||
MSG_WriteShort (msg, ent->v.health);
|
MSG_WriteShort (msg, ent->v.health);
|
||||||
MSG_WriteByte (msg, ent->v.currentammo);
|
MSG_WriteByte (msg, ent->v.currentammo);
|
||||||
|
@ -879,7 +877,7 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
|
||||||
|
|
||||||
//johnfitz -- PROTOCOL_FITZQUAKE
|
//johnfitz -- PROTOCOL_FITZQUAKE
|
||||||
if (bits & SU_WEAPON2)
|
if (bits & SU_WEAPON2)
|
||||||
MSG_WriteByte (msg, SV_ModelIndex(pr_strings+ent->v.weaponmodel) >> 8);
|
MSG_WriteByte (msg, SV_ModelIndex(PR_GetString(ent->v.weaponmodel)) >> 8);
|
||||||
if (bits & SU_ARMOR2)
|
if (bits & SU_ARMOR2)
|
||||||
MSG_WriteByte (msg, (int)ent->v.armorvalue >> 8);
|
MSG_WriteByte (msg, (int)ent->v.armorvalue >> 8);
|
||||||
if (bits & SU_AMMO2)
|
if (bits & SU_AMMO2)
|
||||||
|
@ -1145,7 +1143,7 @@ void SV_CreateBaseline (void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
svent->baseline.colormap = 0;
|
svent->baseline.colormap = 0;
|
||||||
svent->baseline.modelindex = SV_ModelIndex(pr_strings + svent->v.model);
|
svent->baseline.modelindex = SV_ModelIndex(PR_GetString(svent->v.model));
|
||||||
svent->baseline.alpha = svent->alpha; //johnfitz -- alpha support
|
svent->baseline.alpha = svent->alpha; //johnfitz -- alpha support
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1368,7 +1366,6 @@ void SV_SpawnServer (char *server)
|
||||||
SV_ClearWorld ();
|
SV_ClearWorld ();
|
||||||
|
|
||||||
sv.sound_precache[0] = pr_strings;
|
sv.sound_precache[0] = pr_strings;
|
||||||
|
|
||||||
sv.model_precache[0] = pr_strings;
|
sv.model_precache[0] = pr_strings;
|
||||||
sv.model_precache[1] = sv.modelname;
|
sv.model_precache[1] = sv.modelname;
|
||||||
for (i=1 ; i<sv.worldmodel->numsubmodels ; i++)
|
for (i=1 ; i<sv.worldmodel->numsubmodels ; i++)
|
||||||
|
@ -1383,7 +1380,7 @@ void SV_SpawnServer (char *server)
|
||||||
ent = EDICT_NUM(0);
|
ent = EDICT_NUM(0);
|
||||||
memset (&ent->v, 0, progs->entityfields * 4);
|
memset (&ent->v, 0, progs->entityfields * 4);
|
||||||
ent->free = false;
|
ent->free = false;
|
||||||
ent->v.model = sv.worldmodel->name - pr_strings;
|
ent->v.model = PR_SetEngineString(sv.worldmodel->name);
|
||||||
ent->v.modelindex = 1; // world model
|
ent->v.modelindex = 1; // world model
|
||||||
ent->v.solid = SOLID_BSP;
|
ent->v.solid = SOLID_BSP;
|
||||||
ent->v.movetype = MOVETYPE_PUSH;
|
ent->v.movetype = MOVETYPE_PUSH;
|
||||||
|
@ -1393,7 +1390,7 @@ void SV_SpawnServer (char *server)
|
||||||
else
|
else
|
||||||
pr_global_struct->deathmatch = deathmatch.value;
|
pr_global_struct->deathmatch = deathmatch.value;
|
||||||
|
|
||||||
pr_global_struct->mapname = sv.name - pr_strings;
|
pr_global_struct->mapname = PR_SetEngineString(sv.name);
|
||||||
|
|
||||||
// serverflags are for cross level information (sigils)
|
// serverflags are for cross level information (sigils)
|
||||||
pr_global_struct->serverflags = svs.serverflags;
|
pr_global_struct->serverflags = svs.serverflags;
|
||||||
|
|
|
@ -92,12 +92,12 @@ void SV_CheckVelocity (edict_t *ent)
|
||||||
{
|
{
|
||||||
if (IS_NAN(ent->v.velocity[i]))
|
if (IS_NAN(ent->v.velocity[i]))
|
||||||
{
|
{
|
||||||
Con_Printf ("Got a NaN velocity on %s\n", pr_strings + ent->v.classname);
|
Con_Printf ("Got a NaN velocity on %s\n", PR_GetString(ent->v.classname));
|
||||||
ent->v.velocity[i] = 0;
|
ent->v.velocity[i] = 0;
|
||||||
}
|
}
|
||||||
if (IS_NAN(ent->v.origin[i]))
|
if (IS_NAN(ent->v.origin[i]))
|
||||||
{
|
{
|
||||||
Con_Printf ("Got a NaN origin on %s\n", pr_strings + ent->v.classname);
|
Con_Printf ("Got a NaN origin on %s\n", PR_GetString(ent->v.classname));
|
||||||
ent->v.origin[i] = 0;
|
ent->v.origin[i] = 0;
|
||||||
}
|
}
|
||||||
if (ent->v.velocity[i] > sv_maxvelocity.value)
|
if (ent->v.velocity[i] > sv_maxvelocity.value)
|
||||||
|
|
Loading…
Reference in a new issue