diff --git a/include/QF/progs.h b/include/QF/progs.h index 7c8bb3341..5f8661341 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -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; //@} diff --git a/libs/gamecode/pr_debug.c b/libs/gamecode/pr_debug.c index 602a2cc15..3656c2d0f 100644 --- a/libs/gamecode/pr_debug.c +++ b/libs/gamecode/pr_debug.c @@ -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; diff --git a/libs/gamecode/pr_edict.c b/libs/gamecode/pr_edict.c index 2241e3e9f..1e77dee66 100644 --- a/libs/gamecode/pr_edict.c +++ b/libs/gamecode/pr_edict.c @@ -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; diff --git a/libs/gamecode/pr_exec.c b/libs/gamecode/pr_exec.c index 24778dd74..1e995170b 100644 --- a/libs/gamecode/pr_exec.c +++ b/libs/gamecode/pr_exec.c @@ -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; diff --git a/libs/gamecode/pr_load.c b/libs/gamecode/pr_load.c index b32cf71c3..76a84e2a2 100644 --- a/libs/gamecode/pr_load.c +++ b/libs/gamecode/pr_load.c @@ -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); diff --git a/libs/gamecode/pr_parse.c b/libs/gamecode/pr_parse.c index 758e2c4cc..e6900fce9 100644 --- a/libs/gamecode/pr_parse.c +++ b/libs/gamecode/pr_parse.c @@ -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); diff --git a/libs/ruamoko/pr_cmds.c b/libs/ruamoko/pr_cmds.c index 8352228d4..1ce9560d1 100644 --- a/libs/ruamoko/pr_cmds.c +++ b/libs/ruamoko/pr_cmds.c @@ -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 diff --git a/nq/source/host_cmd.c b/nq/source/host_cmd.c index 4a819d66c..76e13fe0e 100644 --- a/nq/source/host_cmd.c +++ b/nq/source/host_cmd.c @@ -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, diff --git a/nq/source/sv_main.c b/nq/source/sv_main.c index d06ec4543..acaccd765 100644 --- a/nq/source/sv_main.c +++ b/nq/source/sv_main.c @@ -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 diff --git a/nq/source/sv_progs.c b/nq/source/sv_progs.c index ca80ae190..6e0b5f7d1 100644 --- a/nq/source/sv_progs.c +++ b/nq/source/sv_progs.c @@ -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 " diff --git a/qw/source/sv_progs.c b/qw/source/sv_progs.c index e11805c17..048961186 100644 --- a/qw/source/sv_progs.c +++ b/qw/source/sv_progs.c @@ -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); diff --git a/qw/source/sv_user.c b/qw/source/sv_user.c index 608b44480..4505b3921 100644 --- a/qw/source/sv_user.c +++ b/qw/source/sv_user.c @@ -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); diff --git a/tools/qfcc/source/qfprogs.c b/tools/qfcc/source/qfprogs.c index d6bf84927..7063d1805 100644 --- a/tools/qfcc/source/qfprogs.c +++ b/tools/qfcc/source/qfprogs.c @@ -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) { diff --git a/tools/qfcc/test/test-harness.c b/tools/qfcc/test/test-harness.c index eff3ff9a4..061b03d4c 100644 --- a/tools/qfcc/test/test-harness.c +++ b/tools/qfcc/test/test-harness.c @@ -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; diff --git a/tools/qwaq/main.c b/tools/qwaq/main.c index edb7c0229..78788dded 100644 --- a/tools/qwaq/main.c +++ b/tools/qwaq/main.c @@ -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; diff --git a/tools/qwaq/qwaq.c b/tools/qwaq/qwaq.c index f1197ccfb..a69c393ae 100644 --- a/tools/qwaq/qwaq.c +++ b/tools/qwaq/qwaq.c @@ -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;