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:
parent
132e25b096
commit
66fda1fddb
16 changed files with 173 additions and 124 deletions
include/QF
libs
nq/source
qw/source
tools
|
@ -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;
|
||||
//@}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 "
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue