Nuke cl_entity_state_t.

It was a hack to help with cleaning up the renderer, but is now in the way
of merging the clients.

This happens to fix the position/angle lerping, though angles behave a
little oddly.
This commit is contained in:
Bill Currie 2012-06-26 15:12:17 +09:00
parent 6e5bc62f78
commit f962db1820
3 changed files with 406 additions and 175 deletions

View file

@ -160,6 +160,7 @@ typedef struct {
// server each frame. The server sets punchangle when the view is temporarily // server each frame. The server sets punchangle when the view is temporarily
// offset, and an angle reset commands at the start of each level and after // offset, and an angle reset commands at the start of each level and after
// teleporting. // teleporting.
int mindex;
vec3_t mviewangles[2]; // During demo playback viewangles is lerped vec3_t mviewangles[2]; // During demo playback viewangles is lerped
// between these // between these
vec3_t viewangles; vec3_t viewangles;
@ -227,25 +228,6 @@ typedef struct {
lightstyle_t lightstyle[MAX_LIGHTSTYLES]; lightstyle_t lightstyle[MAX_LIGHTSTYLES];
} client_state_t; } client_state_t;
typedef struct cl_entity_state_s {
entity_t *ent;
entity_state_t baseline;
int forcelink;
vec3_t msg_origins[2];
vec3_t msg_angles[2];
double msgtime;
int effects;
struct model_s *model;
int skinnum;
byte alpha;
byte scale;
byte colormod;
byte glow_size;
byte glow_color;
} cl_entity_state_t;
// cvars // cvars
extern struct cvar_s *cl_name; extern struct cvar_s *cl_name;
extern struct cvar_s *cl_color; extern struct cvar_s *cl_color;
@ -291,7 +273,10 @@ extern client_state_t cl;
// FIXME, allocate dynamically // FIXME, allocate dynamically
extern entity_t cl_entities[MAX_EDICTS]; extern entity_t cl_entities[MAX_EDICTS];
extern cl_entity_state_t cl_baselines[MAX_EDICTS]; extern entity_state_t cl_entity_states[3][MAX_EDICTS];
extern double cl_msgtime[MAX_EDICTS];
extern byte cl_forcelink[MAX_EDICTS];
extern vec3_t ent_colormod[256];
extern int fps_count; extern int fps_count;

View file

@ -51,10 +51,269 @@
#include "host.h" #include "host.h"
#include "server.h" #include "server.h"
// FIXME: put these on hunk?
entity_t cl_entities[MAX_EDICTS]; entity_t cl_entities[MAX_EDICTS];
cl_entity_state_t cl_baselines[MAX_EDICTS]; entity_state_t cl_entity_states[3][MAX_EDICTS];
double cl_msgtime[MAX_EDICTS];
byte cl_forcelink[MAX_EDICTS];
vec3_t ent_colormod[256] = {
{0, 0, 0},
{0, 0, 0.333333},
{0, 0, 0.666667},
{0, 0, 1},
{0, 0.142857, 0},
{0, 0.142857, 0.333333},
{0, 0.142857, 0.666667},
{0, 0.142857, 1},
{0, 0.285714, 0},
{0, 0.285714, 0.333333},
{0, 0.285714, 0.666667},
{0, 0.285714, 1},
{0, 0.428571, 0},
{0, 0.428571, 0.333333},
{0, 0.428571, 0.666667},
{0, 0.428571, 1},
{0, 0.571429, 0},
{0, 0.571429, 0.333333},
{0, 0.571429, 0.666667},
{0, 0.571429, 1},
{0, 0.714286, 0},
{0, 0.714286, 0.333333},
{0, 0.714286, 0.666667},
{0, 0.714286, 1},
{0, 0.857143, 0},
{0, 0.857143, 0.333333},
{0, 0.857143, 0.666667},
{0, 0.857143, 1},
{0, 1, 0},
{0, 1, 0.333333},
{0, 1, 0.666667},
{0, 1, 1},
{0.142857, 0, 0},
{0.142857, 0, 0.333333},
{0.142857, 0, 0.666667},
{0.142857, 0, 1},
{0.142857, 0.142857, 0},
{0.142857, 0.142857, 0.333333},
{0.142857, 0.142857, 0.666667},
{0.142857, 0.142857, 1},
{0.142857, 0.285714, 0},
{0.142857, 0.285714, 0.333333},
{0.142857, 0.285714, 0.666667},
{0.142857, 0.285714, 1},
{0.142857, 0.428571, 0},
{0.142857, 0.428571, 0.333333},
{0.142857, 0.428571, 0.666667},
{0.142857, 0.428571, 1},
{0.142857, 0.571429, 0},
{0.142857, 0.571429, 0.333333},
{0.142857, 0.571429, 0.666667},
{0.142857, 0.571429, 1},
{0.142857, 0.714286, 0},
{0.142857, 0.714286, 0.333333},
{0.142857, 0.714286, 0.666667},
{0.142857, 0.714286, 1},
{0.142857, 0.857143, 0},
{0.142857, 0.857143, 0.333333},
{0.142857, 0.857143, 0.666667},
{0.142857, 0.857143, 1},
{0.142857, 1, 0},
{0.142857, 1, 0.333333},
{0.142857, 1, 0.666667},
{0.142857, 1, 1},
{0.285714, 0, 0},
{0.285714, 0, 0.333333},
{0.285714, 0, 0.666667},
{0.285714, 0, 1},
{0.285714, 0.142857, 0},
{0.285714, 0.142857, 0.333333},
{0.285714, 0.142857, 0.666667},
{0.285714, 0.142857, 1},
{0.285714, 0.285714, 0},
{0.285714, 0.285714, 0.333333},
{0.285714, 0.285714, 0.666667},
{0.285714, 0.285714, 1},
{0.285714, 0.428571, 0},
{0.285714, 0.428571, 0.333333},
{0.285714, 0.428571, 0.666667},
{0.285714, 0.428571, 1},
{0.285714, 0.571429, 0},
{0.285714, 0.571429, 0.333333},
{0.285714, 0.571429, 0.666667},
{0.285714, 0.571429, 1},
{0.285714, 0.714286, 0},
{0.285714, 0.714286, 0.333333},
{0.285714, 0.714286, 0.666667},
{0.285714, 0.714286, 1},
{0.285714, 0.857143, 0},
{0.285714, 0.857143, 0.333333},
{0.285714, 0.857143, 0.666667},
{0.285714, 0.857143, 1},
{0.285714, 1, 0},
{0.285714, 1, 0.333333},
{0.285714, 1, 0.666667},
{0.285714, 1, 1},
{0.428571, 0, 0},
{0.428571, 0, 0.333333},
{0.428571, 0, 0.666667},
{0.428571, 0, 1},
{0.428571, 0.142857, 0},
{0.428571, 0.142857, 0.333333},
{0.428571, 0.142857, 0.666667},
{0.428571, 0.142857, 1},
{0.428571, 0.285714, 0},
{0.428571, 0.285714, 0.333333},
{0.428571, 0.285714, 0.666667},
{0.428571, 0.285714, 1},
{0.428571, 0.428571, 0},
{0.428571, 0.428571, 0.333333},
{0.428571, 0.428571, 0.666667},
{0.428571, 0.428571, 1},
{0.428571, 0.571429, 0},
{0.428571, 0.571429, 0.333333},
{0.428571, 0.571429, 0.666667},
{0.428571, 0.571429, 1},
{0.428571, 0.714286, 0},
{0.428571, 0.714286, 0.333333},
{0.428571, 0.714286, 0.666667},
{0.428571, 0.714286, 1},
{0.428571, 0.857143, 0},
{0.428571, 0.857143, 0.333333},
{0.428571, 0.857143, 0.666667},
{0.428571, 0.857143, 1},
{0.428571, 1, 0},
{0.428571, 1, 0.333333},
{0.428571, 1, 0.666667},
{0.428571, 1, 1},
{0.571429, 0, 0},
{0.571429, 0, 0.333333},
{0.571429, 0, 0.666667},
{0.571429, 0, 1},
{0.571429, 0.142857, 0},
{0.571429, 0.142857, 0.333333},
{0.571429, 0.142857, 0.666667},
{0.571429, 0.142857, 1},
{0.571429, 0.285714, 0},
{0.571429, 0.285714, 0.333333},
{0.571429, 0.285714, 0.666667},
{0.571429, 0.285714, 1},
{0.571429, 0.428571, 0},
{0.571429, 0.428571, 0.333333},
{0.571429, 0.428571, 0.666667},
{0.571429, 0.428571, 1},
{0.571429, 0.571429, 0},
{0.571429, 0.571429, 0.333333},
{0.571429, 0.571429, 0.666667},
{0.571429, 0.571429, 1},
{0.571429, 0.714286, 0},
{0.571429, 0.714286, 0.333333},
{0.571429, 0.714286, 0.666667},
{0.571429, 0.714286, 1},
{0.571429, 0.857143, 0},
{0.571429, 0.857143, 0.333333},
{0.571429, 0.857143, 0.666667},
{0.571429, 0.857143, 1},
{0.571429, 1, 0},
{0.571429, 1, 0.333333},
{0.571429, 1, 0.666667},
{0.571429, 1, 1},
{0.714286, 0, 0},
{0.714286, 0, 0.333333},
{0.714286, 0, 0.666667},
{0.714286, 0, 1},
{0.714286, 0.142857, 0},
{0.714286, 0.142857, 0.333333},
{0.714286, 0.142857, 0.666667},
{0.714286, 0.142857, 1},
{0.714286, 0.285714, 0},
{0.714286, 0.285714, 0.333333},
{0.714286, 0.285714, 0.666667},
{0.714286, 0.285714, 1},
{0.714286, 0.428571, 0},
{0.714286, 0.428571, 0.333333},
{0.714286, 0.428571, 0.666667},
{0.714286, 0.428571, 1},
{0.714286, 0.571429, 0},
{0.714286, 0.571429, 0.333333},
{0.714286, 0.571429, 0.666667},
{0.714286, 0.571429, 1},
{0.714286, 0.714286, 0},
{0.714286, 0.714286, 0.333333},
{0.714286, 0.714286, 0.666667},
{0.714286, 0.714286, 1},
{0.714286, 0.857143, 0},
{0.714286, 0.857143, 0.333333},
{0.714286, 0.857143, 0.666667},
{0.714286, 0.857143, 1},
{0.714286, 1, 0},
{0.714286, 1, 0.333333},
{0.714286, 1, 0.666667},
{0.714286, 1, 1},
{0.857143, 0, 0},
{0.857143, 0, 0.333333},
{0.857143, 0, 0.666667},
{0.857143, 0, 1},
{0.857143, 0.142857, 0},
{0.857143, 0.142857, 0.333333},
{0.857143, 0.142857, 0.666667},
{0.857143, 0.142857, 1},
{0.857143, 0.285714, 0},
{0.857143, 0.285714, 0.333333},
{0.857143, 0.285714, 0.666667},
{0.857143, 0.285714, 1},
{0.857143, 0.428571, 0},
{0.857143, 0.428571, 0.333333},
{0.857143, 0.428571, 0.666667},
{0.857143, 0.428571, 1},
{0.857143, 0.571429, 0},
{0.857143, 0.571429, 0.333333},
{0.857143, 0.571429, 0.666667},
{0.857143, 0.571429, 1},
{0.857143, 0.714286, 0},
{0.857143, 0.714286, 0.333333},
{0.857143, 0.714286, 0.666667},
{0.857143, 0.714286, 1},
{0.857143, 0.857143, 0},
{0.857143, 0.857143, 0.333333},
{0.857143, 0.857143, 0.666667},
{0.857143, 0.857143, 1},
{0.857143, 1, 0},
{0.857143, 1, 0.333333},
{0.857143, 1, 0.666667},
{0.857143, 1, 1},
{1, 0, 0},
{1, 0, 0.333333},
{1, 0, 0.666667},
{1, 0, 1},
{1, 0.142857, 0},
{1, 0.142857, 0.333333},
{1, 0.142857, 0.666667},
{1, 0.142857, 1},
{1, 0.285714, 0},
{1, 0.285714, 0.333333},
{1, 0.285714, 0.666667},
{1, 0.285714, 1},
{1, 0.428571, 0},
{1, 0.428571, 0.333333},
{1, 0.428571, 0.666667},
{1, 0.428571, 1},
{1, 0.571429, 0},
{1, 0.571429, 0.333333},
{1, 0.571429, 0.666667},
{1, 0.571429, 1},
{1, 0.714286, 0},
{1, 0.714286, 0.333333},
{1, 0.714286, 0.666667},
{1, 0.714286, 1},
{1, 0.857143, 0},
{1, 0.857143, 0.333333},
{1, 0.857143, 0.666667},
{1, 0.857143, 1},
{1, 1, 0},
{1, 1, 0.333333},
{1, 1, 0.666667},
{1, 1, 1}
};
void void
CL_ClearEnts (void) CL_ClearEnts (void)
@ -63,13 +322,13 @@ CL_ClearEnts (void)
// clear other arrays // clear other arrays
memset (cl_entities, 0, sizeof (cl_entities)); memset (cl_entities, 0, sizeof (cl_entities));
memset (cl_baselines, 0, sizeof (cl_baselines)); memset (cl_entity_states, 0, sizeof (cl_entity_states));
memset (cl_msgtime, 0, sizeof (cl_msgtime));
memset (cl_forcelink, 0, sizeof (cl_forcelink));
for (i = 0; i < MAX_EDICTS; i++) { for (i = 0; i < MAX_EDICTS; i++)
cl_baselines[i].ent = &cl_entities[i];
CL_Init_Entity (cl_entities + i); CL_Init_Entity (cl_entities + i);
} }
}
static void static void
CL_NewDlight (int key, vec3_t org, int effects, byte glow_size, CL_NewDlight (int key, vec3_t org, int effects, byte glow_size,
@ -242,7 +501,7 @@ CL_ModelEffects (entity_t *ent, int num, int glow_color)
} }
static void static void
CL_EntityEffects (int num, entity_t *ent, cl_entity_state_t *state) CL_EntityEffects (int num, entity_t *ent, entity_state_t *state)
{ {
dlight_t *dl; dlight_t *dl;
@ -266,11 +525,30 @@ CL_EntityEffects (int num, entity_t *ent, cl_entity_state_t *state)
} }
} }
static void
set_entity_model (entity_t *ent, int modelindex)
{
int i = ent - cl_entities;
ent->model = cl.model_precache[modelindex];
// automatic animation (torches, etc) can be either all together
// or randomized
if (ent->model) {
if (ent->model->synctype == ST_RAND)
ent->syncbase = (float) (rand () & 0x7fff) / 0x7fff;
else
ent->syncbase = 0.0;
} else {
cl_forcelink[i] = true; // hack to make null model players work
}
if (i <= cl.maxclients)
ent->skin = mod_funcs->Skin_SetColormap (ent->skin, i);
}
void void
CL_RelinkEntities (void) CL_RelinkEntities (void)
{ {
entity_t *ent; entity_t *ent;
cl_entity_state_t *state; entity_state_t *new, *old;
float bobjrotate, frac, f, d; float bobjrotate, frac, f, d;
int i, j; int i, j;
vec3_t delta; vec3_t delta;
@ -300,15 +578,12 @@ CL_RelinkEntities (void)
bobjrotate = anglemod (100 * cl.time); bobjrotate = anglemod (100 * cl.time);
// start on the entity after the world // start on the entity after the world
for (i = 1, state = cl_baselines + 1; i < cl.num_entities; i++, state++) { for (i = 1; i < cl.num_entities; i++) {
ent = state->ent; new = &cl_entity_states[1 + cl.mindex][i];
if (!ent->model) { // empty slot old = &cl_entity_states[2 - cl.mindex][i];
if (ent->efrag) ent = &cl_entities[i];
r_funcs->R_RemoveEfrags (ent); // just became empty
continue;
}
// if the object wasn't included in the last packet, remove it // if the object wasn't included in the last packet, remove it
if (state->msgtime != cl.mtime[0]) { if (cl_msgtime[i] != cl.mtime[0] || !new->modelindex) {
ent->model = NULL; ent->model = NULL;
ent->pose1 = ent->pose2 = -1; ent->pose1 = ent->pose2 = -1;
if (ent->efrag) if (ent->efrag)
@ -316,11 +591,32 @@ CL_RelinkEntities (void)
continue; continue;
} }
ent->colormod[3] = ENTALPHA_DECODE (state->alpha); if (cl_forcelink[i] || new->modelindex != old->modelindex) {
old->modelindex = new->modelindex;
set_entity_model (ent, new->modelindex);
}
ent->frame = new->frame;
if (cl_forcelink[i] || new->colormod != old->colormod) {
old->colormod = new->colormod;
ent->skin = mod_funcs->Skin_SetColormap (ent->skin, new->colormod);
}
if (cl_forcelink[i] || new->skinnum != old->skinnum) {
old->skinnum = new->skinnum;
ent->skinnum = new->skinnum;
if (i <= cl.maxclients) {
ent->skin = mod_funcs->Skin_SetColormap (ent->skin, i);
mod_funcs->Skin_SetTranslation (i, cl.scores[i].topcolor,
cl.scores[i].bottomcolor);
}
}
ent->scale = new->scale;
VectorCopy (ent_colormod[new->colormod], ent->colormod);
ent->colormod[3] = ENTALPHA_DECODE (new->alpha);
VectorCopy (ent->origin, ent->old_origin); VectorCopy (ent->origin, ent->old_origin);
if (state->forcelink) { if (cl_forcelink[i]) {
// The entity was not updated in the last message so move to the // The entity was not updated in the last message so move to the
// final spot // final spot
if (i != cl.viewentity || chase_active->int_val) { if (i != cl.viewentity || chase_active->int_val) {
@ -331,29 +627,27 @@ CL_RelinkEntities (void)
} else { } else {
// If the delta is large, assume a teleport and don't lerp // If the delta is large, assume a teleport and don't lerp
f = frac; f = frac;
VectorSubtract (state->msg_origins[0], VectorSubtract (new->origin, old->origin, delta);
state->msg_origins[1], delta);
if (fabs (delta[0]) > 100 || fabs (delta[1] > 100) if (fabs (delta[0]) > 100 || fabs (delta[1] > 100)
|| fabs (delta[2]) > 100) { || fabs (delta[2]) > 100) {
// assume a teleportation, not a motion // assume a teleportation, not a motion
VectorCopy (state->msg_origins[0], ent->origin); VectorCopy (new->origin, ent->origin);
if (!(ent->model->flags & EF_ROTATE)) if (!(ent->model->flags & EF_ROTATE))
CL_TransformEntity (ent, state->msg_angles[0], true); CL_TransformEntity (ent, new->angles, true);
ent->pose1 = ent->pose2 = -1; ent->pose1 = ent->pose2 = -1;
} else { } else {
vec3_t angles, d; vec3_t angles, d;
// interpolate the origin and angles // interpolate the origin and angles
VectorMultAdd (state->msg_origins[1], f, delta, ent->origin); VectorMultAdd (old->origin, f, delta, ent->origin);
if (!(ent->model->flags & EF_ROTATE)) { if (!(ent->model->flags & EF_ROTATE)) {
VectorSubtract (state->msg_angles[0], VectorSubtract (new->angles, old->angles, d);
state->msg_angles[1], d);
for (j = 0; j < 3; j++) { for (j = 0; j < 3; j++) {
if (d[j] > 180) if (d[j] > 180)
d[j] -= 360; d[j] -= 360;
else if (d[j] < -180) else if (d[j] < -180)
d[j] += 360; d[j] += 360;
} }
VectorMultAdd (state->msg_angles[1], f, d, angles); VectorMultAdd (old->angles, f, d, angles);
CL_TransformEntity (ent, angles, false); CL_TransformEntity (ent, angles, false);
} }
} }
@ -372,18 +666,17 @@ CL_RelinkEntities (void)
// rotate binary objects locally // rotate binary objects locally
if (ent->model->flags & EF_ROTATE) { if (ent->model->flags & EF_ROTATE) {
vec3_t angles; vec3_t angles;
VectorCopy (state->msg_angles[0], angles); VectorCopy (new->angles, angles);
angles[YAW] = bobjrotate; angles[YAW] = bobjrotate;
CL_TransformEntity (ent, angles, false); CL_TransformEntity (ent, angles, false);
} }
CL_EntityEffects (i, ent, state); CL_EntityEffects (i, ent, new);
CL_NewDlight (i, ent->origin, state->effects, 0, 0); CL_NewDlight (i, ent->origin, new->effects, 0, 0);
if (VectorDistance_fast (state->msg_origins[1], ent->origin) if (VectorDistance_fast (old->origin, ent->origin) > (256 * 256))
> (256 * 256)) VectorCopy (ent->origin, old->origin);
VectorCopy (ent->origin, state->msg_origins[1]);
if (ent->model->flags & ~EF_ROTATE) if (ent->model->flags & ~EF_ROTATE)
CL_ModelEffects (ent, i, state->glow_color); CL_ModelEffects (ent, i, new->glow_color);
state->forcelink = false; cl_forcelink[i] = false;
} }
} }

View file

@ -144,20 +144,15 @@ CL_LoadSky (void)
This error checks and tracks the total number of entities This error checks and tracks the total number of entities
*/ */
static cl_entity_state_t * static entity_state_t *
CL_EntityNum (int num) CL_EntityNum (int num)
{ {
if (num < 0 || num >= MAX_EDICTS) if (num < 0 || num >= MAX_EDICTS)
Host_Error ("CL_EntityNum: %i is an invalid number", num); Host_Error ("CL_EntityNum: %i is an invalid number", num);
if (num >= cl.num_entities) { if (num >= cl.num_entities)
while (cl.num_entities <= num) { cl.num_entities = num + 1;
cl_baselines[cl.num_entities].ent =
&cl_entities[cl.num_entities];
cl.num_entities++;
}
}
return &cl_baselines[num]; return &cl_entity_states[0][num];
} }
static void static void
@ -460,10 +455,9 @@ int bitcounts[16];
static void static void
CL_ParseUpdate (int bits) CL_ParseUpdate (int bits)
{ {
entity_t *ent; entity_state_t *baseline;
cl_entity_state_t *state; entity_state_t *state;
int modnum, num, skin, i; int modnum, num, i;
model_t *model;
qboolean forcelink; qboolean forcelink;
if (cls.signon == so_begin) { if (cls.signon == so_begin) {
@ -489,94 +483,75 @@ CL_ParseUpdate (int bits)
else else
num = MSG_ReadByte (net_message); num = MSG_ReadByte (net_message);
state = CL_EntityNum (num); baseline = CL_EntityNum (num);
ent = state->ent; state = &cl_entity_states[1 + cl.mindex][num];
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
if (bits & (1 << i)) if (bits & (1 << i))
bitcounts[i]++; bitcounts[i]++;
if (state->msgtime != cl.mtime[1]) if (cl_msgtime[num] != cl.mtime[1])
forcelink = true; // no previous frame to lerp from forcelink = true; // no previous frame to lerp from
else else
forcelink = false; forcelink = false;
if (forcelink) { // FIXME: do this right (ie, protocol support) cl_msgtime[num] = cl.mtime[0];
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] =
ent->colormod[3] = 1.0;
ent->scale = 1.0;
}
state->msgtime = cl.mtime[0];
if (bits & U_MODEL) { if (bits & U_MODEL) {
modnum = MSG_ReadByte (net_message); modnum = MSG_ReadByte (net_message);
if (modnum >= MAX_MODELS) if (modnum >= MAX_MODELS)
Host_Error ("CL_ParseModel: bad modnum"); Host_Error ("CL_ParseModel: bad modnum");
} else } else
modnum = state->baseline.modelindex; modnum = baseline->modelindex;
if (bits & U_FRAME) if (bits & U_FRAME)
ent->frame = MSG_ReadByte (net_message); state->frame = MSG_ReadByte (net_message);
else else
ent->frame = state->baseline.frame; state->frame = baseline->frame;
if (bits & U_COLORMAP) if (bits & U_COLORMAP)
i = MSG_ReadByte (net_message); state->colormap = MSG_ReadByte (net_message);
else else
i = state->baseline.colormap; state->colormap = baseline->colormap;
if (i > cl.maxclients) if (state->colormap > cl.maxclients)
Sys_Error ("i > cl.maxclients"); Sys_Error ("colormap > cl.maxclients");
ent->skin = mod_funcs->Skin_SetColormap (ent->skin, i);
if (bits & U_SKIN) if (bits & U_SKIN)
skin = MSG_ReadByte (net_message); state->skinnum = MSG_ReadByte (net_message);
else else
skin = state->baseline.skinnum; state->skinnum = baseline->skinnum;
if (skin != ent->skinnum) {
ent->skinnum = skin;
if (num <= cl.maxclients) {
ent->skin = mod_funcs->Skin_SetColormap (ent->skin, num);
mod_funcs->Skin_SetTranslation (num, cl.scores[num].topcolor,
cl.scores[num].bottomcolor);
}
}
if (bits & U_EFFECTS) if (bits & U_EFFECTS)
state->effects = MSG_ReadByte (net_message); state->effects = MSG_ReadByte (net_message);
else else
state->effects = state->baseline.effects; state->effects = baseline->effects;
// shift the known values for interpolation
VectorCopy (state->msg_origins[0], state->msg_origins[1]);
VectorCopy (state->msg_angles[0], state->msg_angles[1]);
if (bits & U_ORIGIN1) if (bits & U_ORIGIN1)
state->msg_origins[0][0] = MSG_ReadCoord (net_message); state->origin[0] = MSG_ReadCoord (net_message);
else else
state->msg_origins[0][0] = state->baseline.origin[0]; state->origin[0] = baseline->origin[0];
if (bits & U_ANGLE1) if (bits & U_ANGLE1)
state->msg_angles[0][0] = MSG_ReadAngle (net_message); state->angles[0] = MSG_ReadAngle (net_message);
else else
state->msg_angles[0][0] = state->baseline.angles[0]; state->angles[0] = baseline->angles[0];
if (bits & U_ORIGIN2) if (bits & U_ORIGIN2)
state->msg_origins[0][1] = MSG_ReadCoord (net_message); state->origin[1] = MSG_ReadCoord (net_message);
else else
state->msg_origins[0][1] = state->baseline.origin[1]; state->origin[1] = baseline->origin[1];
if (bits & U_ANGLE2) if (bits & U_ANGLE2)
state->msg_angles[0][1] = MSG_ReadAngle (net_message); state->angles[1] = MSG_ReadAngle (net_message);
else else
state->msg_angles[0][1] = state->baseline.angles[1]; state->angles[1] = baseline->angles[1];
if (bits & U_ORIGIN3) if (bits & U_ORIGIN3)
state->msg_origins[0][2] = MSG_ReadCoord (net_message); state->origin[2] = MSG_ReadCoord (net_message);
else else
state->msg_origins[0][2] = state->baseline.origin[2]; state->origin[2] = baseline->origin[2];
if (bits & U_ANGLE3) if (bits & U_ANGLE3)
state->msg_angles[0][2] = MSG_ReadAngle (net_message); state->angles[2] = MSG_ReadAngle (net_message);
else else
state->msg_angles[0][2] = state->baseline.angles[2]; state->angles[2] = baseline->angles[2];
if (bits & U_STEP) //FIXME lerping (see fitzquake) if (bits & U_STEP) //FIXME lerping (see fitzquake)
forcelink = true; forcelink = true;
@ -585,49 +560,36 @@ CL_ParseUpdate (int bits)
if (bits & U_ALPHA) if (bits & U_ALPHA)
state->alpha = MSG_ReadByte(net_message); state->alpha = MSG_ReadByte(net_message);
else else
state->alpha = state->baseline.alpha; state->alpha = baseline->alpha;
if (bits & U_FRAME2) if (bits & U_FRAME2)
ent->frame |= MSG_ReadByte(net_message) << 8; state->frame |= MSG_ReadByte(net_message) << 8;
if (bits & U_MODEL2) if (bits & U_MODEL2)
modnum |= MSG_ReadByte(net_message) << 8; modnum |= MSG_ReadByte(net_message) << 8;
if (bits & U_LERPFINISH) { if (bits & U_LERPFINISH) {
MSG_ReadByte (net_message); //FIXME ignored for now. see fitzquake MSG_ReadByte (net_message); //FIXME ignored for now. see fitzquake
} }
} else { } else {
state->alpha = state->baseline.alpha; state->alpha = baseline->alpha;
state->scale = state->baseline.scale; state->scale = baseline->scale;
state->glow_size = state->baseline.glow_size; state->glow_size = baseline->glow_size;
state->glow_color = state->baseline.glow_color; state->glow_color = baseline->glow_color;
state->colormod = state->baseline.colormod; state->colormod = baseline->colormod;
} }
model = cl.model_precache[modnum]; state->modelindex = modnum;
if (model != ent->model) {
ent->model = model;
// automatic animation (torches, etc) can be either all together
// or randomized
if (model) {
if (model->synctype == ST_RAND)
ent->syncbase = (float) (rand () & 0x7fff) / 0x7fff;
else
ent->syncbase = 0.0;
} else
forcelink = true; // hack to make null model players work
if (num >= 0 && num <= cl.maxclients)
ent->skin = mod_funcs->Skin_SetColormap (ent->skin, num);
}
if (forcelink) { // didn't have an update last message if (forcelink) { // didn't have an update last message
VectorCopy (state->msg_origins[0], state->msg_origins[1]); //VectorCopy (state->msg_origins[0], state->msg_origins[1]);
VectorCopy (state->msg_origins[0], ent->origin); //VectorCopy (state->msg_origins[0], ent->origin);
VectorCopy (state->msg_angles[0], state->msg_angles[1]); //VectorCopy (state->msg_angles[0], state->msg_angles[1]);
CL_TransformEntity (ent, state->msg_angles[0], true); //CL_TransformEntity (ent, state->msg_angles[0], true);
state->forcelink = true; //state->forcelink = true;
cl_forcelink[num] = true;
} }
} }
static void static void
CL_ParseBaseline (cl_entity_state_t *state, int version) CL_ParseBaseline (entity_state_t *baseline, int version)
{ {
int bits = 0; int bits = 0;
@ -635,29 +597,28 @@ CL_ParseBaseline (cl_entity_state_t *state, int version)
bits = MSG_ReadByte (net_message); bits = MSG_ReadByte (net_message);
if (bits & B_LARGEMODEL) if (bits & B_LARGEMODEL)
state->baseline.modelindex = MSG_ReadShort (net_message); baseline->modelindex = MSG_ReadShort (net_message);
else else
state->baseline.modelindex = MSG_ReadByte (net_message); baseline->modelindex = MSG_ReadByte (net_message);
if (bits & B_LARGEFRAME) if (bits & B_LARGEFRAME)
state->baseline.frame = MSG_ReadShort (net_message); baseline->frame = MSG_ReadShort (net_message);
else else
state->baseline.frame = MSG_ReadByte (net_message); baseline->frame = MSG_ReadByte (net_message);
state->baseline.colormap = MSG_ReadByte (net_message); baseline->colormap = MSG_ReadByte (net_message);
state->baseline.skinnum = MSG_ReadByte (net_message); baseline->skinnum = MSG_ReadByte (net_message);
MSG_ReadCoordAngleV (net_message, state->baseline.origin, MSG_ReadCoordAngleV (net_message, baseline->origin, baseline->angles);
state->baseline.angles);
if (bits & B_ALPHA) if (bits & B_ALPHA)
state->baseline.alpha = MSG_ReadByte (net_message); baseline->alpha = MSG_ReadByte (net_message);
else else
state->baseline.alpha = 255;//FIXME alpha baseline->alpha = 255;//FIXME alpha
state->baseline.scale = 16; baseline->scale = 16;
state->baseline.glow_size = 0; baseline->glow_size = 0;
state->baseline.glow_color = 254; baseline->glow_color = 254;
state->baseline.colormod = 255; baseline->colormod = 255;
} }
/* /*
@ -805,34 +766,25 @@ CL_ParseClientdata (void)
static void static void
CL_ParseStatic (int version) CL_ParseStatic (int version)
{ {
cl_entity_state_t state; entity_state_t baseline;
entity_t *ent; entity_t *ent;
ent = r_funcs->R_AllocEntity (); ent = r_funcs->R_AllocEntity ();
CL_Init_Entity (ent); CL_Init_Entity (ent);
CL_ParseBaseline (&state, version); CL_ParseBaseline (&baseline, version);
// copy it to the current state // copy it to the current state
//FIXME alpha & lerp //FIXME alpha & lerp
ent->model = cl.model_precache[state.baseline.modelindex]; ent->model = cl.model_precache[baseline.modelindex];
ent->frame = state.baseline.frame; ent->frame = baseline.frame;
ent->skin = 0; ent->skin = 0;
ent->skinnum = state.baseline.skinnum; ent->skinnum = baseline.skinnum;
if (state.baseline.colormod == 255) { VectorCopy (ent_colormod[baseline.colormod], ent->colormod);
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1.0; ent->colormod[3] = ENTALPHA_DECODE (baseline.alpha);
} else { ent->scale = baseline.scale / 16.0;
ent->colormod[0] = ((float) ((state.baseline.colormod >> 5) & 7)) * VectorCopy (baseline.origin, ent->origin);
(1.0 / 7.0); CL_TransformEntity (ent, baseline.angles, true);
ent->colormod[1] = ((float) ((state.baseline.colormod >> 2) & 7)) *
(1.0 / 7.0);
ent->colormod[2] = ((float) (state.baseline.colormod & 3)) *
(1.0 / 3.0);
}
ent->colormod[3] = ENTALPHA_DECODE (state.baseline.alpha);
ent->scale = state.baseline.scale / 16.0;
VectorCopy (state.baseline.origin, ent->origin);
CL_TransformEntity (ent, state.baseline.angles, true);
r_funcs->R_AddEfrags (ent); r_funcs->R_AddEfrags (ent);
} }
@ -950,6 +902,7 @@ CL_ParseServerMessage (void)
case svc_time: case svc_time:
cl.mtime[1] = cl.mtime[0]; cl.mtime[1] = cl.mtime[0];
cl.mtime[0] = MSG_ReadFloat (net_message); cl.mtime[0] = MSG_ReadFloat (net_message);
cl.mindex = !cl.mindex;
break; break;
case svc_print: case svc_print: