0
0
Fork 0
mirror of https://git.code.sf.net/p/quake/quakeforge synced 2025-03-21 18:01:15 +00:00

Rewrite edict access.

The server edict arrays are now stored outside of progs memory, only the
entity data itself (ie data accessible to progs via ent.fld) is stored in
progs memory. Many of the changes were due to code accessing edicts and
entity fields directly rather than through the provided macros.
This commit is contained in:
Bill Currie 2013-01-17 14:11:54 +09:00
parent 132e25b096
commit 66fda1fddb
16 changed files with 173 additions and 124 deletions

View file

@ -218,10 +218,11 @@ void PR_BoundsCheck (progs_t *pr, int addr, etype_t type);
struct edict_s {
qboolean free;
progs_t *pr; ///< progs owning this edict
int entnum; ///< number of this entity
int edict; ///< offset of this entity in pr_edict_area
float freetime; ///< sv.time when the object was freed
void *edata; ///< external per-edict data
pr_type_t v[1]; ///< fields from progs
};
// pr_edict.c
@ -252,18 +253,18 @@ struct plitem_s *ED_Parse (progs_t *pr, const char *data);
void ED_LoadFromFile (progs_t *pr, const char *data);
void ED_EntityParseFunction (progs_t *pr);
#define PR_edicts(p) ((byte *) *(p)->edicts)
#define PR_edicts(p) (*(p)->pr_edicts)
#define NEXT_EDICT(p,e) ((edict_t *) ((byte *) e + (p)->pr_edict_size))
#define EDICT_TO_PROG(p,e) ((pr_int_t)(intptr_t)((byte *)(e) - PR_edicts (p)))
#define PROG_TO_EDICT(p,e) ((edict_t *) (PR_edicts (p) + (e)))
#define NEXT_EDICT(p,e) ((e) + 1)
#define EDICT_TO_PROG(p,e) ((e)->entnum * (p)->pr_edict_size)
#define PROG_TO_EDICT(p,e) (&PR_edicts(p)[(e) / (p)->pr_edict_size])
#define NUM_FOR_BAD_EDICT(p,e) ((e)->entnum)
#ifndef PR_PARANOID_PROGS
# define EDICT_NUM(p,n) (PROG_TO_EDICT (p, (n) * (p)->pr_edict_size))
# define NUM_FOR_EDICT(p,e) NUM_FOR_BAD_EDICT (p, e)
# define EDICT_NUM(p,n) (PR_edicts (p) + (n))
# define NUM_FOR_EDICT(p,e) NUM_FOR_BAD_EDICT ((p), (e))
#else
# define EDICT_NUM(p,n) ED_EdictNum (p, n)
# define NUM_FOR_EDICT(p,e) ED_NumForEdict (p, e)
# define EDICT_NUM(p,n) ED_EdictNum ((p), (n))
# define NUM_FOR_EDICT(p,e) ED_NumForEdict ((p), (e))
#endif
//@}
@ -420,7 +421,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\hideinitializer
*/
#define G_EDICT(p,o) ((edict_t *)(PR_edicts (p) + G_INT (p, o)))
#define G_EDICT(p,o) PROG_TO_EDICT ((p), G_INT (p, o))
/** Access an entity global.
@ -610,7 +611,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\hideinitializer
*/
#define P_EDICT(p,n) ((edict_t *)(PR_edicts (p) + P_INT (p, n)))
#define P_EDICT(p,n) PROG_TO_EDICT ((p), P_INT (p, n))
/** Access an entity parameter.
@ -807,7 +808,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\hideinitializer
*/
#define RETURN_EDICT(p,e) (R_STRING (p) = EDICT_TO_PROG(p, e))
#define RETURN_EDICT(p,e) (R_INT (p) = EDICT_TO_PROG(p, e))
/** Set the return value to the given C pointer. NULL is converted to 0.
@ -858,7 +859,18 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_
\hideinitializer
*/
#define E_var(e,o,t) ((e)->v[o].t##_var)
#define E_fld(e,o) ((e)->pr->pr_edict_area[(e)->edict + (o)])
/** \internal
\param e pointer to the entity
\param o field offset into entity data space
\param t typename prefix (see pr_type_u)
\return lvalue of the appropriate type
\hideinitializer
*/
#define E_var(e,o,t) (E_fld (e,o).t##_var)
/** Access a float entity field. Can be assigned to.
@ -1592,7 +1604,7 @@ struct progs_s {
/// \name edicts
//@{
edict_t **edicts;
edict_t **pr_edicts;
int max_edicts;
int *num_edicts;
int *reserved_edicts; ///< alloc will start at reserved_edicts+1
@ -1600,8 +1612,9 @@ struct progs_s {
void (*flush) (void);
int (*prune_edict) (progs_t *pr, edict_t *ent);
void (*free_edict) (progs_t *pr, edict_t *ent);
int pr_edict_size; ///< in bytes
int pr_edictareasize; ///< for bounds checking, starts at 0
pr_type_t *pr_edict_area;
int pr_edict_size; ///< # of pr_type_t slots
int pr_edict_area_size; ///< for bounds checking, starts at 0
func_t edict_parse;
//@}

View file

@ -160,7 +160,7 @@ parse_expression (progs_t *pr, const char *expr, int conditional)
if (!field)
goto error;
d = *field;
expr_ptr = &ent->v[field->ofs];
expr_ptr = &E_fld (ent, field->ofs);
d.ofs = PR_SetPointer (pr, expr_ptr);
} else if (isdigit ((byte) es->token->str[0])) {
expr_ptr = PR_GetPointer (pr, strtol (es->token->str, 0, 0));
@ -924,9 +924,9 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
parm_ind = pr->pr_globals[s->b].uinteger_var;
if (parm_ind < pr->progs->entityfields
&& opval >= 0
&& opval < pr->pr_edictareasize) {
&& opval < pr->pr_edict_area_size) {
ed = PROG_TO_EDICT (pr, opval);
opval = &ed->v[parm_ind] - pr->pr_globals;
opval = &E_fld(ed, parm_ind) - pr->pr_globals;
}
if (!ed) {
str = "bad entity.field";
@ -1064,7 +1064,7 @@ ED_Print (progs_t *pr, edict_t *ed)
&& strchr ("xyz", name[strlen (name) -1]))
continue; // skip _x, _y, _z vars
v = ed->v + d->ofs;
v = &E_fld(ed, d->ofs);
// if the value is still all 0, skip the field
type = d->type & ~DEF_SAVEGLOBAL;

View file

@ -66,13 +66,11 @@ ED_ClearEdict (progs_t *pr, edict_t *e, int val)
if (NUM_FOR_EDICT (pr, e) < *pr->reserved_edicts)
Sys_Printf ("clearing reserved edict %d\n", NUM_FOR_EDICT (pr, e));
for (i=0; i < pr->progs->entityfields; i++)
e->v[i].integer_var = val;
E_INT (e, i) = val;
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
@ -203,9 +201,9 @@ ED_Count (progs_t *pr)
continue;
}
active++;
if (solid_def && ent->v[solid_def->ofs].float_var)
if (solid_def && E_FLOAT (ent, solid_def->ofs))
solid++;
if (model_def && ent->v[model_def->ofs].float_var)
if (model_def && E_FLOAT (ent, model_def->ofs))
models++;
}
@ -219,12 +217,10 @@ ED_Count (progs_t *pr)
edict_t *
ED_EdictNum (progs_t *pr, pr_int_t n)
{
pr_int_t offs = n * pr->pr_edict_size;
if (offs < 0 || n >= pr->pr_edictareasize)
if (n < 0 || n >= *pr->num_edicts)
PR_RunError (pr, "EDICT_NUM: bad number %d", n);
return PROG_TO_EDICT (pr, offs);
return PR_edicts(pr) + n;
}
pr_int_t
@ -234,9 +230,9 @@ ED_NumForEdict (progs_t *pr, edict_t *e)
b = NUM_FOR_BAD_EDICT (pr, e);
if (b && (b < 0 || b >= *(pr)->num_edicts))
if (b && (b < 0 || b >= *pr->num_edicts))
PR_RunError (pr, "NUM_FOR_EDICT: bad pointer %d %p %p", b, e,
*(pr)->edicts);
pr->pr_edicts);
return b;
}
@ -244,7 +240,7 @@ ED_NumForEdict (progs_t *pr, edict_t *e)
qboolean
PR_EdictValid (progs_t *pr, pr_int_t e)
{
if (e < 0 || e >= pr->pr_edictareasize)
if (e < 0 || e >= pr->pr_edict_area_size)
return false;
if (e % pr->pr_edict_size)
return false;

View file

@ -355,9 +355,9 @@ VISIBLE void
PR_ExecuteProgram (progs_t * pr, func_t fnum)
{
int exitdepth, profile, startprofile;
int fldofs;
pr_uint_t pointer;
dstatement_t *st;
edict_t *ed;
pr_type_t *ptr;
pr_type_t old_val = {0}, *watch = 0;
@ -642,7 +642,7 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
case OP_ADDRESS:
if (pr_boundscheck->int_val) {
if (OPA.entity_var < 0
|| OPA.entity_var >= pr->pr_edictareasize)
|| OPA.entity_var >= pr->pr_edict_area_size)
PR_RunError (pr, "Progs attempted to address an out "
"of bounds edict");
if (OPA.entity_var == 0 && pr->null_bad)
@ -651,8 +651,8 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
PR_RunError (pr, "Progs attempted to address an "
"invalid field in an edict");
}
ed = PROG_TO_EDICT (pr, OPA.entity_var);
OPC.integer_var = &ed->v[OPB.integer_var] - pr->pr_globals;
fldofs = OPA.entity_var + OPB.integer_var;
OPC.integer_var = &pr->pr_edict_area[fldofs] - pr->pr_globals;
break;
case OP_ADDRESS_VOID:
case OP_ADDRESS_F:
@ -676,41 +676,41 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
case OP_LOAD_P:
if (pr_boundscheck->int_val) {
if (OPA.entity_var < 0
|| OPA.entity_var >= pr->pr_edictareasize)
|| OPA.entity_var >= pr->pr_edict_area_size)
PR_RunError (pr, "Progs attempted to read an out of "
"bounds edict number");
if (OPB.uinteger_var >= pr->progs->entityfields)
PR_RunError (pr, "Progs attempted to read an invalid "
"field in an edict");
}
ed = PROG_TO_EDICT (pr, OPA.entity_var);
OPC.integer_var = ed->v[OPB.integer_var].integer_var;
fldofs = OPA.entity_var + OPB.integer_var;
OPC.integer_var = pr->pr_edict_area[fldofs].integer_var;
break;
case OP_LOAD_V:
if (pr_boundscheck->int_val) {
if (OPA.entity_var < 0
|| OPA.entity_var >= pr->pr_edictareasize)
|| OPA.entity_var >= pr->pr_edict_area_size)
PR_RunError (pr, "Progs attempted to read an out of "
"bounds edict number");
if (OPB.uinteger_var + 2 >= pr->progs->entityfields)
PR_RunError (pr, "Progs attempted to read an invalid "
"field in an edict");
}
ed = PROG_TO_EDICT (pr, OPA.entity_var);
memcpy (&OPC, &ed->v[OPB.integer_var], 3 * sizeof (OPC));
fldofs = OPA.entity_var + OPB.integer_var;
memcpy (&OPC, &pr->pr_edict_area[fldofs], 3 * sizeof (OPC));
break;
case OP_LOAD_Q:
if (pr_boundscheck->int_val) {
if (OPA.entity_var < 0
|| OPA.entity_var >= pr->pr_edictareasize)
|| OPA.entity_var >= pr->pr_edict_area_size)
PR_RunError (pr, "Progs attempted to read an out of "
"bounds edict number");
if (OPB.uinteger_var + 3 >= pr->progs->entityfields)
PR_RunError (pr, "Progs attempted to read an invalid "
"field in an edict");
}
ed = PROG_TO_EDICT (pr, OPA.entity_var);
memcpy (&OPC, &ed->v[OPB.integer_var], 3 * sizeof (OPC));
fldofs = OPA.entity_var + OPB.integer_var;
memcpy (&OPC, &pr->pr_edict_area[fldofs], 4 * sizeof (OPC));
break;
case OP_LOADB_F:
@ -965,18 +965,34 @@ op_call:
}
break;
case OP_STATE:
ed = PROG_TO_EDICT (pr, *pr->globals.self);
ed->v[pr->fields.nextthink].float_var = *pr->globals.time +
0.1;
ed->v[pr->fields.frame].float_var = OPA.float_var;
ed->v[pr->fields.think].func_var = OPB.func_var;
{
int self = *pr->globals.self;
int nextthink = pr->fields.nextthink;
int frame = pr->fields.frame;
int think = pr->fields.think;
fldofs = self + nextthink;
pr->pr_edict_area[fldofs].float_var = *pr->globals.time +
0.1;
fldofs = self + frame;
pr->pr_edict_area[fldofs].float_var = OPA.float_var;
fldofs = self + think;
pr->pr_edict_area[fldofs].func_var = OPB.func_var;
}
break;
case OP_STATE_F:
ed = PROG_TO_EDICT (pr, *pr->globals.self);
ed->v[pr->fields.nextthink].float_var = *pr->globals.time +
OPC.float_var;
ed->v[pr->fields.frame].float_var = OPA.float_var;
ed->v[pr->fields.think].func_var = OPB.func_var;
{
int self = *pr->globals.self;
int nextthink = pr->fields.nextthink;
int frame = pr->fields.frame;
int think = pr->fields.think;
fldofs = self + nextthink;
pr->pr_edict_area[fldofs].float_var = *pr->globals.time +
OPC.float_var;
fldofs = self + frame;
pr->pr_edict_area[fldofs].float_var = OPA.float_var;
fldofs = self + think;
pr->pr_edict_area[fldofs].func_var = OPB.func_var;
}
break;
case OP_ADD_I:
OPC.integer_var = OPA.integer_var + OPB.integer_var;

View file

@ -166,6 +166,16 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size, int max_edicts, int zone)
pr->progs_size += sizeof (void*) - 1;
pr->progs_size &= ~(sizeof (void*) - 1);
// size of edict asked for by progs, but at least 1
pr->pr_edict_size = max (1, progs.entityfields);
// round off to next highest multiple of 4 words
// this ensures that progs that try to align vectors and quaternions
// get what they want
pr->pr_edict_size += (4 - 1);
pr->pr_edict_size &= ~(4 - 1);
pr->pr_edict_area_size = max_edicts * pr->pr_edict_size;
pr->max_edicts = max_edicts;
// size of heap asked for by vm-subsystem
pr->zone_size = zone;
// round off to next highest whole word address (esp for Alpha)
@ -174,19 +184,8 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size, int max_edicts, int zone)
pr->zone_size += sizeof (void*) - 1;
pr->zone_size &= ~(sizeof (void*) - 1);
// size of edict asked for by progs
pr->pr_edict_size = max (1, progs.entityfields) * 4;
// size of engine data
pr->pr_edict_size += sizeof (edict_t) - sizeof (pr_type_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->pr_edict_size += sizeof (void*) - 1;
pr->pr_edict_size &= ~(sizeof (void*) - 1);
pr->pr_edictareasize = max_edicts * pr->pr_edict_size;
pr->max_edicts = max_edicts;
mem_size = pr->progs_size + pr->zone_size + pr->pr_edictareasize;
mem_size = pr->pr_edict_area_size * sizeof (pr_type_t);
mem_size += pr->progs_size + pr->zone_size;
pr->progs = pr->allocate_progs_mem (pr, mem_size + 1);
if (!pr->progs)
return;
@ -198,13 +197,10 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size, int max_edicts, int zone)
CRC_ProcessBlock (base, &pr->crc, size - sizeof (progs));
base -= sizeof (progs); // offsets are from file start
if (pr->edicts)
*pr->edicts = (edict_t *)((byte *) pr->progs + pr->progs_size);
pr->zone = (memzone_t *)((byte *) pr->progs + pr->progs_size
+ pr->pr_edictareasize);
pr->pr_edict_area = (pr_type_t *)((byte *) pr->progs + pr->progs_size);
pr->zone = (memzone_t *)(&pr->pr_edict_area[pr->pr_edict_area_size]);
pr->pr_functions =
(dfunction_t *) (base + pr->progs->ofs_functions);
pr->pr_functions = (dfunction_t *) (base + pr->progs->ofs_functions);
pr->pr_strings = (char *) base + pr->progs->ofs_strings;
pr->pr_stringsize = (char *) pr->zone + pr->zone_size - (char *) base;
pr->pr_globaldefs = (ddef_t *) (base + pr->progs->ofs_globaldefs);

View file

@ -139,7 +139,7 @@ ED_EntityDict (progs_t *pr, edict_t *ed)
if (name[strlen (name) - 2] == '_')
continue; // skip _x, _y, _z vars
v = &ed->v[d->ofs];
v = &E_fld (ed, d->ofs);
// if the value is still all 0, skip the field
type = d->type & ~DEF_SAVEGLOBAL;
@ -418,7 +418,7 @@ ED_InitEntity (progs_t *pr, plitem_t *entity, edict_t *ent)
continue;
}
} else {
if (!ED_ParseEpair (pr, ent->v, field, value))
if (!ED_ParseEpair (pr, &E_fld (ent, 0), field, value))
PR_Error (pr, "ED_InitEntity: parse error");
}
init = 1;
@ -439,7 +439,7 @@ ED_SpawnEntities (progs_t *pr, plitem_t *entity_list)
int count;
const char *classname;
dfunction_t *func;
pr_int_t max_edicts = pr->pr_edictareasize / pr->pr_edict_size;
pr_int_t max_edicts = pr->pr_edict_area_size / pr->pr_edict_size;
max_edicts -= *pr->num_edicts;
count = PL_A_NumObjects (entity_list);

View file

@ -306,7 +306,7 @@ PF_Find (progs_t *pr)
}
}
RETURN_EDICT (pr, *pr->edicts);
RETURN_EDICT (pr, EDICT_NUM (pr, 0));
}
/*
@ -401,7 +401,7 @@ PF_nextent (progs_t *pr)
while (1) {
i++;
if (i == *pr->num_edicts) {
RETURN_EDICT (pr, *pr->edicts);
RETURN_EDICT (pr, EDICT_NUM (pr, 0));
return;
}
ent = EDICT_NUM (pr, i);
@ -601,7 +601,7 @@ PF_PR_SetField (progs_t *pr)
R_INT (pr) = 0;
if (field)
R_INT (pr) = ED_ParseEpair (pr, ent->v, field, value);
R_INT (pr) = ED_ParseEpair (pr, &E_fld (ent, 0), field, value);
}
static void

View file

@ -700,7 +700,7 @@ Host_Loadgame_f (void)
plitem_t *entity = PL_ObjectAtIndex (list, entnum);
edict_t *ent = EDICT_NUM (&sv_pr_state, entnum);
memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4);
memset (&E_fld (ent, 0), 0, sv_pr_state.progs->entityfields * 4);
ent->free = false;
ED_InitEntity (&sv_pr_state, entity, ent);
@ -989,7 +989,7 @@ Host_Spawn_f (void)
} else {
// set up the edict
ent = host_client->edict;
memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4);
memset (&E_fld (ent, 0), 0, sv_pr_state.progs->entityfields * 4);
SVfloat (ent, colormap) = NUM_FOR_EDICT (&sv_pr_state, ent);
SVfloat (ent, team) = (host_client->colors & 15) + 1;
SVstring (ent, netname) = PR_SetString (&sv_pr_state,

View file

@ -1193,7 +1193,7 @@ SV_SpawnServer (const char *server)
// load the rest of the entities
ent = EDICT_NUM (&sv_pr_state, 0);
memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4);
memset (&E_fld (ent, 0), 0, sv_pr_state.progs->entityfields * 4);
ent->free = false;
SVstring (ent, model) = PR_SetString (&sv_pr_state, sv.worldmodel->name);
SVfloat (ent, modelindex) = 1; // world model

View file

@ -51,6 +51,7 @@ sv_globals_t sv_globals;
sv_funcs_t sv_funcs;
sv_fields_t sv_fields;
edict_t sv_edicts[MAX_EDICTS];
sv_data_t sv_data[MAX_EDICTS];
cvar_t *sv_progs;
@ -448,12 +449,32 @@ resolve (progs_t *pr)
return ret;
}
static int
sv_init_edicts (progs_t *pr)
{
int i;
memset (sv_edicts, 0, sizeof (sv_edicts));
memset (sv_data, 0, sizeof (sv_data));
// init the data field of the edicts
for (i = 0; i < sv.max_edicts; i++) {
edict_t *ent = EDICT_NUM (&sv_pr_state, i);
ent->pr = &sv_pr_state;
ent->entnum = i;
ent->edict = EDICT_TO_PROG (&sv_pr_state, ent);
ent->edata = &sv_data[i];
SVdata (ent)->edict = ent;
}
return 1;
}
void
SV_LoadProgs (void)
{
const char *progs_name = "progs.dat";
const char *range;
int i;
if (strequal (sv_progs_ext->string, "qf")) {
sv_range = PR_RANGE_QF;
@ -475,27 +496,18 @@ SV_LoadProgs (void)
if (*sv_progs->string)
progs_name = sv_progs->string;
sv.edicts = sv_edicts;
PR_LoadProgs (&sv_pr_state, progs_name, sv.max_edicts,
sv_progs_zone->int_val * 1024);
if (!sv_pr_state.progs)
Host_Error ("SV_LoadProgs: couldn't load %s", progs_name);
memset (sv_data, 0, sizeof (sv_data));
// init the data field of the edicts
for (i = 0; i < sv.max_edicts; i++) {
edict_t *ent = EDICT_NUM (&sv_pr_state, i);
ent->entnum = i;
ent->edata = &sv_data[i];
SVdata (ent)->edict = ent;
}
}
void
SV_Progs_Init (void)
{
pr_gametype = "netquake";
sv_pr_state.edicts = &sv.edicts;
sv_pr_state.pr_edicts = &sv.edicts;
sv_pr_state.num_edicts = &sv.num_edicts;
sv_pr_state.reserved_edicts = &svs.maxclients;
sv_pr_state.unlink = SV_UnlinkEdict;
@ -504,6 +516,8 @@ SV_Progs_Init (void)
sv_pr_state.bi_map = bi_map;
sv_pr_state.resolve = resolve;
PR_AddLoadFunc (&sv_pr_state, sv_init_edicts);
SV_PR_Cmds_Init ();
Cmd_AddCommand ("edict", ED_PrintEdict_f, "Report information on a given "

View file

@ -53,6 +53,7 @@ sv_globals_t sv_globals;
sv_funcs_t sv_funcs;
sv_fields_t sv_fields;
edict_t sv_edicts[MAX_EDICTS];
sv_data_t sv_data[MAX_EDICTS];
cvar_t *r_skyname;
@ -92,16 +93,16 @@ static void
free_edict (progs_t *pr, edict_t *ent)
{
if (sv_old_entity_free->int_val) {
ent->v[sv_fields.model].entity_var = 0;
ent->v[sv_fields.takedamage].float_var = 0;
ent->v[sv_fields.modelindex].float_var = 0;
ent->v[sv_fields.colormap].float_var = 0;
ent->v[sv_fields.skin].float_var = 0;
ent->v[sv_fields.frame].float_var = 0;
ent->v[sv_fields.nextthink].float_var = -1;
ent->v[sv_fields.solid].float_var = 0;
memset (ent->v[sv_fields.origin].vector_var, 0, 3*sizeof (float));
memset (ent->v[sv_fields.angles].vector_var, 0, 3*sizeof (float));
E_fld (ent, sv_fields.model).entity_var = 0;
E_fld (ent, sv_fields.takedamage).float_var = 0;
E_fld (ent, sv_fields.modelindex).float_var = 0;
E_fld (ent, sv_fields.colormap).float_var = 0;
E_fld (ent, sv_fields.skin).float_var = 0;
E_fld (ent, sv_fields.frame).float_var = 0;
E_fld (ent, sv_fields.nextthink).float_var = -1;
E_fld (ent, sv_fields.solid).float_var = 0;
memset (E_fld (ent, sv_fields.origin).vector_var, 0, 3*sizeof (float));
memset (E_fld (ent, sv_fields.angles).vector_var, 0, 3*sizeof (float));
} else {
ED_ClearEdict (pr, ent, 0);
}
@ -481,12 +482,32 @@ resolve (progs_t *pr)
return ret;
}
static int
sv_init_edicts (progs_t *pr)
{
int i;
memset (sv_edicts, 0, sizeof (sv_edicts));
memset (sv_data, 0, sizeof (sv_data));
// init the data field of the edicts
for (i = 0; i < MAX_EDICTS; i++) {
edict_t *ent = EDICT_NUM (&sv_pr_state, i);
ent->pr = &sv_pr_state;
ent->entnum = i;
ent->edict = EDICT_TO_PROG (&sv_pr_state, ent);
ent->edata = &sv_data[i];
SVdata (ent)->edict = ent;
}
return 1;
}
void
SV_LoadProgs (void)
{
const char *progs_name = "qwprogs.dat";
const char *range;
int i;
if (strequal (sv_progs_ext->string, "qf")) {
sv_range = PR_RANGE_QF;
@ -521,27 +542,18 @@ SV_LoadProgs (void)
if (*sv_progs->string)
progs_name = sv_progs->string;
sv.edicts = sv_edicts;
PR_LoadProgs (&sv_pr_state, progs_name, MAX_EDICTS,
sv_progs_zone->int_val * 1024);
if (!sv_pr_state.progs)
Sys_Error ("SV_LoadProgs: couldn't load %s", progs_name);
memset (sv_data, 0, sizeof (sv_data));
// init the data field of the edicts
for (i = 0; i < MAX_EDICTS; i++) {
edict_t *ent = EDICT_NUM (&sv_pr_state, i);
ent->entnum = i;
ent->edata = &sv_data[i];
SVdata (ent)->edict = ent;
}
}
void
SV_Progs_Init (void)
{
pr_gametype = "quakeworld";
sv_pr_state.edicts = &sv.edicts;
sv_pr_state.pr_edicts = &sv.edicts;
sv_pr_state.num_edicts = &sv.num_edicts;
sv_pr_state.reserved_edicts = &reserved_edicts;
sv_pr_state.unlink = SV_UnlinkEdict;
@ -552,6 +564,8 @@ SV_Progs_Init (void)
sv_pr_state.bi_map = bi_map;
sv_pr_state.resolve = resolve;
PR_AddLoadFunc (&sv_pr_state, sv_init_edicts);
SV_PR_Cmds_Init ();
SV_PR_QWE_Init (&sv_pr_state);
SV_PR_CPQW_Init (&sv_pr_state);

View file

@ -376,7 +376,7 @@ SV_Spawn (client_t *client)
// set up the edict
ent = client->edict;
memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4);
memset (&E_fld (ent, 0), 0, sv_pr_state.progs->entityfields * 4);
SVfloat (ent, colormap) = NUM_FOR_EDICT (&sv_pr_state, ent);
SVfloat (ent, team) = 0; // FIXME
SVstring (ent, netname) = PR_SetString (&sv_pr_state, client->name);

View file

@ -238,7 +238,7 @@ init_qf (void)
PR_Init_Cvars ();
PR_Init ();
pr.edicts = &edicts;
pr.pr_edicts = &edicts;
pr.num_edicts = &num_edicts;
pr.reserved_edicts = &reserved_edicts;
pr.file_error = file_error;
@ -267,8 +267,8 @@ convert_qfo (void)
pr.pr_fielddefs = P (ddef_t, ofs_fielddefs);
pr.pr_globals = P (pr_type_t, ofs_globals);
pr.globals_size = pr.progs->numglobals;
pr.pr_edict_size = max (1, pr.progs->entityfields) * 4;
pr.pr_edictareasize = 1 * pr.pr_edict_size;
pr.pr_edict_size = max (1, pr.progs->entityfields);
pr.pr_edict_area_size = 1 * pr.pr_edict_size;
#undef P
if (verbosity) {

View file

@ -138,7 +138,7 @@ init_qf (void)
Cvar_Get ("pr_debug", "2", 0, 0, 0);
Cvar_Get ("pr_boundscheck", "2", 0, 0, 0);
pr.edicts = &edicts;
pr.pr_edicts = &edicts;
pr.num_edicts = &num_edicts;
pr.reserved_edicts = &reserved_edicts;
pr.load_file = load_file;

View file

@ -107,7 +107,7 @@ init_qf (void)
Cvar_Get ("pr_debug", "2", 0, 0, 0);
Cvar_Get ("pr_boundscheck", "0", 0, 0, 0);
pr.edicts = &edicts;
pr.pr_edicts = &edicts;
pr.num_edicts = &num_edicts;
pr.reserved_edicts = &reserved_edicts;
pr.load_file = load_file;

View file

@ -118,7 +118,7 @@ init_qf (void)
Cvar_Get ("pr_debug", "2", 0, 0, 0);
Cvar_Get ("pr_boundscheck", "0", 0, 0, 0);
pr.edicts = &edicts;
pr.pr_edicts = &edicts;
pr.num_edicts = &num_edicts;
pr.reserved_edicts = &reserved_edicts;
pr.load_file = load_file;