void ClearStateToDefault(entity_state_t *s)
{
- s->active = 0;
- s->time = 0;
- VectorClear(s->origin);
- VectorClear(s->angles);
- s->effects = 0;
- s->modelindex = 0;
- s->frame = 0;
- s->colormap = 0;
- s->skin = 0;
+ memset(s, 0, sizeof(*s));
s->alpha = 255;
s->scale = 16;
- s->glowsize = 0;
s->glowcolor = 254;
- s->flags = 0;
}
// (server) clears the database to contain no frames (thus delta compression compresses against nothing)
}
// (server) clears frame, to prepare for adding entities
-void EntityFrame_Clear(entity_frame_t *f, vec3_t eye)
+void EntityFrame_Clear(entity_frame_t *f, vec3_t eye, int framenum)
{
- memset(f, 0, sizeof(*f));
- VectorCopy(eye, f->eye);
+ f->time = 0;
+ f->framenum = framenum;
+ f->numentities = 0;
+ if (eye == NULL)
+ {
+ VectorClear(f->eye);
+ }
+ else
+ {
+ VectorCopy(eye, f->eye);
+ }
}
-// (server) allocates an entity slot in frame, returns NULL if full
-entity_state_t *EntityFrame_NewEntity(entity_frame_t *f, int number)
+// (server) adds an entity to frame
+void EntityFrame_AddEntity(entity_frame_t *f, entity_state_t *s)
{
- entity_state_t *e;
- if (f->numentities >= MAX_ENTITY_DATABASE)
- return NULL;
- e = &f->entitydata[f->numentities++];
- e->active = true;
- e->number = number;
- return e;
+ if (f->numentities < MAX_ENTITY_DATABASE)
+ {
+ f->entitydata[f->numentities] = *s;
+ f->entitydata[f->numentities++].active = true;
+ }
}
// (server and client) reads a frame from the database
void EntityFrame_FetchFrame(entity_database_t *d, int framenum, entity_frame_t *f)
{
int i, n;
- memset(f, 0, sizeof(*f));
+ EntityFrame_Clear(f, NULL, -1);
for (i = 0;i < d->numframes && d->frames[i].framenum < framenum;i++);
if (i < d->numframes && framenum == d->frames[i].framenum)
{
memcpy(f->entitydata + n, d->entitydata, sizeof(*f->entitydata) * (f->numentities - n));
VectorCopy(d->eye, f->eye);
}
- else
- f->framenum = -1;
}
// (server and client) adds a entity_frame to the database, for future reference
}
// (server) writes a frame to network stream
+static entity_frame_t deltaframe; // FIXME?
void EntityFrame_Write(entity_database_t *d, entity_frame_t *f, sizebuf_t *msg)
{
int i, onum, bits, number;
- entity_frame_t deltaframe, *o = &deltaframe;
+ float org[3], deltaorg[3];
+ entity_frame_t *o = &deltaframe;
entity_state_t *ent, *delta, baseline;
EntityFrame_AddFrame(d, f);
delta = &baseline;
}
bits = 0;
+ VectorCopy(ent->origin, org);
+ VectorCopy(delta->origin, deltaorg);
if (ent->flags & RENDER_LOWPRECISION)
{
- if ((int) ent->origin[0] != (int) delta->origin[0])
- bits |= E_ORIGIN1;
- if ((int) ent->origin[1] != (int) delta->origin[1])
- bits |= E_ORIGIN2;
- if ((int) ent->origin[2] != (int) delta->origin[2])
- bits |= E_ORIGIN3;
+ if (org[0] > 0)
+ org[0] = (int) (org[0] + 0.5f);
+ else
+ org[0] = (int) (org[0] - 0.5f);
+ if (org[1] > 0)
+ org[1] = (int) (org[1] + 0.5f);
+ else
+ org[1] = (int) (org[1] - 0.5f);
+ if (org[2] > 0)
+ org[2] = (int) (org[2] + 0.5f);
+ else
+ org[2] = (int) (org[2] - 0.5f);
}
- else
+ if (delta->flags & RENDER_LOWPRECISION)
{
- if (fabs(ent->origin[0] - delta->origin[0]) > 0.01f)
- bits |= E_ORIGIN1;
- if (fabs(ent->origin[1] - delta->origin[1]) > 0.01f)
- bits |= E_ORIGIN2;
- if (fabs(ent->origin[2] - delta->origin[2]) > 0.01f)
- bits |= E_ORIGIN3;
+ if (deltaorg[0] > 0)
+ deltaorg[0] = (int) (deltaorg[0] + 0.5f);
+ else
+ deltaorg[0] = (int) (deltaorg[0] - 0.5f);
+ if (deltaorg[1] > 0)
+ deltaorg[1] = (int) (deltaorg[1] + 0.5f);
+ else
+ deltaorg[1] = (int) (deltaorg[1] - 0.5f);
+ if (deltaorg[2] > 0)
+ deltaorg[2] = (int) (deltaorg[2] + 0.5f);
+ else
+ deltaorg[2] = (int) (deltaorg[2] - 0.5f);
}
+ if (fabs(org[0] - deltaorg[0]) > 0.01f)
+ bits |= E_ORIGIN1;
+ if (fabs(org[1] - deltaorg[1]) > 0.01f)
+ bits |= E_ORIGIN2;
+ if (fabs(org[2] - deltaorg[2]) > 0.01f)
+ bits |= E_ORIGIN3;
if ((qbyte) (ent->angles[0] * (256.0f / 360.0f)) != (qbyte) (delta->angles[0] * (256.0f / 360.0f)))
bits |= E_ANGLE1;
if ((qbyte) (ent->angles[1] * (256.0f / 360.0f)) != (qbyte) (delta->angles[1] * (256.0f / 360.0f)))
bits |= E_GLOWCOLOR;
if (ent->flags != delta->flags)
bits |= E_FLAGS;
+ if (ent->tagindex != delta->tagindex || ent->tagentity != delta->tagentity)
+ bits |= E_TAGATTACHMENT;
if (bits) // don't send anything if it hasn't changed
{
if (ent->flags & RENDER_LOWPRECISION)
{
if (bits & E_ORIGIN1)
- MSG_WriteShort(msg, ent->origin[0]);
+ MSG_WriteShort(msg, org[0]);
if (bits & E_ORIGIN2)
- MSG_WriteShort(msg, ent->origin[1]);
+ MSG_WriteShort(msg, org[1]);
if (bits & E_ORIGIN3)
- MSG_WriteShort(msg, ent->origin[2]);
+ MSG_WriteShort(msg, org[2]);
}
else
{
if (bits & E_ORIGIN1)
- MSG_WriteFloat(msg, ent->origin[0]);
+ MSG_WriteFloat(msg, org[0]);
if (bits & E_ORIGIN2)
- MSG_WriteFloat(msg, ent->origin[1]);
+ MSG_WriteFloat(msg, org[1]);
if (bits & E_ORIGIN3)
- MSG_WriteFloat(msg, ent->origin[2]);
+ MSG_WriteFloat(msg, org[2]);
}
if (bits & E_ANGLE1)
MSG_WriteAngle(msg, ent->angles[0]);
MSG_WriteByte(msg, ent->glowsize);
if (bits & E_GLOWCOLOR)
MSG_WriteByte(msg, ent->glowcolor);
+ if (bits & E_TAGATTACHMENT)
+ {
+ MSG_WriteShort(msg, ent->tagentity);
+ MSG_WriteByte(msg, ent->tagindex);
+ }
}
}
for (;onum < o->numentities;onum++)
}
// (client) reads a frame from network stream
+static entity_frame_t framedata; // FIXME?
void EntityFrame_Read(entity_database_t *d)
{
int number, removed, bits;
- entity_frame_t framedata, *f = &framedata, deltaframedata, *delta = &deltaframedata;
+ entity_frame_t *f = &framedata, *delta = &deltaframe;
entity_state_t *e, baseline, *old, *oldend;
ClearStateToDefault(&baseline);
- memset(f, 0, sizeof(*f));
+
+ EntityFrame_Clear(f, NULL, -1);
+
// read the frame header info
f->time = cl.mtime[0];
number = MSG_ReadLong();
if (dpprotocol == DPPROTOCOL_VERSION2)
if (bits & E_FLAGS)
e->flags = MSG_ReadByte();
+ if (bits & E_TAGATTACHMENT)
+ {
+ e->tagentity = MSG_ReadShort();
+ e->tagindex = MSG_ReadByte();
+ }
}
}
while (old < oldend)
EntityFrame_AddFrame(d, f);
}
-/*
-// (client) reads (and interpolates) the eye location from the database,
-// given a current time
-int EntityFrame_FetchEye(entity_database_t *d, vec3_t eye, double time)
-{
- float frac;
- if (d->numframes == 0)
- return false;
-// Host_Error("EntityFrame_FetchEye: no frames\n");
- if (d->numframes > 1 && d->frames[d->numframes - 2].time != d->frames[d->numframes - 1].time)
- {
- frac = (time - d->frames[d->numframes - 2].time) / (d->frames[d->numframes - 1].time - d->frames[d->numframes - 2].time);
- frac = bound(0, frac, 1);
- VectorSubtract(d->frames[d->numframes - 2].eye, d->frames[d->numframes - 1].eye, eye);
- VectorMA(d->frames[d->numframes - 2].eye, frac, eye, eye);
- }
- else
- VectorCopy(d->frames[0].eye, eye);
- return true;
-}
-
-// (client) fetchs an entity from a frame, index is the index into the frame's entity list, returns false if index is out of bounds
-int EntityFrame_FetchEntityByIndex(entity_frame_t *f, entity_state_t *e, int index)
-{
- if (index < 0 || index >= f->numentities)
- return false;
- memcpy(e, f->entitydata + index, sizeof(*e));
- return true;
-}
-
-int EntityFrame_FetchEntityByNumber(entity_frame_t *f, entity_state_t *e, int number)
-{
- int i;
- for (i = 0;i < f->numentities;i++)
- {
- if (f->entitydata[i].number == number)
- {
- memcpy(e, f->entitydata + i, sizeof(*e));
- return true;
- }
- }
- ClearStateToDefault(e);
- return false;
-}
-*/
// (client) returns the frame number of the most recent frame recieved
int EntityFrame_MostRecentlyRecievedFrameNum(entity_database_t *d)
else
return -1;
}
+