protocol: Use combined entity state structure

This commit is contained in:
Denis Pauk 2024-12-08 21:29:43 +02:00
parent d4b4266758
commit 032b66b062
16 changed files with 121 additions and 68 deletions

View file

@ -778,7 +778,7 @@ CL_AddMuzzleFlash2(void)
}
void
CL_TeleporterParticles(entity_state_t *ent)
CL_TeleporterParticles(const entity_xstate_t *ent)
{
int i, j;
cparticle_t *p;
@ -2046,7 +2046,7 @@ CL_TeleportParticles(vec3_t org)
extern struct sfx_s *cl_sfx_footsteps[4];
void
CL_EntityEvent(entity_state_t *ent)
CL_EntityEvent(entity_xstate_t *ent)
{
switch (ent->event)
{

View file

@ -32,14 +32,9 @@ extern struct model_s *cl_mod_powerscreen;
void
CL_AddPacketEntities(frame_t *frame)
{
entity_t ent = {0};
entity_state_t *s1;
float autorotate, autobob;
int i;
int pnum;
centity_t *cent;
int autoanim;
clientinfo_t *ci;
int pnum;
/* To distinguish baseq2, xatrix and rogue. */
cvar_t *gametype = Cvar_Get("gametype", "", CVAR_LATCH | CVAR_SERVERINFO);
@ -54,6 +49,11 @@ CL_AddPacketEntities(frame_t *frame)
for (pnum = 0; pnum < frame->num_entities; pnum++)
{
unsigned int effects, renderfx, rr_effects;
entity_xstate_t *s1;
entity_t ent = {0};
clientinfo_t *ci;
centity_t *cent;
int i;
s1 = &cl_parse_entities[(frame->parse_entities +
pnum) & (MAX_PARSE_ENTITIES - 1)];

View file

@ -88,7 +88,7 @@ client_state_t cl;
centity_t cl_entities[MAX_EDICTS];
entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES];
entity_xstate_t cl_parse_entities[MAX_PARSE_ENTITIES];
/*Evil hack against too many power screen and power
shield impact sounds. For example if the player
@ -156,8 +156,8 @@ CL_Record_f(void)
sizebuf_t buf;
int i;
int len;
entity_state_t *ent;
entity_state_t nullstate;
entity_xstate_t *ent;
entity_xstate_t nullstate;
if (Cmd_Argc() != 2)
{

View file

@ -135,7 +135,7 @@ CL_ParseEntityBits(unsigned *bits)
* Can go from either a baseline or a previous packet_entity
*/
static void
CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits)
CL_ParseDelta(const entity_xstate_t *from, entity_xstate_t *to, int number, int bits)
{
/* set everything to the state we are delta'ing from */
*to = *from;
@ -354,10 +354,10 @@ CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits)
* the current frame
*/
static void
CL_DeltaEntity(frame_t *frame, int newnum, entity_state_t *old, int bits)
CL_DeltaEntity(frame_t *frame, int newnum, entity_xstate_t *old, int bits)
{
centity_t *ent;
entity_state_t *state;
entity_xstate_t *state;
ent = &cl_entities[newnum];
@ -422,8 +422,7 @@ CL_ParsePacketEntities(frame_t *oldframe, frame_t *newframe)
{
unsigned int newnum;
unsigned bits;
entity_state_t
*oldstate = NULL;
entity_xstate_t *oldstate = NULL;
int oldindex, oldnum;
newframe->parse_entities = cl.parse_entities;
@ -756,11 +755,13 @@ CL_ParsePlayerstate(frame_t *oldframe, frame_t *newframe)
static void
CL_FireEntityEvents(frame_t *frame)
{
entity_state_t *s1;
int pnum, num;
int pnum;
for (pnum = 0; pnum < frame->num_entities; pnum++)
{
entity_xstate_t *s1;
int num;
num = (frame->parse_entities + pnum) & (MAX_PARSE_ENTITIES - 1);
s1 = &cl_parse_entities[num];
@ -1037,10 +1038,10 @@ CL_ParseServerData(void)
static void
CL_ParseBaseline(void)
{
entity_state_t *es;
entity_xstate_t nullstate;
entity_xstate_t *es;
unsigned bits;
int newnum;
entity_state_t nullstate;
memset(&nullstate, 0, sizeof(nullstate));

View file

@ -81,17 +81,19 @@ void
CL_ClipMoveToEntities(vec3_t start, vec3_t mins, vec3_t maxs,
vec3_t end, trace_t *tr)
{
int i, x, zd, zu;
trace_t trace;
int headnode;
float *angles;
entity_state_t *ent;
int num;
cmodel_t *cmodel;
vec3_t bmins, bmaxs;
int i;
for (i = 0; i < cl.frame.num_entities; i++)
{
int x, zd, zu;
trace_t trace;
int headnode;
float *angles;
int num;
cmodel_t *cmodel;
vec3_t bmins, bmaxs;
entity_xstate_t *ent;
num = (cl.frame.parse_entities + i) & (MAX_PARSE_ENTITIES - 1);
ent = &cl_parse_entities[num];
@ -184,15 +186,16 @@ int
CL_PMpointcontents(vec3_t point)
{
int i;
entity_state_t *ent;
int num;
cmodel_t *cmodel;
int contents;
contents = CM_PointContents(point, 0);
for (i = 0; i < cl.frame.num_entities; i++)
{
entity_xstate_t *ent;
int num;
cmodel_t *cmodel;
num = (cl.frame.parse_entities + i) & (MAX_PARSE_ENTITIES - 1);
ent = &cl_parse_entities[num];

View file

@ -72,9 +72,9 @@ typedef struct
typedef struct
{
entity_state_t baseline; /* delta from this if not from a previous frame */
entity_state_t current;
entity_state_t prev; /* will always be valid, but might just be a copy of current */
entity_xstate_t baseline; /* delta from this if not from a previous frame */
entity_xstate_t current;
entity_xstate_t prev; /* will always be valid, but might just be a copy of current */
int serverframe; /* if not current, this ent isn't in the frame */
@ -331,7 +331,7 @@ typedef struct
extern centity_t cl_entities[MAX_EDICTS];
extern entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES];
extern entity_xstate_t cl_parse_entities[MAX_PARSE_ENTITIES];
extern netadr_t net_from;
extern sizebuf_t net_message;
@ -364,7 +364,7 @@ typedef struct cl_sustain
void CL_ParticleSteamEffect2(cl_sustain_t *self);
void CL_TeleporterParticles (entity_state_t *ent);
void CL_TeleporterParticles (const entity_xstate_t *ent);
void CL_ParticleEffect (vec3_t org, vec3_t dir, unsigned int basecolor, unsigned int finalcolor,
int count);
void CL_ParticleEffect2 (vec3_t org, vec3_t dir, unsigned int basecolor, unsigned int finalcolor,
@ -535,7 +535,7 @@ void CL_DiminishingTrail (vec3_t start, vec3_t end, centity_t *old, int flags);
void CL_FlyEffect (centity_t *ent, vec3_t origin);
void CL_BfgParticles (entity_t *ent);
void CL_AddParticles (void);
void CL_EntityEvent (entity_state_t *ent);
void CL_EntityEvent (entity_xstate_t *ent);
void CL_TrapParticles (entity_t *ent);
void M_Init (void);

View file

@ -850,11 +850,6 @@ AL_AddLoopSounds(void)
{
int i;
int sounds[MAX_EDICTS];
channel_t *ch;
sfx_t *sfx;
sfxcache_t *sc;
int num;
entity_state_t *ent;
if ((cls.state != ca_active) || (cl_paused->value && cl_audiopaused->value) || !s_ambient->value)
{
@ -866,6 +861,12 @@ AL_AddLoopSounds(void)
for (i = 0; i < cl.frame.num_entities; i++)
{
channel_t *ch;
sfx_t *sfx;
sfxcache_t *sc;
int num;
entity_xstate_t *ent;
if (!sounds[i])
{
continue;

View file

@ -681,14 +681,8 @@ SDL_Spatialize(channel_t *ch)
void
SDL_AddLoopSounds(void)
{
int i, j;
int i;
int sounds[MAX_EDICTS];
int left, right, left_total, right_total;
channel_t *ch;
sfx_t *sfx;
sfxcache_t *sc;
int num;
entity_state_t *ent;
if ((cls.state != ca_active) || (cl_paused->value && cl_audiopaused->value) ||
!cl.sound_prepped || !s_ambient->value)
@ -701,6 +695,14 @@ SDL_AddLoopSounds(void)
for (i = 0; i < cl.frame.num_entities; i++)
{
int left, right, left_total, right_total;
channel_t *ch;
sfx_t *sfx;
sfxcache_t *sc;
int num;
entity_xstate_t *ent;
int j;
if (!sounds[i])
{
continue;

View file

@ -704,7 +704,7 @@ S_RegisterSound(char *name)
}
static struct sfx_s *
S_RegisterSexedSound(entity_state_t *ent, char *base)
S_RegisterSexedSound(entity_xstate_t *ent, char *base)
{
int n;
struct sfx_s *sfx;
@ -1346,7 +1346,7 @@ S_BuildSoundList(int *sounds)
for (i = 0; i < cl.frame.num_entities; i++)
{
int num;
entity_state_t *ent;
entity_xstate_t *ent;
if (i >= MAX_EDICTS)
{

View file

@ -118,8 +118,8 @@ void MSG_WriteAngle(sizebuf_t *sb, float f);
void MSG_WriteAngle16(sizebuf_t *sb, float f);
void MSG_WriteDeltaUsercmd(sizebuf_t *sb, struct usercmd_s *from,
struct usercmd_s *cmd);
void MSG_WriteDeltaEntity(struct entity_state_s *from,
struct entity_state_s *to, sizebuf_t *msg,
void MSG_WriteDeltaEntity(const struct entity_xstate_s *from,
const struct entity_xstate_s *to, sizebuf_t *msg,
qboolean force, qboolean newentity, int protocol);
void MSG_WriteDir(sizebuf_t *sb, vec3_t vector);

View file

@ -1238,6 +1238,33 @@ typedef struct entity_rrstate_s
unsigned int effects;
} entity_rrstate_t;
typedef struct entity_xstate_s
{
/* keep it insync with entity_state_t */
int number; /* edict index */
vec3_t origin;
vec3_t angles;
vec3_t old_origin; /* for lerping */
int modelindex;
int modelindex2, modelindex3, modelindex4; /* weapons, CTF flags, etc */
int frame;
int skinnum;
unsigned int effects;
int renderfx;
int solid; /* for client side prediction, 8*(bits 0-4) is x/y radius */
/* 8*(bits 5-9) is z down distance, 8(bits10-15) is z up */
/* gi.linkentity sets this properly */
int sound; /* for looping sounds, to guarantee shutoff */
int event; /* impulse events -- muzzle flashes, footsteps, etc */
/* events only go out for a single frame, they */
/* are automatically cleared each frame */
/* New protocol fields, sync with entity_rrstate_t */
vec3_t scale; /* model scale */
unsigned int rreffects;
} entity_xstate_t;
/* ============================================== */
/* player_state_t is the information needed in addition to pmove_state_t

View file

@ -429,8 +429,8 @@ MSG_ReadDir(sizebuf_t *sb, vec3_t dir)
* Can delta from either a baseline or a previous packet_entity
*/
void
MSG_WriteDeltaEntity(entity_state_t *from,
entity_state_t *to,
MSG_WriteDeltaEntity(const entity_xstate_t *from,
const entity_xstate_t *to,
sizebuf_t *msg,
qboolean force,
qboolean newentity,

View file

@ -74,7 +74,7 @@ typedef struct
struct cmodel_s *models[MAX_MODELS];
char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH];
entity_state_t baselines[MAX_EDICTS];
entity_xstate_t baselines[MAX_EDICTS];
/* the multicast buffer is used to send a message to a set of clients
it is only used to marshall data until SV_Multicast is called */
@ -167,7 +167,7 @@ typedef struct
client_t *clients; /* [maxclients->value]; */
int num_client_entities; /* maxclients->value*UPDATE_BACKUP*MAX_PACKET_ENTITIES */
int next_client_entities; /* next client_entity to use */
entity_state_t *client_entities; /* [num_client_entities] */
entity_xstate_t *client_entities; /* [num_client_entities] */
int last_heartbeat;
@ -204,6 +204,7 @@ void SV_DropClient(client_t *drop);
int SV_ModelIndex(const char *name);
int SV_SoundIndex(const char *name);
int SV_ImageIndex(const char *name);
void SV_GetEntityState(const edict_t *svent, entity_xstate_t *state);
void SV_WriteClientdataToMessage(client_t *client, sizebuf_t *msg);

View file

@ -40,11 +40,9 @@ static void
SV_EmitPacketEntities(client_frame_t *from, client_frame_t *to, sizebuf_t *msg,
int protocol)
{
entity_state_t *oldent, *newent;
entity_xstate_t *oldent, *newent;
int oldindex, newindex;
int oldnum, newnum;
int from_num_entities;
int bits;
MSG_WriteByte(msg, svc_packetentities);
@ -64,6 +62,9 @@ SV_EmitPacketEntities(client_frame_t *from, client_frame_t *to, sizebuf_t *msg,
while (newindex < to->num_entities || oldindex < from_num_entities)
{
int oldnum, newnum;
int bits;
if (msg->cursize > MAX_MSGLEN - 150)
{
break;
@ -526,7 +527,6 @@ SV_BuildClientFrame(client_t *client)
edict_t *ent;
edict_t *clent;
client_frame_t *frame;
entity_state_t *state;
int l;
int clientarea, clientcluster;
int leafnum;
@ -571,6 +571,8 @@ SV_BuildClientFrame(client_t *client)
for (e = 1; e < ge->num_edicts; e++)
{
entity_xstate_t *state;
ent = EDICT_NUM(e);
/* ignore ents without visible models */
@ -670,7 +672,7 @@ SV_BuildClientFrame(client_t *client)
ent->s.number = e;
}
*state = ent->s;
SV_GetEntityState(ent, state);
/* don't mark players missiles as solid */
if (ent->owner == client->edict)
@ -692,7 +694,7 @@ SV_RecordDemoMessage(void)
{
int e;
edict_t *ent;
entity_state_t nostate;
entity_xstate_t nostate;
sizebuf_t buf;
byte buf_data[32768];
int len;
@ -722,7 +724,10 @@ SV_RecordDemoMessage(void)
(ent->s.modelindex || ent->s.effects || ent->s.sound ||
ent->s.event) && !(ent->svflags & SVF_NOCLIENT))
{
MSG_WriteDeltaEntity(&nostate, &ent->s, &buf,
entity_xstate_t state;
SV_GetEntityState(ent, &state);
MSG_WriteDeltaEntity(&nostate, &state, &buf,
false, true, PROTOCOL_VERSION);
}

View file

@ -95,6 +95,17 @@ SV_ImageIndex(const char *name)
return SV_FindIndex(name, CS_IMAGES, MAX_IMAGES, true);
}
/*
* Combine entity_state and entity_rrstate_t
*/
void
SV_GetEntityState(const edict_t *svent, entity_xstate_t *state)
{
memcpy(state, &svent->s, sizeof(entity_state_t));
memcpy((byte *)state + sizeof(entity_state_t),
&svent->rrs, sizeof(entity_rrstate_t));
}
/*
* Entity baselines are used to compress the update messages
* to the clients -- only the fields that differ from the
@ -129,7 +140,8 @@ SV_CreateBaseline(void)
Com_Error(ERR_DROP, "%s: bad entity %d >= %d\n",
__func__, entnum, MAX_EDICTS);
}
sv.baselines[entnum] = svent->s;
SV_GetEntityState(svent, &sv.baselines[entnum]);
}
}
@ -463,7 +475,7 @@ SV_InitGame(void)
svs.spawncount = randk();
svs.clients = Z_Malloc(sizeof(client_t) * maxclients->value);
svs.num_client_entities = maxclients->value * UPDATE_BACKUP * 64;
svs.client_entities = Z_Malloc( sizeof(entity_state_t) * svs.num_client_entities);
svs.client_entities = Z_Malloc( sizeof(entity_xstate_t) * svs.num_client_entities);
/* init network stuff */
if (dedicated->value)

View file

@ -186,8 +186,7 @@ static void
SV_Baselines_f(void)
{
int start;
entity_state_t nullstate;
entity_state_t *base;
entity_xstate_t nullstate;
Com_DPrintf("Baselines() from %s\n", sv_client->name);
@ -212,6 +211,8 @@ SV_Baselines_f(void)
while (sv_client->netchan.message.cursize < MAX_MSGLEN / 2 &&
start < MAX_EDICTS)
{
entity_xstate_t *base;
base = &sv.baselines[start];
if (base->modelindex || base->sound || base->effects)