Remove non-progs data from edict_t.

All data that is irrelevant to the progs engine itself has been removed
from edict_t and moved into the sv_progs code.
This commit is contained in:
Bill Currie 2010-12-09 14:27:36 +09:00
parent 9deb178e21
commit 3ae2ef8d11
10 changed files with 117 additions and 88 deletions

View file

@ -34,10 +34,10 @@
\image latex vm-mem.eps "VM memory map"
*/
#include "QF/link.h"
#include "QF/pr_comp.h"
#include "QF/pr_debug.h"
#include "QF/quakeio.h"
struct QFile_s;
/** \ingroup progs */
//@{
@ -154,7 +154,7 @@ typedef int pr_load_func_t (progs_t *pr);
So far, 1MB has proven more than sufficient for Quakeword, even when using
Ruamoko objects.
*/
void PR_LoadProgsFile (progs_t *pr, QFile *file, int size, int edicts,
void PR_LoadProgsFile (progs_t *pr, struct QFile_s *file, int size, int edicts,
int zone);
/** Convenience wrapper for PR_LoadProgsFile() and PR_RunLoadFuncs().
@ -215,22 +215,12 @@ void PR_BoundsCheck (progs_t *pr, int addr, etype_t type);
*/
//@{
typedef struct edict_leaf_s {
struct edict_leaf_s *next;
struct mleaf_s *leaf;
} edict_leaf_t;
struct edict_s {
qboolean free;
link_t area; ///< linked to a division node or leaf
edict_leaf_t *leafs;
float freetime; ///< sv.time when the object was freed
void *data; ///< external per-edict data
void *edata; ///< external per-edict data
pr_type_t v[1]; ///< fields from progs
};
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
// pr_edict.c
void ED_ClearEdict (progs_t *pr, edict_t *e, int val);

View file

@ -32,7 +32,10 @@
#ifndef __sv_progs_h
#define __sv_progs_h
#include "QF/link.h"
#include "QF/progs.h"
#include "protocol.h"
#include "sv_pr_cmds.h"
typedef struct {
@ -189,6 +192,8 @@ typedef struct
extern sv_fields_t sv_fields;
extern progs_t sv_pr_state;
#define PR_RANGE_ID 0x0000
#define PR_RANGE_ID_MAX 82
@ -205,7 +210,20 @@ extern sv_fields_t sv_fields;
#define SVvector(e,f) SVFIELD (e, f, vector)
#define SVinteger(e,f) SVFIELD (e, f, integer)
extern progs_t sv_pr_state;
typedef struct edict_leaf_s {
struct edict_leaf_s *next;
struct mleaf_s *leaf;
} edict_leaf_t;
typedef struct sv_data_s {
edict_t *edict;
link_t area; ///< linked to a division node or leaf
edict_leaf_t *leafs;
entity_state_t state;
} sv_data_t;
#define SVdata(e) ((sv_data_t *) ((e)->edata))
#define EDICT_FROM_AREA(l) (STRUCT_FROM_LINK(l,sv_data_t,area)->edict)
static inline void
sv_pr_touch (edict_t *self, edict_t *other)

View file

@ -51,8 +51,6 @@ char localmodels[MAX_MODELS][5]; // inline model names for precache
int sv_protocol = PROTOCOL_FITZQUAKE;
entity_state_t baselines[MAX_EDICTS];
static void
SV_Protocol_f (void)
{
@ -452,7 +450,7 @@ SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg)
// send over all entities (excpet the client) that touch the pvs
ent = NEXT_EDICT (&sv_pr_state, sv.edicts);
for (e = 1; e < sv.num_edicts; e++, ent = NEXT_EDICT (&sv_pr_state, ent)) {
baseline = (entity_state_t*) ent->data;
baseline = &SVdata (ent)->state;
// ignore if not touching a PV leaf
if (ent != clent) { // clent is ALWAYS sent
@ -466,7 +464,7 @@ SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg)
&& (int) SVfloat (ent, modelindex) & 0xFF00)
continue;
for (el = ent->leafs; el; el = el->next) {
for (el = SVdata (ent)->leafs; el; el = el->next) {
unsigned leafnum = el->leaf - sv.worldmodel->leafs - 1;
if (pvs[leafnum >> 3] & (1 << (leafnum & 7)))
break;
@ -972,7 +970,7 @@ SV_CreateBaseline (void)
for (entnum = 0; entnum < sv.num_edicts; entnum++) {
// get the current server version
svent = EDICT_NUM (&sv_pr_state, entnum);
baseline = (entity_state_t *) svent->data;
baseline = &SVdata (svent)->state;
if (svent->free)
continue;
@ -1144,12 +1142,6 @@ SV_SpawnServer (const char *server)
SV_LoadProgs ();
SV_FreeAllEdictLeafs ();
// init the data field of the edicts
for (i = 0; i < sv.max_edicts; i++) {
ent = EDICT_NUM (&sv_pr_state, i);
ent->data = &baselines[i];
}
sv.datagram.maxsize = sizeof (sv.datagram_buf);
sv.datagram.cursize = 0;
sv.datagram.data = sv.datagram_buf;

View file

@ -54,6 +54,8 @@ sv_globals_t sv_globals;
sv_funcs_t sv_funcs;
sv_fields_t sv_fields;
sv_data_t sv_data[MAX_EDICTS];
cvar_t *sv_progs;
cvar_t *sv_progs_zone;
cvar_t *sv_progs_ext;
@ -473,6 +475,7 @@ 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;
@ -498,6 +501,13 @@ SV_LoadProgs (void)
sv_progs_zone->int_val * 1024);
if (!sv_pr_state.progs)
Host_Error ("SV_LoadProgs: couldn't load %s", progs_name);
// 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->edata = &sv_data[i];
SVdata (ent)->edict = ent;
}
}
void

View file

@ -351,14 +351,14 @@ link_t **sv_link_prev;
void
SV_UnlinkEdict (edict_t *ent)
{
if (!ent->area.prev)
if (!SVdata (ent)->area.prev)
return; // not linked in anywhere
RemoveLink (&ent->area);
if (sv_link_next && *sv_link_next == &ent->area)
*sv_link_next = ent->area.next;
if (sv_link_prev && *sv_link_prev == &ent->area)
*sv_link_prev = ent->area.prev;
ent->area.prev = ent->area.next = NULL;
RemoveLink (&SVdata (ent)->area);
if (sv_link_next && *sv_link_next == &SVdata (ent)->area)
*sv_link_next = SVdata (ent)->area.next;
if (sv_link_prev && *sv_link_prev == &SVdata (ent)->area)
*sv_link_prev = SVdata (ent)->area.prev;
SVdata (ent)->area.prev = SVdata (ent)->area.next = NULL;
}
static void
@ -424,8 +424,8 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
edict_leaf = alloc_edict_leaf ();
edict_leaf->leaf = leaf;
edict_leaf->next = ent->leafs;
ent->leafs = edict_leaf;
edict_leaf->next = SVdata (ent)->leafs;
SVdata (ent)->leafs = edict_leaf;
return;
}
@ -447,7 +447,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
{
areanode_t *node;
if (ent->area.prev)
if (SVdata (ent)->area.prev)
SV_UnlinkEdict (ent); // unlink from old position
if (ent == sv.edicts)
@ -479,7 +479,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
}
// link to PVS leafs
free_edict_leafs (&ent->leafs);
free_edict_leafs (&SVdata (ent)->leafs);
if (SVfloat (ent, modelindex))
SV_FindTouchedLeafs (ent, sv.worldmodel->nodes);
@ -501,9 +501,9 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
// link it in
if (SVfloat (ent, solid) == SOLID_TRIGGER)
InsertLinkBefore (&ent->area, &node->trigger_edicts);
InsertLinkBefore (&SVdata (ent)->area, &node->trigger_edicts);
else
InsertLinkBefore (&ent->area, &node->solid_edicts);
InsertLinkBefore (&SVdata (ent)->area, &node->solid_edicts);
// if touch_triggers, touch all entities at this node and descend for more
if (touch_triggers)

View file

@ -32,7 +32,10 @@
#ifndef __sv_progs_h
#define __sv_progs_h
#include "QF/link.h"
#include "QF/progs.h"
#include "qw/protocol.h"
#include "sv_pr_cmds.h"
typedef struct {
@ -174,7 +177,7 @@ typedef struct
extern sv_fields_t sv_fields;
extern struct progs_s sv_pr_state;
extern progs_t sv_pr_state;
#define PR_RANGE_ID 0x0000
#define PR_RANGE_ID_MAX 82
@ -194,7 +197,20 @@ extern struct progs_s sv_pr_state;
#define SVvector(e,f) SVFIELD (e, f, vector)
#define SVinteger(e,f) SVFIELD (e, f, integer)
#define PROGHEADER_CRC 54730
typedef struct edict_leaf_s {
struct edict_leaf_s *next;
struct mleaf_s *leaf;
} edict_leaf_t;
typedef struct sv_data_s {
edict_t *edict;
link_t area; ///< linked to a division node or leaf
edict_leaf_t *leafs;
entity_state_t state;
} sv_data_t;
#define SVdata(e) ((sv_data_t *) ((e)->edata))
#define EDICT_FROM_AREA(l) (STRUCT_FROM_LINK(l,sv_data_t,area)->edict)
static inline void
sv_pr_touch (edict_t *self, edict_t *other)

View file

@ -377,8 +377,8 @@ SV_EmitPacketEntities (delta_t *delta, packet_entities_t *to, sizebuf_t *msg,
}
ent = EDICT_NUM (&sv_pr_state, newnum);
// SV_Printf ("baseline %i\n", newnum);
SV_WriteDelta (ent->data, &to->entities[newindex], msg, true,
stdver);
SV_WriteDelta (&SVdata (ent)->state, &to->entities[newindex], msg,
true, stdver);
newindex++;
continue;
}
@ -615,7 +615,7 @@ SV_WritePlayersToClient (delta_t *delta, byte *pvs, sizebuf_t *msg)
if (pvs) {
// ignore if not touching a PV leaf
for (el = ent->leafs; el; el = el->next) {
for (el = SVdata (ent)->leafs; el; el = el->next) {
unsigned leafnum = el->leaf - sv.worldmodel->leafs - 1;
if (pvs[leafnum >> 3] & (1 << (leafnum & 7)))
break;
@ -804,7 +804,7 @@ SV_WriteEntitiesToClient (delta_t *delta, sizebuf_t *msg)
if (pvs) {
// ignore if not touching a PV leaf
for (el = ent->leafs; el; el = el->next) {
for (el = SVdata (ent)->leafs; el; el = el->next) {
unsigned leafnum = el->leaf - sv.worldmodel->leafs - 1;
if (pvs[leafnum >> 3] & (1 << (leafnum & 7)))
break;

View file

@ -58,8 +58,6 @@ static __attribute__ ((used)) const char rcsid[] =
info_t *localinfo; // local game info
char localmodels[MAX_MODELS][5]; // inline model names for precache
entity_state_t baselines[MAX_EDICTS];
server_t sv; // local server
@ -122,28 +120,26 @@ SV_CreateBaseline (void)
continue;
// create entity baseline
VectorCopy (SVvector (svent, origin),
((entity_state_t*)svent->data)->origin);
VectorCopy (SVvector (svent, angles),
((entity_state_t*)svent->data)->angles);
((entity_state_t*)svent->data)->frame = SVfloat (svent, frame);
((entity_state_t*)svent->data)->skinnum = SVfloat (svent, skin);
VectorCopy (SVvector (svent, origin), SVdata (svent)->state.origin);
VectorCopy (SVvector (svent, angles), SVdata (svent)->state.angles);
SVdata (svent)->state.frame = SVfloat (svent, frame);
SVdata (svent)->state.skinnum = SVfloat (svent, skin);
if (entnum > 0 && entnum <= MAX_CLIENTS) {
((entity_state_t*)svent->data)->colormap = entnum;
((entity_state_t*)svent->data)->modelindex = SV_ModelIndex
SVdata (svent)->state.colormap = entnum;
SVdata (svent)->state.modelindex = SV_ModelIndex
("progs/player.mdl");
} else {
((entity_state_t*)svent->data)->colormap = 0;
((entity_state_t*)svent->data)->modelindex =
SVdata (svent)->state.colormap = 0;
SVdata (svent)->state.modelindex =
SV_ModelIndex (PR_GetString (&sv_pr_state,
SVstring (svent, model)));
}
// LordHavoc: setup baseline to include new effects
((entity_state_t*)svent->data)->alpha = 255;
((entity_state_t*)svent->data)->scale = 16;
((entity_state_t*)svent->data)->glow_size = 0;
((entity_state_t*)svent->data)->glow_color = 254;
((entity_state_t*)svent->data)->colormod = 255;
SVdata (svent)->state.alpha = 255;
SVdata (svent)->state.scale = 16;
SVdata (svent)->state.glow_size = 0;
SVdata (svent)->state.glow_color = 254;
SVdata (svent)->state.colormod = 255;
// flush the signon message out to a separate buffer if nearly full
SV_FlushSignon ();
@ -152,14 +148,13 @@ SV_CreateBaseline (void)
MSG_WriteByte (&sv.signon, svc_spawnbaseline);
MSG_WriteShort (&sv.signon, entnum);
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->modelindex);
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->frame);
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->colormap);
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->skinnum);
MSG_WriteByte (&sv.signon, SVdata (svent)->state.modelindex);
MSG_WriteByte (&sv.signon, SVdata (svent)->state.frame);
MSG_WriteByte (&sv.signon, SVdata (svent)->state.colormap);
MSG_WriteByte (&sv.signon, SVdata (svent)->state.skinnum);
MSG_WriteCoordAngleV (&sv.signon,
((entity_state_t*)svent->data)->origin,
((entity_state_t*)svent->data)->angles);
MSG_WriteCoordAngleV (&sv.signon, SVdata (svent)->state.origin,
SVdata (svent)->state.angles);
}
}
@ -355,12 +350,6 @@ SV_SpawnServer (const char *server)
Info_SetValueForStarKey (svs.info, "*progs", va ("%i", sv_pr_state.crc),
!sv_highchars->int_val);
// init the data field of the edicts
for (i = 0; i < MAX_EDICTS; i++) {
ent = EDICT_NUM (&sv_pr_state, i);
ent->data = &baselines[i];
}
// leave slots at start for only clients
sv.num_edicts = MAX_CLIENTS + 1;
for (i = 0; i < MAX_CLIENTS; i++) {

View file

@ -27,6 +27,10 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((used)) const char rcsid[] =
"$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
@ -52,6 +56,8 @@ sv_globals_t sv_globals;
sv_funcs_t sv_funcs;
sv_fields_t sv_fields;
sv_data_t sv_data[MAX_EDICTS];
cvar_t *r_skyname;
cvar_t *sv_progs;
cvar_t *sv_progs_zone;
@ -480,6 +486,7 @@ 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;
@ -515,6 +522,13 @@ SV_LoadProgs (void)
sv_progs_zone->int_val * 1024);
if (!sv_pr_state.progs)
Sys_Error ("SV_LoadProgs: couldn't load %s", progs_name);
// init the data field of the edicts
for (i = 0; i < MAX_EDICTS; i++) {
edict_t *ent = EDICT_NUM (&sv_pr_state, i);
ent->edata = &sv_data[i];
SVdata (ent)->edict = ent;
}
}
void

