]> icculus.org git repositories - divverent/darkplaces.git/blob - protocol.c
embedded a fallback conchars.tga so it can load in an empty directory with a visible...
[divverent/darkplaces.git] / protocol.c
1
2 #include "quakedef.h"
3
4 // this is 80 bytes
5 entity_state_t defaultstate =
6 {
7         // ! means this is sent to client
8         0,//double time; // time this state was built (used on client for interpolation)
9         {0,0,0},//float origin[3]; // !
10         {0,0,0},//float angles[3]; // !
11         0,//int number; // ! entity number this state is for
12         0,//int effects; // !
13         0,//unsigned short modelindex; // !
14         0,//unsigned short frame; // !
15         0,//unsigned short tagentity; // !
16         0,//unsigned short specialvisibilityradius; // larger if it has effects/light
17         0,//unsigned short viewmodelforclient;
18         0,//unsigned short exteriormodelforclient; // not shown if first person viewing from this entity, shown in all other cases
19         0,//unsigned short nodrawtoclient;
20         0,//unsigned short drawonlytoclient;
21         {0,0,0,0},//unsigned short light[4]; // ! color*256 (0.00 to 255.996), and radius*1
22         0,//unsigned char active; // ! true if a valid state
23         0,//unsigned char lightstyle; // !
24         0,//unsigned char lightpflags; // !
25         0,//unsigned char colormap; // !
26         0,//unsigned char skin; // ! also chooses cubemap for rtlights if lightpflags & LIGHTPFLAGS_FULLDYNAMIC
27         255,//unsigned char alpha; // !
28         16,//unsigned char scale; // !
29         0,//unsigned char glowsize; // !
30         254,//unsigned char glowcolor; // !
31         0,//unsigned char flags; // !
32         0,//unsigned char tagindex; // !
33         // padding to a multiple of 8 bytes (to align the double time)
34         {0,0,0,0,0}//unsigned char unused[5];
35 };
36
37 void ClearStateToDefault(entity_state_t *s)
38 {
39         *s = defaultstate;
40 }
41
42 int EntityState_DeltaBits(const entity_state_t *o, const entity_state_t *n)
43 {
44         unsigned int bits;
45         // if o is not active, delta from default
46         if (!o->active)
47                 o = &defaultstate;
48         bits = 0;
49         if (fabs(n->origin[0] - o->origin[0]) > (1.0f / 256.0f))
50                 bits |= E_ORIGIN1;
51         if (fabs(n->origin[1] - o->origin[1]) > (1.0f / 256.0f))
52                 bits |= E_ORIGIN2;
53         if (fabs(n->origin[2] - o->origin[2]) > (1.0f / 256.0f))
54                 bits |= E_ORIGIN3;
55         if ((qbyte) (n->angles[0] * (256.0f / 360.0f)) != (qbyte) (o->angles[0] * (256.0f / 360.0f)))
56                 bits |= E_ANGLE1;
57         if ((qbyte) (n->angles[1] * (256.0f / 360.0f)) != (qbyte) (o->angles[1] * (256.0f / 360.0f)))
58                 bits |= E_ANGLE2;
59         if ((qbyte) (n->angles[2] * (256.0f / 360.0f)) != (qbyte) (o->angles[2] * (256.0f / 360.0f)))
60                 bits |= E_ANGLE3;
61         if ((n->modelindex ^ o->modelindex) & 0x00FF)
62                 bits |= E_MODEL1;
63         if ((n->modelindex ^ o->modelindex) & 0xFF00)
64                 bits |= E_MODEL2;
65         if ((n->frame ^ o->frame) & 0x00FF)
66                 bits |= E_FRAME1;
67         if ((n->frame ^ o->frame) & 0xFF00)
68                 bits |= E_FRAME2;
69         if ((n->effects ^ o->effects) & 0x00FF)
70                 bits |= E_EFFECTS1;
71         if ((n->effects ^ o->effects) & 0xFF00)
72                 bits |= E_EFFECTS2;
73         if (n->colormap != o->colormap)
74                 bits |= E_COLORMAP;
75         if (n->skin != o->skin)
76                 bits |= E_SKIN;
77         if (n->alpha != o->alpha)
78                 bits |= E_ALPHA;
79         if (n->scale != o->scale)
80                 bits |= E_SCALE;
81         if (n->glowsize != o->glowsize)
82                 bits |= E_GLOWSIZE;
83         if (n->glowcolor != o->glowcolor)
84                 bits |= E_GLOWCOLOR;
85         if (n->flags != o->flags)
86                 bits |= E_FLAGS;
87         if (n->tagindex != o->tagindex || n->tagentity != o->tagentity)
88                 bits |= E_TAGATTACHMENT;
89         if (n->light[0] != o->light[0] || n->light[1] != o->light[1] || n->light[2] != o->light[2] || n->light[3] != o->light[3])
90                 bits |= E_LIGHT;
91         if (n->lightstyle != o->lightstyle)
92                 bits |= E_LIGHTSTYLE;
93         if (n->lightpflags != o->lightpflags)
94                 bits |= E_LIGHTPFLAGS;
95
96         if (bits)
97         {
98                 if (bits &  0xFF000000)
99                         bits |= 0x00800000;
100                 if (bits &  0x00FF0000)
101                         bits |= 0x00008000;
102                 if (bits &  0x0000FF00)
103                         bits |= 0x00000080;
104         }
105         return bits;
106 }
107
108 void EntityState_WriteExtendBits(sizebuf_t *msg, unsigned int bits)
109 {
110         MSG_WriteByte(msg, bits & 0xFF);
111         if (bits & 0x00000080)
112         {
113                 MSG_WriteByte(msg, (bits >> 8) & 0xFF);
114                 if (bits & 0x00008000)
115                 {
116                         MSG_WriteByte(msg, (bits >> 16) & 0xFF);
117                         if (bits & 0x00800000)
118                                 MSG_WriteByte(msg, (bits >> 24) & 0xFF);
119                 }
120         }
121 }
122
123 void EntityState_WriteFields(entity_state_t *ent, sizebuf_t *msg, unsigned int bits)
124 {
125         // LordHavoc: have to write flags first, as they can modify protocol
126         if (bits & E_FLAGS)
127                 MSG_WriteByte(msg, ent->flags);
128         if (ent->flags & RENDER_LOWPRECISION)
129         {
130                 if (bits & E_ORIGIN1)
131                         MSG_WriteShort(msg, ent->origin[0]);
132                 if (bits & E_ORIGIN2)
133                         MSG_WriteShort(msg, ent->origin[1]);
134                 if (bits & E_ORIGIN3)
135                         MSG_WriteShort(msg, ent->origin[2]);
136                 if (bits & E_ANGLE1)
137                         MSG_WriteAngle(msg, ent->angles[0]);
138                 if (bits & E_ANGLE2)
139                         MSG_WriteAngle(msg, ent->angles[1]);
140                 if (bits & E_ANGLE3)
141                         MSG_WriteAngle(msg, ent->angles[2]);
142         }
143         else
144         {
145                 if (bits & E_ORIGIN1)
146                         MSG_WriteFloat(msg, ent->origin[0]);
147                 if (bits & E_ORIGIN2)
148                         MSG_WriteFloat(msg, ent->origin[1]);
149                 if (bits & E_ORIGIN3)
150                         MSG_WriteFloat(msg, ent->origin[2]);
151                 if (bits & E_ANGLE1)
152                         MSG_WritePreciseAngle(msg, ent->angles[0]);
153                 if (bits & E_ANGLE2)
154                         MSG_WritePreciseAngle(msg, ent->angles[1]);
155                 if (bits & E_ANGLE3)
156                         MSG_WritePreciseAngle(msg, ent->angles[2]);
157         }
158         if (bits & E_MODEL1)
159                 MSG_WriteByte(msg, ent->modelindex & 0xFF);
160         if (bits & E_MODEL2)
161                 MSG_WriteByte(msg, (ent->modelindex >> 8) & 0xFF);
162         if (bits & E_FRAME1)
163                 MSG_WriteByte(msg, ent->frame & 0xFF);
164         if (bits & E_FRAME2)
165                 MSG_WriteByte(msg, (ent->frame >> 8) & 0xFF);
166         if (bits & E_EFFECTS1)
167                 MSG_WriteByte(msg, ent->effects & 0xFF);
168         if (bits & E_EFFECTS2)
169                 MSG_WriteByte(msg, (ent->effects >> 8) & 0xFF);
170         if (bits & E_COLORMAP)
171                 MSG_WriteByte(msg, ent->colormap);
172         if (bits & E_SKIN)
173                 MSG_WriteByte(msg, ent->skin);
174         if (bits & E_ALPHA)
175                 MSG_WriteByte(msg, ent->alpha);
176         if (bits & E_SCALE)
177                 MSG_WriteByte(msg, ent->scale);
178         if (bits & E_GLOWSIZE)
179                 MSG_WriteByte(msg, ent->glowsize);
180         if (bits & E_GLOWCOLOR)
181                 MSG_WriteByte(msg, ent->glowcolor);
182         if (bits & E_TAGATTACHMENT)
183         {
184                 MSG_WriteShort(msg, ent->tagentity);
185                 MSG_WriteByte(msg, ent->tagindex);
186         }
187         if (bits & E_LIGHT)
188         {
189                 MSG_WriteShort(msg, ent->light[0]);
190                 MSG_WriteShort(msg, ent->light[1]);
191                 MSG_WriteShort(msg, ent->light[2]);
192                 MSG_WriteShort(msg, ent->light[3]);
193         }
194         if (bits & E_LIGHTSTYLE)
195                 MSG_WriteByte(msg, ent->lightstyle);
196         if (bits & E_LIGHTPFLAGS)
197                 MSG_WriteByte(msg, ent->lightpflags);
198 }
199
200 void EntityState_WriteUpdate(entity_state_t *ent, sizebuf_t *msg, entity_state_t *delta)
201 {
202         unsigned int bits;
203         if (ent->active)
204         {
205                 // entity is active, check for changes from the delta
206                 if ((bits = EntityState_DeltaBits(delta, ent)))
207                 {
208                         // write the update number, bits, and fields
209                         MSG_WriteShort(msg, ent->number);
210                         EntityState_WriteExtendBits(msg, bits);
211                         EntityState_WriteFields(ent, msg, bits);
212                 }
213         }
214         else
215         {
216                 // entity is inactive, check if the delta was active
217                 if (delta->active)
218                 {
219                         // write the remove number
220                         MSG_WriteShort(msg, ent->number | 0x8000);
221                 }
222         }
223 }
224
225 int EntityState_ReadExtendBits(void)
226 {
227         unsigned int bits;
228         bits = MSG_ReadByte();
229         if (bits & 0x00000080)
230         {
231                 bits |= MSG_ReadByte() << 8;
232                 if (bits & 0x00008000)
233                 {
234                         bits |= MSG_ReadByte() << 16;
235                         if (bits & 0x00800000)
236                                 bits |= MSG_ReadByte() << 24;
237                 }
238         }
239         return bits;
240 }
241
242 void EntityState_ReadFields(entity_state_t *e, unsigned int bits)
243 {
244         if (cl.protocol == PROTOCOL_DARKPLACES2)
245         {
246                 if (bits & E_ORIGIN1)
247                         e->origin[0] = (signed short) MSG_ReadShort();
248                 if (bits & E_ORIGIN2)
249                         e->origin[1] = (signed short) MSG_ReadShort();
250                 if (bits & E_ORIGIN3)
251                         e->origin[2] = (signed short) MSG_ReadShort();
252         }
253         else
254         {
255                 if (bits & E_FLAGS)
256                         e->flags = MSG_ReadByte();
257                 if (e->flags & RENDER_LOWPRECISION || cl.protocol == PROTOCOL_DARKPLACES2)
258                 {
259                         if (bits & E_ORIGIN1)
260                                 e->origin[0] = (signed short) MSG_ReadShort();
261                         if (bits & E_ORIGIN2)
262                                 e->origin[1] = (signed short) MSG_ReadShort();
263                         if (bits & E_ORIGIN3)
264                                 e->origin[2] = (signed short) MSG_ReadShort();
265                 }
266                 else
267                 {
268                         if (bits & E_ORIGIN1)
269                                 e->origin[0] = MSG_ReadFloat();
270                         if (bits & E_ORIGIN2)
271                                 e->origin[1] = MSG_ReadFloat();
272                         if (bits & E_ORIGIN3)
273                                 e->origin[2] = MSG_ReadFloat();
274                 }
275         }
276         if (cl.protocol == PROTOCOL_DARKPLACES5 && !(e->flags & RENDER_LOWPRECISION))
277         {
278                 if (bits & E_ANGLE1)
279                         e->angles[0] = MSG_ReadPreciseAngle();
280                 if (bits & E_ANGLE2)
281                         e->angles[1] = MSG_ReadPreciseAngle();
282                 if (bits & E_ANGLE3)
283                         e->angles[2] = MSG_ReadPreciseAngle();
284         }
285         else
286         {
287                 if (bits & E_ANGLE1)
288                         e->angles[0] = MSG_ReadAngle();
289                 if (bits & E_ANGLE2)
290                         e->angles[1] = MSG_ReadAngle();
291                 if (bits & E_ANGLE3)
292                         e->angles[2] = MSG_ReadAngle();
293         }
294         if (bits & E_MODEL1)
295                 e->modelindex = (e->modelindex & 0xFF00) | (unsigned int) MSG_ReadByte();
296         if (bits & E_MODEL2)
297                 e->modelindex = (e->modelindex & 0x00FF) | ((unsigned int) MSG_ReadByte() << 8);
298         if (bits & E_FRAME1)
299                 e->frame = (e->frame & 0xFF00) | (unsigned int) MSG_ReadByte();
300         if (bits & E_FRAME2)
301                 e->frame = (e->frame & 0x00FF) | ((unsigned int) MSG_ReadByte() << 8);
302         if (bits & E_EFFECTS1)
303                 e->effects = (e->effects & 0xFF00) | (unsigned int) MSG_ReadByte();
304         if (bits & E_EFFECTS2)
305                 e->effects = (e->effects & 0x00FF) | ((unsigned int) MSG_ReadByte() << 8);
306         if (bits & E_COLORMAP)
307                 e->colormap = MSG_ReadByte();
308         if (bits & E_SKIN)
309                 e->skin = MSG_ReadByte();
310         if (bits & E_ALPHA)
311                 e->alpha = MSG_ReadByte();
312         if (bits & E_SCALE)
313                 e->scale = MSG_ReadByte();
314         if (bits & E_GLOWSIZE)
315                 e->glowsize = MSG_ReadByte();
316         if (bits & E_GLOWCOLOR)
317                 e->glowcolor = MSG_ReadByte();
318         if (cl.protocol == PROTOCOL_DARKPLACES2)
319                 if (bits & E_FLAGS)
320                         e->flags = MSG_ReadByte();
321         if (bits & E_TAGATTACHMENT)
322         {
323                 e->tagentity = MSG_ReadShort();
324                 e->tagindex = MSG_ReadByte();
325         }
326         if (bits & E_LIGHT)
327         {
328                 e->light[0] = MSG_ReadShort();
329                 e->light[1] = MSG_ReadShort();
330                 e->light[2] = MSG_ReadShort();
331                 e->light[3] = MSG_ReadShort();
332         }
333         if (bits & E_LIGHTSTYLE)
334                 e->lightstyle = MSG_ReadByte();
335         if (bits & E_LIGHTPFLAGS)
336                 e->lightpflags = MSG_ReadByte();
337
338         if (developer_networkentities.integer >= 2)
339         {
340                 Con_Printf("ReadFields e%i", e->number);
341
342                 if (bits & E_ORIGIN1)
343                         Con_Printf(" E_ORIGIN1 %f", e->origin[0]);
344                 if (bits & E_ORIGIN2)
345                         Con_Printf(" E_ORIGIN2 %f", e->origin[1]);
346                 if (bits & E_ORIGIN3)
347                         Con_Printf(" E_ORIGIN3 %f", e->origin[2]);
348                 if (bits & E_ANGLE1)
349                         Con_Printf(" E_ANGLE1 %f", e->angles[0]);
350                 if (bits & E_ANGLE2)
351                         Con_Printf(" E_ANGLE2 %f", e->angles[1]);
352                 if (bits & E_ANGLE3)
353                         Con_Printf(" E_ANGLE3 %f", e->angles[2]);
354                 if (bits & (E_MODEL1 | E_MODEL2))
355                         Con_Printf(" E_MODEL %i", e->modelindex);
356
357                 if (bits & (E_FRAME1 | E_FRAME2))
358                         Con_Printf(" E_FRAME %i", e->frame);
359                 if (bits & (E_EFFECTS1 | E_EFFECTS2))
360                         Con_Printf(" E_EFFECTS %i", e->effects);
361                 if (bits & E_ALPHA)
362                         Con_Printf(" E_ALPHA %f", e->alpha / 255.0f);
363                 if (bits & E_SCALE)
364                         Con_Printf(" E_SCALE %f", e->scale / 16.0f);
365                 if (bits & E_COLORMAP)
366                         Con_Printf(" E_COLORMAP %i", e->colormap);
367                 if (bits & E_SKIN)
368                         Con_Printf(" E_SKIN %i", e->skin);
369
370                 if (bits & E_GLOWSIZE)
371                         Con_Printf(" E_GLOWSIZE %i", e->glowsize * 4);
372                 if (bits & E_GLOWCOLOR)
373                         Con_Printf(" E_GLOWCOLOR %i", e->glowcolor);
374                 
375                 if (bits & E_LIGHT)
376                         Con_Printf(" E_LIGHT %i:%i:%i:%i", e->light[0], e->light[1], e->light[2], e->light[3]);
377                 if (bits & E_LIGHTPFLAGS)                       
378                         Con_Printf(" E_LIGHTPFLAGS %i", e->lightpflags);
379
380                 if (bits & E_TAGATTACHMENT)
381                         Con_Printf(" E_TAGATTACHMENT e%i:%i", e->tagentity, e->tagindex);
382                 if (bits & E_LIGHTSTYLE)
383                         Con_Printf(" E_LIGHTSTYLE %i", e->lightstyle);
384                 Con_Print("\n");
385         }
386 }
387
388 // (server) clears the database to contain no frames (thus delta compression compresses against nothing)
389 void EntityFrame_ClearDatabase(entity_database_t *d)
390 {
391         memset(d, 0, sizeof(*d));
392 }
393
394 // (server and client) removes frames older than 'frame' from database
395 void EntityFrame_AckFrame(entity_database_t *d, int frame)
396 {
397         int i;
398         if (d->ackframe < frame)
399                 d->ackframe = frame;
400         for (i = 0;i < d->numframes && d->frames[i].framenum < frame;i++);
401         // ignore outdated frame acks (out of order packets)
402         if (i == 0)
403                 return;
404         d->numframes -= i;
405         // if some queue is left, slide it down to beginning of array
406         if (d->numframes)
407                 memmove(&d->frames[0], &d->frames[i], sizeof(d->frames[0]) * d->numframes);
408 }
409
410 // (server) clears frame, to prepare for adding entities
411 void EntityFrame_Clear(entity_frame_t *f, vec3_t eye, int framenum)
412 {
413         f->time = 0;
414         f->framenum = framenum;
415         f->numentities = 0;
416         if (eye == NULL)
417         {
418                 VectorClear(f->eye);
419         }
420         else
421         {
422                 VectorCopy(eye, f->eye);
423         }
424 }
425
426 // (server) adds an entity to frame
427 void EntityFrame_AddEntity(entity_frame_t *f, entity_state_t *s)
428 {
429         if (f->numentities < MAX_ENTITY_DATABASE)
430         {
431                 f->entitydata[f->numentities] = *s;
432                 f->entitydata[f->numentities++].active = true;
433         }
434 }
435
436 // (server and client) reads a frame from the database
437 void EntityFrame_FetchFrame(entity_database_t *d, int framenum, entity_frame_t *f)
438 {
439         int i, n;
440         EntityFrame_Clear(f, NULL, -1);
441         for (i = 0;i < d->numframes && d->frames[i].framenum < framenum;i++);
442         if (i < d->numframes && framenum == d->frames[i].framenum)
443         {
444                 f->framenum = framenum;
445                 f->numentities = d->frames[i].endentity - d->frames[i].firstentity;
446                 n = MAX_ENTITY_DATABASE - (d->frames[i].firstentity % MAX_ENTITY_DATABASE);
447                 if (n > f->numentities)
448                         n = f->numentities;
449                 memcpy(f->entitydata, d->entitydata + d->frames[i].firstentity % MAX_ENTITY_DATABASE, sizeof(*f->entitydata) * n);
450                 if (f->numentities > n)
451                         memcpy(f->entitydata + n, d->entitydata, sizeof(*f->entitydata) * (f->numentities - n));
452                 VectorCopy(d->eye, f->eye);
453         }
454 }
455
456 // (server and client) adds a entity_frame to the database, for future reference
457 void EntityFrame_AddFrame(entity_database_t *d, entity_frame_t *f)
458 {
459         int n, e;
460         entity_frameinfo_t *info;
461
462         VectorCopy(f->eye, d->eye);
463
464         // figure out how many entity slots are used already
465         if (d->numframes)
466         {
467                 n = d->frames[d->numframes - 1].endentity - d->frames[0].firstentity;
468                 if (n + f->numentities > MAX_ENTITY_DATABASE || d->numframes >= MAX_ENTITY_HISTORY)
469                 {
470                         // ran out of room, dump database
471                         EntityFrame_ClearDatabase(d);
472                 }
473         }
474
475         info = &d->frames[d->numframes];
476         info->framenum = f->framenum;
477         e = -1000;
478         // make sure we check the newly added frame as well, but we haven't incremented numframes yet
479         for (n = 0;n <= d->numframes;n++)
480         {
481                 if (e >= d->frames[n].framenum)
482                 {
483                         if (e == f->framenum)
484                                 Con_Print("EntityFrame_AddFrame: tried to add out of sequence frame to database\n");
485                         else
486                                 Con_Print("EntityFrame_AddFrame: out of sequence frames in database\n");
487                         return;
488                 }
489                 e = d->frames[n].framenum;
490         }
491         // if database still has frames after that...
492         if (d->numframes)
493                 info->firstentity = d->frames[d->numframes - 1].endentity;
494         else
495                 info->firstentity = 0;
496         info->endentity = info->firstentity + f->numentities;
497         d->numframes++;
498
499         n = info->firstentity % MAX_ENTITY_DATABASE;
500         e = MAX_ENTITY_DATABASE - n;
501         if (e > f->numentities)
502                 e = f->numentities;
503         memcpy(d->entitydata + n, f->entitydata, sizeof(entity_state_t) * e);
504         if (f->numentities > e)
505                 memcpy(d->entitydata, f->entitydata + e, sizeof(entity_state_t) * (f->numentities - e));
506 }
507
508 // (server) writes a frame to network stream
509 static entity_frame_t deltaframe; // FIXME?
510 void EntityFrame_Write(entity_database_t *d, entity_frame_t *f, sizebuf_t *msg)
511 {
512         int i, onum, number;
513         entity_frame_t *o = &deltaframe;
514         entity_state_t *ent, *delta;
515
516         EntityFrame_AddFrame(d, f);
517
518         EntityFrame_FetchFrame(d, d->ackframe > 0 ? d->ackframe : -1, o);
519         MSG_WriteByte (msg, svc_entities);
520         MSG_WriteLong (msg, o->framenum);
521         MSG_WriteLong (msg, f->framenum);
522         MSG_WriteFloat (msg, f->eye[0]);
523         MSG_WriteFloat (msg, f->eye[1]);
524         MSG_WriteFloat (msg, f->eye[2]);
525
526         onum = 0;
527         for (i = 0;i < f->numentities;i++)
528         {
529                 ent = f->entitydata + i;
530                 number = ent->number;
531                 for (;onum < o->numentities && o->entitydata[onum].number < number;onum++)
532                 {
533                         // write remove message
534                         MSG_WriteShort(msg, o->entitydata[onum].number | 0x8000);
535                 }
536                 if (onum < o->numentities && (o->entitydata[onum].number == number))
537                 {
538                         // delta from previous frame
539                         delta = o->entitydata + onum;
540                         // advance to next entity in delta frame
541                         onum++;
542                 }
543                 else
544                 {
545                         // delta from defaults
546                         delta = &defaultstate;
547                 }
548                 EntityState_WriteUpdate(ent, msg, delta);
549         }
550         for (;onum < o->numentities;onum++)
551         {
552                 // write remove message
553                 MSG_WriteShort(msg, o->entitydata[onum].number | 0x8000);
554         }
555         MSG_WriteShort(msg, 0xFFFF);
556 }
557
558 // (client) reads a frame from network stream
559 static entity_frame_t framedata; // FIXME?
560 void EntityFrame_Read(entity_database_t *d)
561 {
562         int number, removed;
563         entity_frame_t *f = &framedata, *delta = &deltaframe;
564         entity_state_t *e, *old, *oldend;
565
566         EntityFrame_Clear(f, NULL, -1);
567
568         // read the frame header info
569         f->time = cl.mtime[0];
570         number = MSG_ReadLong();
571         f->framenum = MSG_ReadLong();
572         f->eye[0] = MSG_ReadFloat();
573         f->eye[1] = MSG_ReadFloat();
574         f->eye[2] = MSG_ReadFloat();
575         EntityFrame_AckFrame(d, number);
576         EntityFrame_FetchFrame(d, number, delta);
577         old = delta->entitydata;
578         oldend = old + delta->numentities;
579         // read entities until we hit the magic 0xFFFF end tag
580         while ((number = (unsigned short) MSG_ReadShort()) != 0xFFFF)
581         {
582                 if (msg_badread)
583                         Host_Error("EntityFrame_Read: read error\n");
584                 removed = number & 0x8000;
585                 number &= 0x7FFF;
586                 if (number >= MAX_EDICTS)
587                         Host_Error("EntityFrame_Read: number (%i) >= MAX_EDICTS (%i)\n", number, MAX_EDICTS);
588
589                 // seek to entity, while copying any skipped entities (assume unchanged)
590                 while (old < oldend && old->number < number)
591                 {
592                         if (f->numentities >= MAX_ENTITY_DATABASE)
593                                 Host_Error("EntityFrame_Read: entity list too big\n");
594                         f->entitydata[f->numentities] = *old++;
595                         f->entitydata[f->numentities++].time = cl.mtime[0];
596                 }
597                 if (removed)
598                 {
599                         if (old < oldend && old->number == number)
600                                 old++;
601                         else
602                                 Con_Printf("EntityFrame_Read: REMOVE on unused entity %i\n", number);
603                 }
604                 else
605                 {
606                         if (f->numentities >= MAX_ENTITY_DATABASE)
607                                 Host_Error("EntityFrame_Read: entity list too big\n");
608
609                         // reserve this slot
610                         e = f->entitydata + f->numentities++;
611
612                         if (old < oldend && old->number == number)
613                         {
614                                 // delta from old entity
615                                 *e = *old++;
616                         }
617                         else
618                         {
619                                 // delta from defaults
620                                 *e = defaultstate;
621                         }
622
623                         cl_entities_active[number] = true;
624                         e->active = true;
625                         e->time = cl.mtime[0];
626                         e->number = number;
627                         EntityState_ReadFields(e, EntityState_ReadExtendBits());
628                 }
629         }
630         while (old < oldend)
631         {
632                 if (f->numentities >= MAX_ENTITY_DATABASE)
633                         Host_Error("EntityFrame_Read: entity list too big\n");
634                 f->entitydata[f->numentities] = *old++;
635                 f->entitydata[f->numentities++].time = cl.mtime[0];
636         }
637         EntityFrame_AddFrame(d, f);
638 }
639
640
641 // (client) returns the frame number of the most recent frame recieved
642 int EntityFrame_MostRecentlyRecievedFrameNum(entity_database_t *d)
643 {
644         if (d->numframes)
645                 return d->frames[d->numframes - 1].framenum;
646         else
647                 return -1;
648 }
649
650
651
652
653
654
655 entity_state_t *EntityFrame4_GetReferenceEntity(entity_database4_t *d, int number)
656 {
657         if (d->maxreferenceentities <= number)
658         {
659                 int oldmax = d->maxreferenceentities;
660                 entity_state_t *oldentity = d->referenceentity;
661                 d->maxreferenceentities = (number + 15) & ~7;
662                 d->referenceentity = Mem_Alloc(d->mempool, d->maxreferenceentities * sizeof(*d->referenceentity));
663                 if (oldentity)
664                 {
665                         memcpy(d->referenceentity, oldentity, oldmax * sizeof(*d->referenceentity));
666                         Mem_Free(oldentity);
667                 }
668                 // clear the newly created entities
669                 for (;oldmax < d->maxreferenceentities;oldmax++)
670                 {
671                         d->referenceentity[oldmax] = defaultstate;
672                         d->referenceentity[oldmax].number = oldmax;
673                 }
674         }
675         return d->referenceentity + number;
676 }
677
678 void EntityFrame4_AddCommitEntity(entity_database4_t *d, entity_state_t *s)
679 {
680         // resize commit's entity list if full
681         if (d->currentcommit->maxentities <= d->currentcommit->numentities)
682         {
683                 entity_state_t *oldentity = d->currentcommit->entity;
684                 d->currentcommit->maxentities += 8;
685                 d->currentcommit->entity = Mem_Alloc(d->mempool, d->currentcommit->maxentities * sizeof(*d->currentcommit->entity));
686                 if (oldentity)
687                 {
688                         memcpy(d->currentcommit->entity, oldentity, d->currentcommit->numentities * sizeof(*d->currentcommit->entity));
689                         Mem_Free(oldentity);
690                 }
691         }
692         d->currentcommit->entity[d->currentcommit->numentities++] = *s;
693 }
694
695 entity_database4_t *EntityFrame4_AllocDatabase(mempool_t *pool)
696 {
697         entity_database4_t *d;
698         d = Mem_Alloc(pool, sizeof(*d));
699         d->mempool = pool;
700         EntityFrame4_ResetDatabase(d);
701         d->ackframenum = -1;
702         return d;
703 }
704
705 void EntityFrame4_FreeDatabase(entity_database4_t *d)
706 {
707         int i;
708         for (i = 0;i < MAX_ENTITY_HISTORY;i++)
709                 if (d->commit[i].entity)
710                         Mem_Free(d->commit[i].entity);
711         if (d->referenceentity)
712                 Mem_Free(d->referenceentity);
713         Mem_Free(d);
714 }
715
716 void EntityFrame4_ResetDatabase(entity_database4_t *d)
717 {
718         int i;
719         d->ackframenum = -1;
720         d->referenceframenum = -1;
721         for (i = 0;i < MAX_ENTITY_HISTORY;i++)
722                 d->commit[i].numentities = 0;
723         for (i = 0;i < d->maxreferenceentities;i++)
724                 d->referenceentity[i] = defaultstate;
725 }
726
727 int EntityFrame4_AckFrame(entity_database4_t *d, int framenum)
728 {
729         int i, j, found;
730         entity_database4_commit_t *commit;
731         if (framenum == -1)
732         {
733                 // reset reference, but leave commits alone
734                 d->referenceframenum = -1;
735                 for (i = 0;i < d->maxreferenceentities;i++)
736                         d->referenceentity[i] = defaultstate;
737                 found = true;
738         }
739         else if (d->referenceframenum == framenum)
740                 found = true;
741         else
742         {
743                 found = false;
744                 for (i = 0, commit = d->commit;i < MAX_ENTITY_HISTORY;i++, commit++)
745                 {
746                         if (commit->numentities && commit->framenum <= framenum)
747                         {
748                                 if (commit->framenum == framenum)
749                                 {
750                                         found = true;
751                                         d->referenceframenum = framenum;
752                                         if (developer_networkentities.integer >= 3)
753                                         {
754                                                 for (j = 0;j < commit->numentities;j++)
755                                                 {
756                                                         entity_state_t *s = EntityFrame4_GetReferenceEntity(d, commit->entity[j].number);
757                                                         if (commit->entity[j].active != s->active)
758                                                         {
759                                                                 if (commit->entity[j].active)
760                                                                         Con_Printf("commit entity %i has become active (modelindex %i)\n", commit->entity[j].number, commit->entity[j].modelindex);
761                                                                 else
762                                                                         Con_Printf("commit entity %i has become inactive (modelindex %i)\n", commit->entity[j].number, commit->entity[j].modelindex);
763                                                         }
764                                                         *s = commit->entity[j];
765                                                 }
766                                         }
767                                         else
768                                                 for (j = 0;j < commit->numentities;j++)
769                                                         *EntityFrame4_GetReferenceEntity(d, commit->entity[j].number) = commit->entity[j];
770                                 }
771                                 commit->numentities = 0;
772                         }
773                 }
774         }
775         if (developer_networkentities.integer >= 1)
776         {
777                 Con_Printf("ack ref:%i database updated to: ref:%i commits:", framenum, d->referenceframenum);
778                 for (i = 0;i < MAX_ENTITY_HISTORY;i++)
779                         if (d->commit[i].numentities)
780                                 Con_Printf(" %i", d->commit[i].framenum);
781                 Con_Print("\n");
782         }
783         return found;
784 }
785
786 int EntityFrame4_SV_WriteFrame_Entity(entity_database4_t *d, sizebuf_t *msg, int maxbytes, entity_state_t *s)
787 {
788         qbyte data[128];
789         sizebuf_t buf;
790         entity_state_t *e;
791         // prepare the buffer
792         memset(&buf, 0, sizeof(buf));
793         buf.data = data;
794         buf.maxsize = sizeof(data);
795         // make the update message
796         e = EntityFrame4_GetReferenceEntity(d, s->number);
797         EntityState_WriteUpdate(s, &buf, e);
798         // if the message is empty, skip out now
799         if (!buf.cursize)
800                 return true;
801         // if the commit is full, we're done
802         if (msg->cursize + buf.cursize + 2 >= min(msg->maxsize, maxbytes))
803                 return false;
804         // add the entity to the commit
805         EntityFrame4_AddCommitEntity(d, s);
806         // write the message to the packet
807         SZ_Write(msg, buf.data, buf.cursize);
808         // carry on
809         return true;
810 }
811
812 extern void CL_MoveLerpEntityStates(entity_t *ent);
813 void EntityFrame4_CL_ReadFrame(entity_database4_t *d)
814 {
815         int i, n, cnumber, referenceframenum, framenum, enumber, done, stopnumber, skip = false;
816         entity_state_t *s;
817         // read the number of the frame this refers to
818         referenceframenum = MSG_ReadLong();
819         // read the number of this frame
820         framenum = MSG_ReadLong();
821         // read the start number
822         enumber = MSG_ReadShort();
823         if (developer_networkentities.integer >= 1)
824         {
825                 Con_Printf("recv svc_entities num:%i ref:%i database: ref:%i commits:", framenum, referenceframenum, d->referenceframenum);
826                 for (i = 0;i < MAX_ENTITY_HISTORY;i++)
827                         if (d->commit[i].numentities)
828                                 Con_Printf(" %i", d->commit[i].framenum);
829                 Con_Print("\n");
830         }
831         if (!EntityFrame4_AckFrame(d, referenceframenum))
832         {
833                 Con_Print("EntityFrame4_CL_ReadFrame: reference frame invalid (VERY BAD ERROR), this update will be skipped\n");
834                 skip = true;
835         }
836         d->currentcommit = NULL;
837         for (i = 0;i < MAX_ENTITY_HISTORY;i++)
838         {
839                 if (!d->commit[i].numentities)
840                 {
841                         d->currentcommit = d->commit + i;
842                         d->currentcommit->framenum = d->ackframenum = framenum;
843                         d->currentcommit->numentities = 0;
844                 }
845         }
846         if (d->currentcommit == NULL)
847         {
848                 Con_Printf("EntityFrame4_CL_ReadFrame: error while decoding frame %i: database full, reading but not storing this update\n", framenum);
849                 skip = true;
850         }
851         done = false;
852         while (!done && !msg_badread)
853         {
854                 // read the number of the modified entity
855                 // (gaps will be copied unmodified)
856                 n = (unsigned short)MSG_ReadShort();
857                 if (n == 0x8000)
858                 {
859                         // no more entities in this update, but we still need to copy the
860                         // rest of the reference entities (final gap)
861                         done = true;
862                         // read end of range number, then process normally
863                         n = (unsigned short)MSG_ReadShort();
864                 }
865                 // high bit means it's a remove message
866                 cnumber = n & 0x7FFF;
867                 // add one (the changed one) if not done
868                 stopnumber = cnumber + !done;
869                 // process entities in range from the last one to the changed one
870                 for (;enumber < stopnumber;enumber++)
871                 {
872                         if (skip)
873                         {
874                                 if (enumber == cnumber && (n & 0x8000) == 0)
875                                 {
876                                         entity_state_t tempstate;
877                                         EntityState_ReadFields(&tempstate, EntityState_ReadExtendBits());
878                                 }
879                                 continue;
880                         }
881                         // slide the current into the previous slot
882                         cl_entities[enumber].state_previous = cl_entities[enumber].state_current;
883                         // copy a new current from reference database
884                         cl_entities[enumber].state_current = *EntityFrame4_GetReferenceEntity(d, enumber);
885                         s = &cl_entities[enumber].state_current;
886                         // if this is the one to modify, read more data...
887                         if (enumber == cnumber)
888                         {
889                                 if (n & 0x8000)
890                                 {
891                                         // simply removed
892                                         if (developer_networkentities.integer >= 2)
893                                                 Con_Printf("entity %i: remove\n", enumber);
894                                         *s = defaultstate;
895                                 }
896                                 else
897                                 {
898                                         // read the changes
899                                         if (developer_networkentities.integer >= 2)
900                                                 Con_Printf("entity %i: update\n", enumber);
901                                         s->active = true;
902                                         EntityState_ReadFields(s, EntityState_ReadExtendBits());
903                                 }
904                         }
905                         else if (developer_networkentities.integer >= 4)
906                                 Con_Printf("entity %i: copy\n", enumber);
907                         // set the cl_entities_active flag
908                         cl_entities_active[enumber] = s->active;
909                         // set the update time
910                         s->time = cl.mtime[0];
911                         // fix the number (it gets wiped occasionally by copying from defaultstate)
912                         s->number = enumber;
913                         // check if we need to update the lerp stuff
914                         if (s->active)
915                                 CL_MoveLerpEntityStates(&cl_entities[enumber]);
916                         // add this to the commit entry whether it is modified or not
917                         if (d->currentcommit)
918                                 EntityFrame4_AddCommitEntity(d, &cl_entities[enumber].state_current);
919                         // print extra messages if desired
920                         if (developer_networkentities.integer >= 2 && cl_entities[enumber].state_current.active != cl_entities[enumber].state_previous.active)
921                         {
922                                 if (cl_entities[enumber].state_current.active)
923                                         Con_Printf("entity #%i has become active\n", enumber);
924                                 else if (cl_entities[enumber].state_previous.active)
925                                         Con_Printf("entity #%i has become inactive\n", enumber);
926                         }
927                 }
928         }
929         d->currentcommit = NULL;
930         if (skip)
931                 EntityFrame4_ResetDatabase(d);
932 }
933
934
935
936
937
938 /*
939 int EntityState5_PriorityForChangedBits(int changedbits)
940 {
941         if (changedbits & E5_ISACTIVE)
942                 return 2;
943         else if (changedbits & (E5_FLAGS | E5_ATTACHMENT | E5_MODEL | E5_SKIN | E5_EXTERIORFORENTITY | E5_COLORMAP | E5_LIGHT | E5_GLOW | E5_EFFECTS | E5_ORIGIN | E5_ANGLES | E5_FRAME | E5_ALPHA | E5_SCALE))
944                 return 1;
945         else
946                 return 0;
947 }
948
949 void EntityState5_WriteUpdate(int number, entitystate_t *s, int changedbits, sizebuf_t *msg)
950 {
951         bits = 0;
952         if (!s->active)
953                 MSG_WriteShort(msg, number | 0x8000);
954         else
955         {
956                 bits |= E5_ISACTIVE;
957                 if (changedbits & E5_ORIGIN)
958                 {
959                         bits |= E5_ORIGIN;
960                         if (s->origin[0] < -4096 || s->origin[0] >= 4096 || s->origin[1] < -4096 || s->origin[1] >= 4096 || s->origin[2] < -4096 || s->origin[2] >= 4096)
961                                 bits |= E5_ORIGIN32;
962                 }
963                 if (changedbits & E5_ANGLES)
964                 {
965                         bits |= E5_ANGLES;
966                         if (!(s->flags & RENDERFLAGS_LOWPRECISION))
967                                 bits |= E5_ANGLES16;
968                 }
969                 if (changedbits & E5_MODEL)
970                 {
971                         bits |= E5_MODEL;
972                         if (s->modelindex >= 256)
973                                 bits |= E5_MODEL16;
974                 }
975                 if (changedbits & E5_FRAME)
976                 {
977                         bits |= E5_FRAME;
978                         if (s->frame >= 256)
979                                 bits |= E5_FRAME16;
980                 }
981                 if (changedbits & E5_SKIN)
982                         bits |= E5_SKIN;
983                 if (changedbits & E5_EFFECTS)
984                 {
985                         bits |= E5_EFFECTS;
986                         if (s->modelindex >= 256)
987                                 bits |= E5_MODEL16;
988                 }
989                 if (changedbits & E5_FLAGS)
990                         bits |= E5_FLAGS;
991                 if (changedbits & E5_ALPHA)
992                         bits |= E5_ALPHA;
993                 if (changedbits & E5_SCALE)
994                         bits |= E5_SCALE;
995                 if (changedbits & E5_ATTACHMENT)
996                         bits |= E5_ATTACHMENT;
997                 if (changedbits & E5_EXTERIORFORENTITY)
998                         bits |= E5_EXTERIORFORENTITY;
999                 if (changedbits & E5_LIGHT)
1000                         bits |= E5_LIGHT;
1001                 if (changedbits & E5_COLORMAP)
1002                         bits |= E5_COLORMAP;
1003                 if (changedbits & E5_GLOW)
1004                         bits |= E5_GLOW;
1005                 if (bits >= 256)
1006                         bits |= E5_EXTEND1;
1007                 if (bits >= 65536)
1008                         bits |= E5_EXTEND2;
1009                 if (bits >= 16777216)
1010                         bits |= E5_EXTEND3;
1011                 MSG_WriteShort(msg, number);
1012                 MSG_WriteByte(msg, bits & 0xFF);
1013                 if (bits & E5_EXTEND1)
1014                         MSG_WriteByte(msg, (bits >> 8) & 0xFF);
1015                 if (bits & E5_EXTEND2)
1016                         MSG_WriteByte(msg, (bits >> 16) & 0xFF);
1017                 if (bits & E5_EXTEND3)
1018                         MSG_WriteByte(msg, (bits >> 24) & 0xFF);
1019                 if (bits & E5_FLAGS)
1020                         MSG_WriteByte(msg, s->flags);
1021                 if (bits & E5_ORIGIN)
1022                 {
1023                         if (bits & E5_ORIGIN32)
1024                         {
1025                                 MSG_WriteFloat(msg, s->origin[0]);
1026                                 MSG_WriteFloat(msg, s->origin[1]);
1027                                 MSG_WriteFloat(msg, s->origin[2]);
1028                         }
1029                         else
1030                         {
1031                                 MSG_WriteShort(msg, (int)floor(s->origin[0] * 8 + 0.5f));
1032                                 MSG_WriteShort(msg, (int)floor(s->origin[1] * 8 + 0.5f));
1033                                 MSG_WriteShort(msg, (int)floor(s->origin[2] * 8 + 0.5f));
1034                         }
1035                 }
1036                 if (bits & E5_ANGLES)
1037                 {
1038                         if (bits & E5_ANGLES16)
1039                         {
1040                                 MSG_WriteShort(msg, (int)floor(s->angles[0] * (65536.0f / 360.0f) + 0.5f));
1041                                 MSG_WriteShort(msg, (int)floor(s->angles[1] * (65536.0f / 360.0f) + 0.5f));
1042                                 MSG_WriteShort(msg, (int)floor(s->angles[2] * (65536.0f / 360.0f) + 0.5f));
1043                         }
1044                         else
1045                         {
1046                                 MSG_WriteByte(msg, (int)floor(s->angles[0] * (256.0f / 360.0f) + 0.5f));
1047                                 MSG_WriteByte(msg, (int)floor(s->angles[1] * (256.0f / 360.0f) + 0.5f));
1048                                 MSG_WriteByte(msg, (int)floor(s->angles[2] * (256.0f / 360.0f) + 0.5f));
1049                         }
1050                 }
1051                 if (bits & E5_MODEL)
1052                 {
1053                         if (bits & E5_MODEL16)
1054                                 MSG_WriteShort(msg, s->modelindex);
1055                         else
1056                                 MSG_WriteByte(msg, s->modelindex);
1057                 }
1058                 if (bits & E5_FRAME)
1059                 {
1060                         if (bits & E5_FRAME16)
1061                                 MSG_WriteShort(msg, s->frame);
1062                         else
1063                                 MSG_WriteByte(msg, s->frame);
1064                 }
1065                 if (bits & E5_SKIN)
1066                         MSG_WriteByte(msg, s->flags);
1067                 if (bits & E5_EFFECTS)
1068                 {
1069                         if (bits & E5_EFFECTS32)
1070                                 MSG_WriteLong(msg, s->effects);
1071                         else if (bits & E5_EFFECTS16)
1072                                 MSG_WriteShort(msg, s->effects);
1073                         else
1074                                 MSG_WriteByte(msg, s->effects);
1075                 }
1076                 if (bits & E5_ALPHA)
1077                         MSG_WriteByte(msg, s->flags);
1078                 if (bits & E5_SCALE)
1079                         MSG_WriteByte(msg, s->flags);
1080                 if (bits & E5_ATTACHMENT)
1081                 {
1082                         MSG_WriteShort(msg, s->tagentity);
1083                         MSG_WriteByte(msg, s->tagindex);
1084                 }
1085                 if (bits & E5_EXTERIORFORENTITY)
1086                         MSG_WriteShort(msg, s->tagentity);
1087                 if (bits & E5_LIGHT)
1088                 {
1089                         MSG_WriteShort(msg, s->light[0]);
1090                         MSG_WriteShort(msg, s->light[1]);
1091                         MSG_WriteShort(msg, s->light[2]);
1092                         MSG_WriteShort(msg, s->light[3]);
1093                 }
1094                 if (bits & E5_COLORMAP)
1095                         MSG_WriteByte(msg, s->colormap);
1096                 if (bits & E5_GLOW)
1097                 {
1098                         MSG_WriteByte(msg, s->glowsize);
1099                         MSG_WriteByte(msg, s->glowcolor);
1100                 }
1101         }
1102 }
1103
1104 int EntityFrame5_ReadUpdate(void)
1105 {
1106         number = MSG_ReadShort();
1107         e = cl_entities + (number & 0x7FFF);
1108         e->state_previous = e->state_current;
1109         if (number & 0x8000)
1110         {
1111                 if (number == 0x8000)
1112                 {
1113                         // end of entity list
1114                         return false;
1115                 }
1116                 // remove
1117                 number &= 0x7FFF;
1118                 e->state_current = defaultstate;
1119                 e->state_current.number = number;
1120                 return true;
1121         }
1122         else
1123         {
1124         }
1125 }
1126
1127 int cl_entityframe5_lastreceivedframenum;
1128
1129 void EntityFrame5_CL_ReadFrame(void)
1130 {
1131         int n, enumber;
1132         entity_t *ent;
1133         entity_state_t *s;
1134         // read the number of this frame to echo back in next input packet
1135         cl_entityframe5_lastreceivedframenum = MSG_ReadLong();
1136         // read entity numbers until we find a 0x8000
1137         // (which would be remove world entity, but is actually a terminator)
1138         while ((n = MSG_ReadShort()) != 0x8000)
1139         {
1140                 // get the entity number and look it up
1141                 enumber = n & 0x7FFF;
1142                 ent = cl_entities + enumber;
1143                 // slide the current into the previous slot
1144                 ent->state_previous = ent->state_current;
1145                 // read the update
1146                 s = &ent->state_current;
1147                 if (n & 0x8000)
1148                 {
1149                         // remove entity
1150                         *s = defaultstate;
1151                 }
1152                 else
1153                 {
1154                         // update entity
1155                         s->active = true;
1156                         EntityState_ReadFields(s, EntityState_ReadExtendBits());
1157                 }
1158                 // set the cl_entities_active flag
1159                 cl_entities_active[enumber] = s->active;
1160                 // set the update time
1161                 s->time = cl.mtime[0];
1162                 // fix the number (it gets wiped occasionally by copying from defaultstate)
1163                 s->number = enumber;
1164                 // check if we need to update the lerp stuff
1165                 if (s->active)
1166                         CL_MoveLerpEntityStates(&cl_entities[enumber]);
1167                 // print extra messages if desired
1168                 if (developer_networkentities.integer >= 2 && cl_entities[enumber].state_current.active != cl_entities[enumber].state_previous.active)
1169                 {
1170                         if (cl_entities[enumber].state_current.active)
1171                                 Con_Printf("entity #%i has become active\n", enumber);
1172                         else if (cl_entities[enumber].state_previous.active)
1173                                 Con_Printf("entity #%i has become inactive\n", enumber);
1174                 }
1175         }
1176 }
1177
1178 #define ENTITYFRAME5_MAXPACKETLOGS 64
1179 #define ENTITYFRAME5_MAXSTATES 128
1180
1181 typedef struct entityframe5_state_s
1182 {
1183         unsigned short entitynumber;
1184         qbyte active;
1185         qbyte activedirtybit;
1186         int dirtybits;
1187 }
1188 entityframe5_state_t;
1189
1190 typedef struct entityframe5_packetlog_s
1191 {
1192         int packetnumber;
1193         int numstates;
1194         entityframe5_state_t states[ENTITYFRAME5_MAXSTATES];
1195 }
1196 entityframe5_packetlog_t;
1197
1198 typedef struct entityframe5_s
1199 {
1200         int ackedframenum;
1201         entityframe5_packetlog_t packetlog[ENTITYFRAME5_MAXPACKETLOGS];
1202         qbyte activedirtybits[(MAX_EDICTS + 7) / 8];
1203         int dirtybits[MAX_EDICTS];
1204 }
1205 entityframe5_t;
1206
1207 void EntityFrame5_AckFrame(entityframe5_t *d, int framenum)
1208 {
1209         int i, j, k, l, dirtybits, activedirtybit;
1210         entityframe5_state_t *s, *s2;
1211         entityframe5_packetlog_t *p, *p2;
1212         if (framenum >= d->ackedframenum)
1213                 return;
1214         d->ackedframenum = framenum;
1215         // scan for packets made obsolete by this ack
1216         for (i = 0, p = d->packetlog;i < ENTITYFRAME5_MAXPACKETLOGS;i++, p++)
1217         {
1218                 // skip packets that are empty or in the future
1219                 if (p->packetnumber == 0 || p->packetnumber > framenum)
1220                         continue;
1221                 // if the packetnumber matches it is deleted without any processing 
1222                 // (since it was received).
1223                 // if the packet number is less than this ack it was lost and its
1224                 // important information will be repeated in this update if it is not
1225                 // already obsolete due to a later update.
1226                 if (p->packetnumber < framenum)
1227                 {
1228                         // packet was lost - merge dirtybits into the main array so they
1229                         // will be re-sent, but only if there is no newer update of that
1230                         // bit in the logs (as those will arrive before this update)
1231                         for (j = 0, s = p->states;j < p->numstates;j++, s++)
1232                         {
1233                                 activedirtybit = s->activedirtybit;
1234                                 dirtybits = s->dirtybits;
1235                                 // check for any newer updates to this entity
1236                                 for (k = 0, p2 = d->packetlog;k < ENTITYFRAME5_MAXPACKETLOGS;k++, p2++)
1237                                 {
1238                                         if (p2->packetnumber > framenum)
1239                                         {
1240                                                 for (l = 0, s2 = p2->states;l < p2->numstates;l++, p2++)
1241                                                 {
1242                                                         if (s2->entitynumber == s->entitynumber)
1243                                                         {
1244                                                                 activedirtybit &= ~s2->activedirtybit;
1245                                                                 dirtybits &= ~s2->dirtybits;
1246                                                                 break;
1247                                                         }
1248                                                 }
1249                                                 if (!activedirtybit && !dirtybits)
1250                                                         break;
1251                                         }
1252                                 }
1253                                 // if the bits haven't all been cleared, there were some bits
1254                                 // lost with this packet, so set them again now
1255                                 if (activedirtybit)
1256                                         d->activedirtybits[s->entitynumber / 8] |= 1 << (s->entitynumber & 7);
1257                                 if (dirtybits)
1258                                         d->dirtybits[s->entitynumber] |= dirtybits;
1259                         }
1260                 }
1261                 // delete this packet log as it is now obsolete
1262                 p->packetnumber = 0;
1263         }
1264 }
1265
1266 void EntityFrame5_WriteFrame(sizebuf_t *msg, int numstates, entity_state_t *states)
1267 {
1268 }
1269 */
1270