Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-// AK new vm
+// AK new vm
#include "quakedef.h"
+#include "progsvm.h"
prvm_prog_t *prog;
{
int i;
+ // reserve space for the null entity aka world
// check bound of max_edicts
- prog->max_edicts = min(prog->max_edicts,prog->limit_edicts);
+ prog->max_edicts = bound(1, prog->max_edicts, prog->limit_edicts);
+ prog->num_edicts = bound(1, prog->num_edicts, prog->max_edicts);
// edictprivate_size has to be min as big prvm_edict_private_t
- prog->edictprivate_size = max(prog->edictprivate_size,(int)sizeof(prvm_edict_private_t));
+ prog->edictprivate_size = max(prog->edictprivate_size,(int)sizeof(prvm_edict_private_t));
// alloc edicts
- prog->edicts = Mem_Alloc(prog->edicts_mempool,prog->limit_edicts * sizeof(prvm_edict_t));
-
+ prog->edicts = Mem_Alloc(prog->progs_mempool,prog->limit_edicts * sizeof(prvm_edict_t));
+
// alloc edict private space
- prog->edictprivate = Mem_Alloc(prog->edicts_mempool, prog->max_edicts * prog->edictprivate_size);
-
+ prog->edictprivate = Mem_Alloc(prog->progs_mempool, prog->max_edicts * prog->edictprivate_size);
+
// alloc edict fields
- prog->edictsfields = Mem_Alloc(prog->edicts_mempool, prog->max_edicts * prog->edict_size);
+ prog->edictsfields = Mem_Alloc(prog->progs_mempool, prog->max_edicts * prog->edict_size);
// set edict pointers
for(i = 0; i < prog->max_edicts; i++)
{
- prog->edicts[i].e = (prvm_edict_private_t *)((qbyte *)prog->edictprivate + i * prog->edictprivate_size);
+ prog->edicts[i].p.e = (prvm_edict_private_t *)((qbyte *)prog->edictprivate + i * prog->edictprivate_size);
prog->edicts[i].v = (void*)((qbyte *)prog->edictsfields + i * prog->edict_size);
}
}
void PRVM_MEM_IncreaseEdicts()
{
int i;
- int oldmaxedicts = prog->max_edicts;
+ int oldmaxedicts = prog->max_edicts;
void *oldedictsfields = prog->edictsfields;
void *oldedictprivate = prog->edictprivate;
-
+
if(prog->max_edicts >= prog->limit_edicts)
return;
-
+
PRVM_GCALL(begin_increase_edicts)();
// increase edicts
prog->max_edicts = min(prog->max_edicts + 256, prog->limit_edicts);
- prog->edictsfields = Mem_Alloc(prog->edicts_mempool, prog->max_edicts * prog->edict_size);
- prog->edictprivate = Mem_Alloc(prog->edicts_mempool, prog->max_edicts * prog->edictprivate_size);
+ prog->edictsfields = Mem_Alloc(prog->progs_mempool, prog->max_edicts * prog->edict_size);
+ prog->edictprivate = Mem_Alloc(prog->progs_mempool, prog->max_edicts * prog->edictprivate_size);
memcpy(prog->edictsfields, oldedictsfields, oldmaxedicts * prog->edict_size);
memcpy(prog->edictprivate, oldedictprivate, oldmaxedicts * prog->edictprivate_size);
//set e and v pointers
for(i = 0; i < prog->max_edicts; i++)
{
- prog->edicts[i].e = (prvm_edict_private_t *)((qbyte *)prog->edictprivate + i * prog->edictprivate_size);
+ prog->edicts[i].p.e = (prvm_edict_private_t *)((qbyte *)prog->edictprivate + i * prog->edictprivate_size);
prog->edicts[i].v = (void*)((qbyte *)prog->edictsfields + i * prog->edict_size);
}
void PRVM_SetProg(int prognr)
{
if(prognr && prognr < PRVM_MAXPROGS)
- {
+ {
if(prog_list[prognr].loaded)
prog = &prog_list[prognr];
else
{
int num;
memset (e->v, 0, prog->progs->entityfields * 4);
- e->e->free = false;
+ e->p.e->free = false;
// LordHavoc: for consistency set these here
num = PRVM_NUM_FOR_EDICT(e) - 1;
// AK: Let the init_edict function determine if something needs to be initialized
- PRVM_GCALL(init_edict)(num);
+ PRVM_GCALL(init_edict)(num);
}
/*
// the client qc dont need maxclients
// thus it doesnt need to use svs.maxclients
// AK: changed i=svs.maxclients+1
- // AK: changed so the edict 0 wont spawned -> used as reserved/world entity
+ // AK: changed so the edict 0 wont spawn -> used as reserved/world entity
// although the menu/client has no world
for (i = 1;i < prog->num_edicts;i++)
{
e = PRVM_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->e->free && ( e->e->freetime < 2 || prog->time - e->e->freetime > 0.5 ) )
+ if (e->p.e->free && ( e->p.e->freetime < 2 || (*prog->time - e->p.e->freetime) > 0.5 ) )
{
PRVM_ED_ClearEdict (e);
return e;
*/
void PRVM_ED_Free (prvm_edict_t *ed)
{
+ // dont delete the null entity (world)
+ if(PRVM_NUM_FOR_EDICT(ed) == 0)
+ return;
+
PRVM_GCALL(free_edict)(ed);
- ed->e->free = true;
- ed->e->freetime = prog->time;
+ ed->p.e->free = true;
+ ed->p.e->freetime = *prog->time;
}
//===========================================================================
switch (type)
{
case ev_string:
- sprintf (line, "%s", PRVM_GetString(val->string));
+ strlcpy (line, PRVM_GetString (val->string), sizeof (line));
break;
case ev_entity:
n = val->edict;
{
static char line[4096];
int i;
- char *s;
+ const char *s;
ddef_t *def;
mfunction_t *f;
-
+
type &= ~DEF_SAVEGLOBAL;
-
+
switch (type)
{
case ev_string:
line[i] = '\0';
break;
case ev_entity:
- snprintf (line, sizeof (line), "%i", PRVM_NUM_FOR_EDICT(PRVM_PROG_TO_EDICT(val->edict)));
+ dpsnprintf (line, sizeof (line), "%i", PRVM_NUM_FOR_EDICT(PRVM_PROG_TO_EDICT(val->edict)));
break;
case ev_function:
f = pr_functions + val->function;
- snprintf (line, sizeof (line), "%s", PRVM_GetString(f->s_name));
+ strlcpy (line, PRVM_GetString (f->s_name), sizeof (line));
break;
case ev_field:
def = PRVM_ED_FieldAtOfs ( val->_int );
- snprintf (line, sizeof (line), ".%s", PRVM_GetString(def->s_name));
+ dpsnprintf (line, sizeof (line), ".%s", PRVM_GetString(def->s_name));
break;
case ev_void:
- snprintf (line, sizeof (line), "void");
+ dpsnprintf (line, sizeof (line), "void");
break;
case ev_float:
- snprintf (line, sizeof (line), "%f", val->_float);
+ dpsnprintf (line, sizeof (line), "%f", val->_float);
break;
case ev_vector:
- snprintf (line, sizeof (line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
+ dpsnprintf (line, sizeof (line), "%f %f %f", val->vector[0], val->vector[1], val->vector[2]);
break;
default:
- snprintf (line, sizeof (line), "bad type %i", type);
+ dpsnprintf (line, sizeof (line), "bad type %i", type);
break;
}
-
+
return line;
}
*/
// LordHavoc: optimized this to print out much more quickly (tempstring)
// LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print)
-void PRVM_ED_Print (prvm_edict_t *ed)
+void PRVM_ED_Print(prvm_edict_t *ed)
{
int l;
ddef_t *d;
int *v;
int i, j;
- char *name;
+ const char *name;
int type;
char tempstring[8192], tempstring2[260]; // temporary string buffers
- if (ed->e->free)
+ if (ed->p.e->free)
{
- Con_Printf ("%s: FREE\n",PRVM_NAME);
+ Con_Printf("%s: FREE\n",PRVM_NAME);
return;
}
if (strlen(name) > 256)
{
- strncpy(tempstring2, name, 256);
+ memcpy (tempstring2, name, 256);
tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
tempstring2[259] = 0;
name = tempstring2;
name = PRVM_ValueString(d->type, (prvm_eval_t *)v);
if (strlen(name) > 256)
{
- strncpy(tempstring2, name, 256);
+ memcpy (tempstring2, name, 256);
tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
tempstring2[259] = 0;
name = tempstring2;
strcat(tempstring, "\n");
if (strlen(tempstring) >= 4096)
{
- Con_Printf("%s", tempstring);
+ Con_Print(tempstring);
tempstring[0] = 0;
}
}
if (tempstring[0])
- Con_Printf("%s", tempstring);
+ Con_Print(tempstring);
}
/*
ddef_t *d;
int *v;
int i, j;
- char *name;
+ const char *name;
int type;
- FS_Printf (f, "{\n");
+ FS_Print(f, "{\n");
- if (ed->e->free)
+ if (ed->p.e->free)
{
- FS_Printf (f, "}\n");
+ FS_Print(f, "}\n");
return;
}
if (j == prvm_type_size[type])
continue;
- FS_Printf (f,"\"%s\" ",name);
- FS_Printf (f,"\"%s\"\n", PRVM_UglyValueString(d->type, (prvm_eval_t *)v));
+ FS_Printf(f,"\"%s\" ",name);
+ FS_Printf(f,"\"%s\"\n", PRVM_UglyValueString(d->type, (prvm_eval_t *)v));
}
- FS_Printf (f, "}\n");
+ FS_Print(f, "}\n");
}
void PRVM_ED_PrintNum (int ent)
{
- PRVM_ED_Print (PRVM_EDICT_NUM(ent));
+ PRVM_ED_Print(PRVM_EDICT_NUM(ent));
}
/*
Con_Print("prvm_edicts <program name>\n");
return;
}
-
+
PRVM_Begin;
if(!PRVM_SetProgFromString(Cmd_Argv(1)))
return;
- Con_Printf ("%s: %i entities\n", PRVM_NAME, prog->num_edicts);
+ Con_Printf("%s: %i entities\n", PRVM_NAME, prog->num_edicts);
for (i=0 ; i<prog->num_edicts ; i++)
PRVM_ED_PrintNum (i);
i = atoi (Cmd_Argv(2));
if (i >= prog->num_edicts)
{
- Con_Printf("Bad edict number\n");
+ Con_Print("Bad edict number\n");
+ PRVM_End;
return;
}
PRVM_ED_PrintNum (i);
for (i=0 ; i<prog->num_edicts ; i++)
{
ent = PRVM_EDICT_NUM(i);
- if (ent->e->free)
+ if (ent->p.e->free)
continue;
active++;
}
-
- Con_Printf ("num_edicts:%3i\n", sv.num_edicts);
- Con_Printf ("active :%3i\n", active);
+
+ Con_Printf("num_edicts:%3i\n", prog->num_edicts);
+ Con_Printf("active :%3i\n", active);
}
PRVM_End;
{
ddef_t *def;
int i;
- char *name;
+ const char *name;
int type;
- FS_Printf (f,"{\n");
+ FS_Print(f,"{\n");
for (i=0 ; i<prog->progs->numglobaldefs ; i++)
{
def = &prog->globaldefs[i];
continue;
name = PRVM_GetString(def->s_name);
- FS_Printf (f,"\"%s\" ", name);
- FS_Printf (f,"\"%s\"\n", PRVM_UglyValueString(type, (prvm_eval_t *)&prog->globals[def->ofs]));
+ FS_Printf(f,"\"%s\" ", name);
+ FS_Printf(f,"\"%s\"\n", PRVM_UglyValueString(type, (prvm_eval_t *)&prog->globals[def->ofs]));
}
- FS_Printf (f,"}\n");
+ FS_Print(f,"}\n");
}
/*
key = PRVM_ED_FindGlobal (keyname);
if (!key)
{
- Con_DPrintf ("'%s' is not a global on %s\n", keyname, PRVM_NAME);
+ Con_DPrintf("'%s' is not a global on %s\n", keyname, PRVM_NAME);
continue;
}
//============================================================================
-/*
-=============
-PRVM_ED_NewString
-=============
-*/
-char *PRVM_ED_NewString (const char *string)
-{
- char *new, *new_p;
- int i,l;
-
- l = strlen(string) + 1;
- new = Mem_Alloc(prog->edictstring_mempool, l);
- new_p = new;
-
- 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];
- }
-
- return new;
-}
-
-
/*
=============
PRVM_ED_ParseEval
*/
qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s)
{
- int i;
+ int i, l;
+ char *new_p;
ddef_t *def;
prvm_eval_t *val;
mfunction_t *func;
if (ent)
val = (prvm_eval_t *)((int *)ent->v + key->ofs);
else
- val = (prvm_eval_t *)((int *)pr_globals + key->ofs);
+ val = (prvm_eval_t *)((int *)prog->globals + key->ofs);
switch (key->type & ~DEF_SAVEGLOBAL)
{
case ev_string:
- val->string = PRVM_SetString(ED_NewString(s));
+ l = strlen(s) + 1;
+ new_p = PRVM_AllocString(l);
+ val->string = PRVM_SetQCString(new_p);
+ for (i = 0;i < l;i++)
+ {
+ if (s[i] == '\\' && i < l-1)
+ {
+ i++;
+ if (s[i] == 'n')
+ *new_p++ = '\n';
+ else if (s[i] == 'r')
+ *new_p++ = '\r';
+ else
+ *new_p++ = s[i];
+ }
+ else
+ *new_p++ = s[i];
+ }
break;
case ev_float:
def = PRVM_ED_FindField(s);
if (!def)
{
- Con_DPrintf("PRVM_ED_ParseEpair: Can't find field %s on %s\n", s, PRVM_NAME);
+ Con_DPrintf("PRVM_ED_ParseEpair: Can't find field %s in %s\n", s, PRVM_NAME);
return false;
}
- val->_int = PRVM_G_INT(def->ofs);
+ val->_int = def->ofs;
break;
case ev_function:
func = PRVM_ED_FindFunction(s);
if (!func)
{
- Con_Printf ("PRVM_ED_ParseEpair: Can't find function %s on %s\n", s, PRVM_NAME);
+ Con_Printf("PRVM_ED_ParseEpair: Can't find function %s in %s\n", s, PRVM_NAME);
return false;
}
val->function = func - prog->functions;
return true;
}
+/*
+=============
+PRVM_ED_EdictSet_f
+
+Console command to set a field of a specified edict
+=============
+*/
+void PRVM_ED_EdictSet_f(void)
+{
+ prvm_edict_t *ed;
+ ddef_t *key;
+
+ if(Cmd_Argc() != 5)
+ {
+ Con_Print("prvm_edictset <program name> <edict number> <field> <value>\n");
+ return;
+ }
+
+ PRVM_Begin;
+ if(!PRVM_SetProgFromString(Cmd_Argv(1)))
+ {
+ Con_Printf("Wrong program name %s !\n", Cmd_Argv(1));
+ return;
+ }
+
+ ed = PRVM_EDICT_NUM(atoi(Cmd_Argv(2)));
+
+ if((key = PRVM_ED_FindField(Cmd_Argv(3))) == 0)
+ Con_Printf("Key %s not found !\n", Cmd_Argv(3));
+ else
+ PRVM_ED_ParseEpair(ed, key, Cmd_Argv(4));
+
+ PRVM_End;
+}
+
/*
====================
PRVM_ED_ParseEdict
init = false;
-// clear it
- if (ent != prog->edicts) // hack
- memset (ent->v, 0, prog->progs->entityfields * 4);
-
// go through all the dictionary pairs
while (1)
{
strcpy (keyname, com_token);
- // another hack to fix heynames with trailing spaces
+ // another hack to fix keynames with trailing spaces
n = strlen(keyname);
while (n && keyname[n-1] == ' ')
{
key = PRVM_ED_FindField (keyname);
if (!key)
{
- Con_DPrintf ("%s: '%s' is not a field\n", PRVM_NAME, keyname);
+ Con_DPrintf("%s: '%s' is not a field\n", PRVM_NAME, keyname);
continue;
}
}
if (!init)
- ent->e->free = true;
+ ent->p.e->free = true;
return data;
}
int parsed, inhibited, spawned, died;
mfunction_t *func;
- ent = NULL;
parsed = 0;
inhibited = 0;
spawned = 0;
died = 0;
- // time defined ?
- if(prog->flag & PRVM_GE_TIME)
- PRVM_G_FLOAT(PRVM_ED_FindFieldOffset("time")) = prog->time;
-
+
// parse ents
while (1)
{
if (!COM_ParseToken(&data, false))
break;
if (com_token[0] != '{')
- PRVM_ERROR ("PRVM_ED_LoadFromFile: found %s when expecting (%s) {",com_token, PRVM_NAME);
+ PRVM_ERROR ("PRVM_ED_LoadFromFile: %s: found %s when expecting {", PRVM_NAME, com_token);
- if (!ent)
+ // CHANGED: this is not conform to ED_LoadFromFile
+ if(!prog->num_edicts)
ent = PRVM_EDICT_NUM(0);
else
- ent = PRVM_ED_Alloc ();
+ ent = PRVM_ED_Alloc();
+
+ // clear it
+ if (ent != prog->edicts) // hack
+ memset (ent->v, 0, prog->progs->entityfields * 4);
+
data = PRVM_ED_ParseEdict (data, ent);
parsed++;
}
//
-// immediately call spawn function, but only if there is a self global
+// immediately call spawn function, but only if there is a self global and a classname
//
if(prog->self && prog->flag & PRVM_FE_CLASSNAME)
{
string_t handle = *(string_t*)&((float*)ent->v)[PRVM_ED_FindFieldOffset("classname")];
if (!handle)
{
- Con_Printf ("No classname for:\n");
- PRVM_ED_Print (ent);
+ Con_Print("No classname for:\n");
+ PRVM_ED_Print(ent);
PRVM_ED_Free (ent);
continue;
}
-
+
// look for the spawn function
func = PRVM_ED_FindFunction (PRVM_GetString(handle));
-
+
if (!func)
{
if (developer.integer) // don't confuse non-developers with errors
{
- Con_Printf ("No spawn function for:\n");
- PRVM_ED_Print (ent);
+ Con_Print("No spawn function for:\n");
+ PRVM_ED_Print(ent);
}
PRVM_ED_Free (ent);
continue;
}
-
+
// self = ent
PRVM_G_INT(prog->self->ofs) = PRVM_EDICT_TO_PROG(ent);
PRVM_ExecuteProgram (func - prog->functions, "");
}
-
+
spawned++;
- if (ent->e->free)
+ if (ent->p.e->free)
died++;
}
- Con_DPrintf ("%s: %i entities parsed, %i inhibited, %i spawned (%i removed self, %i stayed)\n", PRVM_NAME, parsed, inhibited, spawned, died, spawned - died);
+ Con_DPrintf("%s: %i new entities parsed, %i new inhibited, %i (%i new) spawned (whereas %i removed self, %i stayed)\n", PRVM_NAME, parsed, inhibited, prog->num_edicts, spawned, died, spawned - died);
}
// not used
void PRVM_ResetProg()
{
- mempool_t *t1, *t2, *t3;
-
- t1 = prog->progs_mempool;
- t2 = prog->edictstring_mempool;
- t3 = prog->edicts_mempool;
-
- Mem_EmptyPool(prog->progs_mempool);
- Mem_EmptyPool(prog->edictstring_mempool);
- Mem_EmptyPool(prog->edicts_mempool);
-
+ Mem_FreePool(&prog->progs_mempool);
memset(prog,0,sizeof(prvm_prog_t));
-
-
- prog->progs_mempool = t1;
- prog->edictstring_mempool = t2;
- prog->edicts_mempool = t3;
-
PRVM_GCALL(reset_cmd)();
}
int i;
dstatement_t *st;
ddef_t *infielddefs;
- void *temp;
dfunction_t *dfunctions;
Mem_EmptyPool(prog->progs_mempool);
- Mem_EmptyPool(prog->edictstring_mempool);
- temp = FS_LoadFile (filename, false);
- if (temp == 0)
+ prog->progs = (dprograms_t *)FS_LoadFile (filename, prog->progs_mempool, false);
+ if (prog->progs == NULL)
PRVM_ERROR ("PRVM_LoadProgs: couldn't load %s for %s", filename, PRVM_NAME);
- prog->progs = (dprograms_t *)Mem_Alloc(prog->progs_mempool, fs_filesize);
-
- memcpy(prog->progs, temp, fs_filesize);
- Mem_Free(temp);
-
- Con_DPrintf ("%s programs occupy %iK.\n", PRVM_NAME, fs_filesize/1024);
+ Con_DPrintf("%s programs occupy %iK.\n", PRVM_NAME, fs_filesize/1024);
pr_crc = CRC_Block((qbyte *)prog->progs, fs_filesize);
//pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
dfunctions = (dfunction_t *)((qbyte *)prog->progs + prog->progs->ofs_functions);
+
prog->strings = (char *)prog->progs + prog->progs->ofs_strings;
+ prog->stringssize = 0;
+ for (i = 0;i < prog->progs->numstrings;i++)
+ {
+ if (prog->progs->ofs_strings + prog->stringssize >= fs_filesize)
+ PRVM_ERROR ("%s: %s strings go past end of file\n", PRVM_NAME, filename);
+ prog->stringssize += strlen (prog->strings + prog->stringssize) + 1;
+ }
+ prog->numknownstrings = 0;
+ prog->maxknownstrings = 0;
+ prog->knownstrings = NULL;
+
prog->globaldefs = (ddef_t *)((qbyte *)prog->progs + prog->progs->ofs_globaldefs);
// we need to expand the fielddefs list to include all the engine fields,
{
pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
- pr_fielddefs[progs->numfielddefs].s_name = PR_SetString(dpfields[i].string);
+ pr_fielddefs[progs->numfielddefs].s_name = PR_SetEngineString(dpfields[i].string);
if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
progs->entityfields += 3;
else
PRVM_Init_Exec();
prog->loaded = TRUE;
-
+
// set flags & ddef_ts in prog
-
+
prog->flag = 0;
-
+
prog->self = PRVM_ED_FindGlobal("self");
- if(PRVM_ED_FindGlobal("time"))
- prog->flag |= PRVM_GE_TIME;
+ if( PRVM_ED_FindGlobal("time") && PRVM_ED_FindGlobal("time")->type & ev_float )
+ prog->time = &PRVM_G_FLOAT(PRVM_ED_FindGlobal("time")->ofs);
if(PRVM_ED_FindField ("chain"))
prog->flag |= PRVM_FE_CHAIN;
if(PRVM_ED_FindField ("classname"))
- prog->flag |= PRVM_FE_CLASSNAME;
+ prog->flag |= PRVM_FE_CLASSNAME;
- if(PRVM_ED_FindField ("nextthink") && PRVM_ED_FindField ("frame") && PRVM_ED_FindField ("think")
- && prog->flag & PRVM_GE_TIME && prog->self)
+ if(PRVM_ED_FindField ("nextthink") && PRVM_ED_FindField ("frame") && PRVM_ED_FindField ("think")
+ && prog->flag && prog->self)
prog->flag |= PRVM_OP_STATE;
-
+
PRVM_GCALL(reset_cmd)();
+ PRVM_GCALL(init_cmd)();
// init mempools
PRVM_MEM_Alloc();
{
int i, j, ednum, used, usedamount;
int *counts;
- char tempstring[5000], tempstring2[260], *name;
+ char tempstring[5000], tempstring2[260];
+ const char *name;
prvm_edict_t *ed;
ddef_t *d;
int *v;
/*
if (!sv.active)
{
- Con_Printf("no progs loaded\n");
+ Con_Print("no progs loaded\n");
return;
}
*/
for (ednum = 0;ednum < prog->max_edicts;ednum++)
{
ed = PRVM_EDICT_NUM(ednum);
- if (ed->e->free)
+ if (ed->p.e->free)
continue;
for (i = 1;i < prog->progs->numfielddefs;i++)
{
}
if (strlen(name) > 256)
{
- strncpy(tempstring2, name, 256);
+ memcpy (tempstring2, name, 256);
tempstring2[256] = tempstring2[257] = tempstring2[258] = '.';
tempstring2[259] = 0;
name = tempstring2;
strcat(tempstring, "\n");
if (strlen(tempstring) >= 4096)
{
- Con_Printf("%s", tempstring);
+ Con_Print(tempstring);
tempstring[0] = 0;
}
if (counts[i])
// TODO
/*if (!sv.active)
{
- Con_Printf("no progs loaded\n");
+ Con_Print("no progs loaded\n");
return;
}*/
if(Cmd_Argc () != 2)
{
- Con_Print ("prvm_globals <program name>\n");
+ Con_Print("prvm_globals <program name>\n");
return;
}
Con_Printf("%s :", PRVM_NAME);
for (i = 0;i < prog->progs->numglobaldefs;i++)
- Con_Printf("%s\n", PRVM_GetString(pr_globaldefs[i].s_name));
+ Con_Printf("%s\n", PRVM_GetString(prog->globaldefs[i].s_name));
Con_Printf("%i global variables, totalling %i bytes\n", prog->progs->numglobals, prog->progs->numglobals * 4);
PRVM_End;
}
+/*
+===============
+PRVM_Global
+===============
+*/
+void PRVM_Global_f(void)
+{
+ ddef_t *global;
+ if( Cmd_Argc() != 3 ) {
+ Con_Printf( "prvm_global <program name> <global name>\n" );
+ return;
+ }
+
+ PRVM_Begin;
+ if( !PRVM_SetProgFromString( Cmd_Argv(1) ) )
+ return;
+
+ global = PRVM_ED_FindGlobal( Cmd_Argv(2) );
+ if( !global )
+ Con_Printf( "No global '%s' in %s!\n", Cmd_Argv(2), Cmd_Argv(1) );
+ else
+ Con_Printf( "%s: %s\n", Cmd_Argv(2), PRVM_ValueString( global->type, (prvm_eval_t *) &prog->globals[ global->ofs ] ) );
+ PRVM_End;
+}
+
+/*
+===============
+PRVM_GlobalSet
+===============
+*/
+void PRVM_GlobalSet_f(void)
+{
+ ddef_t *global;
+ if( Cmd_Argc() != 4 ) {
+ Con_Printf( "prvm_globalset <program name> <global name> <value>\n" );
+ return;
+ }
+
+ PRVM_Begin;
+ if( !PRVM_SetProgFromString( Cmd_Argv(1) ) )
+ return;
+
+ global = PRVM_ED_FindGlobal( Cmd_Argv(2) );
+ if( !global )
+ Con_Printf( "No global '%s' in %s!\n", Cmd_Argv(2), Cmd_Argv(1) );
+ else
+ PRVM_ED_ParseEpair( NULL, global, Cmd_Argv(3) );
+ PRVM_End;
+}
+
/*
===============
PRVM_Init
Cmd_AddCommand ("prvm_profile", PRVM_Profile_f);
Cmd_AddCommand ("prvm_fields", PRVM_Fields_f);
Cmd_AddCommand ("prvm_globals", PRVM_Globals_f);
+ Cmd_AddCommand ("prvm_global", PRVM_Global_f);
+ Cmd_AddCommand ("prvm_globalset", PRVM_GlobalSet_f);
+ Cmd_AddCommand ("prvm_edictset", PRVM_ED_EdictSet_f);
// LordHavoc: optional runtime bounds checking (speed drain, but worth it for security, on by default - breaks most QCCX features (used by CRMod and others))
Cvar_RegisterVariable (&prvm_boundscheck);
Cvar_RegisterVariable (&prvm_traceqc);
- VM_Cmd_Init();
+ //VM_Cmd_Init();
}
/*
prog = &prog_list[prognr];
+ if(prog->loaded)
+ PRVM_ResetProg();
+
memset(prog, 0, sizeof(prvm_prog_t));
- PRVM_GCALL(init_cmd)();
+ prog->time = &prog->_time;
}
int PRVM_GetProgNr()
return prog - prog_list;
}
+void *_PRVM_Alloc(size_t buffersize, const char *filename, int fileline)
+{
+ return _Mem_Alloc(prog->progs_mempool, buffersize, filename, fileline);
+}
+
+void _PRVM_Free(void *buffer, const char *filename, int fileline)
+{
+ _Mem_Free(buffer, filename, fileline);
+}
+
+void _PRVM_FreeAll(const char *filename, int fileline)
+{
+ prog->progs = NULL;
+ prog->fielddefs = NULL;
+ prog->functions = NULL;
+ _Mem_EmptyPool(prog->progs_mempool, filename, fileline);
+}
+
// LordHavoc: turned PRVM_EDICT_NUM into a #define for speed reasons
prvm_edict_t *PRVM_EDICT_NUM_ERROR(int n, char *filename, int fileline)
{
return NULL;
}
+void PRVM_ProcessError(void)
+{
+ if(prog)
+ PRVM_GCALL(error_cmd)();
+}
+
/*
int NUM_FOR_EDICT_ERROR(edict_t *e)
{
}
*/
+
+const char *PRVM_GetString(int num)
+{
+ if (num >= 0 && num < prog->stringssize)
+ return prog->strings + num;
+ else if (num < 0 && num >= -prog->numknownstrings)
+ {
+ num = -1 - num;
+ if (!prog->knownstrings[num])
+ Host_Error("PRVM_GetString: attempt to get string that is already freed\n");
+ return prog->knownstrings[num];
+ }
+ else
+ {
+ Host_Error("PRVM_GetString: invalid string offset %i\n", num);
+ return "";
+ }
+}
+
+int PRVM_SetQCString(const char *s)
+{
+ int i;
+ if (!s)
+ return 0;
+ if (s >= prog->strings && s <= prog->strings + prog->stringssize)
+ return s - prog->strings;
+ for (i = 0;i < prog->numknownstrings;i++)
+ if (prog->knownstrings[i] == s)
+ return -1 - i;
+ Host_Error("PRVM_SetQCString: unknown string\n");
+ return -1 - i;
+}
+
+int PRVM_SetEngineString(const char *s)
+{
+ int i;
+ if (!s)
+ return 0;
+ if (s >= prog->strings && s <= prog->strings + prog->stringssize)
+ Host_Error("PRVM_SetEngineString: s in prog->strings area\n");
+ for (i = 0;i < prog->numknownstrings;i++)
+ if (prog->knownstrings[i] == s)
+ return -1 - i;
+ // new unknown engine string
+ if (developer.integer >= 3)
+ Con_Printf("new engine string %p\n", s);
+ for (i = 0;i < prog->numknownstrings;i++)
+ if (!prog->knownstrings[i])
+ break;
+ if (i >= prog->numknownstrings)
+ {
+ if (i >= prog->maxknownstrings)
+ {
+ const char **oldstrings = prog->knownstrings;
+ prog->maxknownstrings += 128;
+ prog->knownstrings = PRVM_Alloc(prog->maxknownstrings * sizeof(char *));
+ if (prog->numknownstrings)
+ memcpy((char **)prog->knownstrings, oldstrings, prog->numknownstrings * sizeof(char *));
+ }
+ prog->numknownstrings++;
+ }
+ prog->knownstrings[i] = s;
+ return -1 - i;
+}
+
+char *PRVM_AllocString(int bufferlength)
+{
+ int i;
+ if (!bufferlength)
+ return 0;
+ for (i = 0;i < prog->numknownstrings;i++)
+ if (!prog->knownstrings[i])
+ break;
+ if (i >= prog->numknownstrings)
+ {
+ if (i >= prog->maxknownstrings)
+ {
+ const char **oldstrings = prog->knownstrings;
+ prog->maxknownstrings += 128;
+ prog->knownstrings = PRVM_Alloc(prog->maxknownstrings * sizeof(char *));
+ if (prog->numknownstrings)
+ memcpy((char **)prog->knownstrings, oldstrings, prog->numknownstrings * sizeof(char *));
+ }
+ prog->numknownstrings++;
+ }
+ return (char *)(prog->knownstrings[i] = PRVM_Alloc(bufferlength));
+}
+
+void PRVM_FreeString(char *s)
+{
+ int i;
+ if (!s)
+ Host_Error("PRVM_FreeString: attempt to free a NULL string\n");
+ if (s >= prog->strings && s <= prog->strings + prog->stringssize)
+ Host_Error("PRVM_FreeString: attempt to free a constant string\n");
+ for (i = 0;i < prog->numknownstrings;i++)
+ if (prog->knownstrings[i] == s)
+ break;
+ if (i == prog->numknownstrings)
+ Host_Error("PRVM_FreeString: attempt to free a non-existent or already freed string\n");
+ PRVM_Free((char *)prog->knownstrings[i]);
+ prog->knownstrings[i] = NULL;
+}
+