View file

@ -351,14 +351,14 @@ link_t **sv_link_prev;
void
SV_UnlinkEdict (edict_t *ent)
{
if (!ent->area.prev)
if (!SVdata (ent)->area.prev)
return; // not linked in anywhere
RemoveLink (&ent->area);
if (sv_link_next && *sv_link_next == &ent->area)
*sv_link_next = ent->area.next;
if (sv_link_prev && *sv_link_prev == &ent->area)
*sv_link_prev = ent->area.prev;
ent->area.prev = ent->area.next = NULL;
RemoveLink (&SVdata (ent)->area);
if (sv_link_next && *sv_link_next == &SVdata (ent)->area)
*sv_link_next = SVdata (ent)->area.next;
if (sv_link_prev && *sv_link_prev == &SVdata (ent)->area)
*sv_link_prev = SVdata (ent)->area.prev;
SVdata (ent)->area.prev = SVdata (ent)->area.next = NULL;
}
static void
@ -424,8 +424,8 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
edict_leaf = alloc_edict_leaf ();
edict_leaf->leaf = leaf;
edict_leaf->next = ent->leafs;
ent->leafs = edict_leaf;
edict_leaf->next = SVdata (ent)->leafs;
SVdata (ent)->leafs = edict_leaf;
return;
}
@ -447,7 +447,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
{
areanode_t *node;
if (ent->area.prev)
if (SVdata (ent)->area.prev)
SV_UnlinkEdict (ent); // unlink from old position
if (ent == sv.edicts)
@ -479,7 +479,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
}
// link to PVS leafs
free_edict_leafs (&ent->leafs);
free_edict_leafs (&SVdata (ent)->leafs);
if (SVfloat (ent, modelindex))
SV_FindTouchedLeafs (ent, sv.worldmodel->nodes);
@ -501,9 +501,9 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
// link it in
if (SVfloat (ent, solid) == SOLID_TRIGGER)
InsertLinkBefore (&ent->area, &node->trigger_edicts);
InsertLinkBefore (&SVdata (ent)->area, &node->trigger_edicts);
else
InsertLinkBefore (&ent->area, &node->solid_edicts);
InsertLinkBefore (&SVdata (ent)->area, &node->solid_edicts);
// if touch_triggers, touch all entities at this node and descend for more
if (touch_triggers)