4 // (client) adds a entity_frame to the database, for future reference
5 void EntityFrame_AddFrame_Client(entityframe_database_t *d, vec3_t eye, int framenum, int numentities, const entity_state_t *entitydata)
8 entity_frameinfo_t *info;
10 VectorCopy(eye, d->eye);
12 // figure out how many entity slots are used already
15 n = d->frames[d->numframes - 1].endentity - d->frames[0].firstentity;
16 if (n + numentities > MAX_ENTITY_DATABASE || d->numframes >= MAX_ENTITY_HISTORY)
18 // ran out of room, dump database
19 EntityFrame_ClearDatabase(d);
23 info = &d->frames[d->numframes];
24 info->framenum = framenum;
26 // make sure we check the newly added frame as well, but we haven't incremented numframes yet
27 for (n = 0;n <= d->numframes;n++)
29 if (e >= d->frames[n].framenum)
32 Con_Print("EntityFrame_AddFrame: tried to add out of sequence frame to database\n");
34 Con_Print("EntityFrame_AddFrame: out of sequence frames in database\n");
37 e = d->frames[n].framenum;
39 // if database still has frames after that...
41 info->firstentity = d->frames[d->numframes - 1].endentity;
43 info->firstentity = 0;
44 info->endentity = info->firstentity + numentities;
47 n = info->firstentity % MAX_ENTITY_DATABASE;
48 e = MAX_ENTITY_DATABASE - n;
51 memcpy(d->entitydata + n, entitydata, sizeof(entity_state_t) * e);
53 memcpy(d->entitydata, entitydata + e, sizeof(entity_state_t) * (numentities - e));
56 // (client) reads a frame from network stream
57 void EntityFrame_CL_ReadFrame(void)
59 int i, number, removed;
60 entity_frame_t *f, *delta;
61 entity_state_t *e, *old, *oldend;
63 entityframe_database_t *d;
64 if (!cl.entitydatabase)
65 cl.entitydatabase = EntityFrame_AllocDatabase(cls.levelmempool);
66 d = cl.entitydatabase;
68 delta = &d->deltaframe;
70 EntityFrame_Clear(f, NULL, -1);
72 // read the frame header info
73 f->time = cl.mtime[0];
74 number = MSG_ReadLong(&cl_message);
75 f->framenum = MSG_ReadLong(&cl_message);
76 CL_NewFrameReceived(f->framenum);
77 f->eye[0] = MSG_ReadFloat(&cl_message);
78 f->eye[1] = MSG_ReadFloat(&cl_message);
79 f->eye[2] = MSG_ReadFloat(&cl_message);
80 EntityFrame_AckFrame(d, number);
81 EntityFrame_FetchFrame(d, number, delta);
82 old = delta->entitydata;
83 oldend = old + delta->numentities;
84 // read entities until we hit the magic 0xFFFF end tag
85 while ((number = (unsigned short) MSG_ReadShort(&cl_message)) != 0xFFFF && !cl_message.badread)
87 if (cl_message.badread)
88 Host_Error("EntityFrame_Read: read error");
89 removed = number & 0x8000;
91 if (number >= MAX_EDICTS)
92 Host_Error("EntityFrame_Read: number (%i) >= MAX_EDICTS (%i)", number, MAX_EDICTS);
94 // seek to entity, while copying any skipped entities (assume unchanged)
95 while (old < oldend && old->number < number)
97 if (f->numentities >= MAX_ENTITY_DATABASE)
98 Host_Error("EntityFrame_Read: entity list too big");
99 f->entitydata[f->numentities] = *old++;
100 f->entitydata[f->numentities++].time = cl.mtime[0];
104 if (old < oldend && old->number == number)
107 Con_Printf("EntityFrame_Read: REMOVE on unused entity %i\n", number);
111 if (f->numentities >= MAX_ENTITY_DATABASE)
112 Host_Error("EntityFrame_Read: entity list too big");
115 e = f->entitydata + f->numentities++;
117 if (old < oldend && old->number == number)
119 // delta from old entity
124 // delta from defaults
128 if (cl.num_entities <= number)
130 cl.num_entities = number + 1;
131 if (number >= cl.max_entities)
132 CL_ExpandEntities(number);
134 cl.entities_active[number] = true;
135 e->active = ACTIVE_NETWORK;
136 e->time = cl.mtime[0];
138 EntityState_ReadFields(e, EntityState_ReadExtendBits());
143 if (f->numentities >= MAX_ENTITY_DATABASE)
144 Host_Error("EntityFrame_Read: entity list too big");
145 f->entitydata[f->numentities] = *old++;
146 f->entitydata[f->numentities++].time = cl.mtime[0];
148 EntityFrame_AddFrame_Client(d, f->eye, f->framenum, f->numentities, f->entitydata);
150 memset(cl.entities_active, 0, cl.num_entities * sizeof(unsigned char));
152 for (i = 0;i < f->numentities;i++)
154 for (;number < f->entitydata[i].number && number < cl.num_entities;number++)
156 if (cl.entities_active[number])
158 cl.entities_active[number] = false;
159 cl.entities[number].state_current.active = ACTIVE_NOT;
162 if (number >= cl.num_entities)
165 ent = &cl.entities[number];
166 ent->state_previous = ent->state_current;
167 ent->state_current = f->entitydata[i];
168 CL_MoveLerpEntityStates(ent);
169 // the entity lives again...
170 cl.entities_active[number] = true;
173 for (;number < cl.num_entities;number++)
175 if (cl.entities_active[number])
177 cl.entities_active[number] = false;
178 cl.entities[number].state_current.active = ACTIVE_NOT;
184 // (client) returns the frame number of the most recent frame recieved
185 int EntityFrame_MostRecentlyRecievedFrameNum(entityframe_database_t *d)
188 return d->frames[d->numframes - 1].framenum;