added code for protocol 4, not hooked up or tested
[divverent/darkplaces.git] / protocol.c
1
2 #include "quakedef.h"
3
4 void ClearStateToDefault(entity_state_t *s)
5 {
6         memset(s, 0, sizeof(*s));
7         s->alpha = 255;
8         s->scale = 16;
9         s->glowcolor = 254;
10 }
11
12 void EntityState_Write(entity_state_t *ent, sizebuf_t *msg, entity_state_t *delta)
13 {
14         int bits;
15         vec3_t org, deltaorg;
16         if (ent->active)
17         {
18                 bits = 0;
19                 VectorCopy(ent->origin, org);
20                 VectorCopy(delta->origin, deltaorg);
21                 if (ent->flags & RENDER_LOWPRECISION)
22                 {
23                         if (org[0] > 0)
24                                 org[0] = (int) (org[0] + 0.5f);
25                         else
26                                 org[0] = (int) (org[0] - 0.5f);
27                         if (org[1] > 0)
28                                 org[1] = (int) (org[1] + 0.5f);
29                         else
30                                 org[1] = (int) (org[1] - 0.5f);
31                         if (org[2] > 0)
32                                 org[2] = (int) (org[2] + 0.5f);
33                         else
34                                 org[2] = (int) (org[2] - 0.5f);
35                 }
36                 if (delta->flags & RENDER_LOWPRECISION)
37                 {
38                         if (deltaorg[0] > 0)
39                                 deltaorg[0] = (int) (deltaorg[0] + 0.5f);
40                         else
41                                 deltaorg[0] = (int) (deltaorg[0] - 0.5f);
42                         if (deltaorg[1] > 0)
43                                 deltaorg[1] = (int) (deltaorg[1] + 0.5f);
44                         else
45                                 deltaorg[1] = (int) (deltaorg[1] - 0.5f);
46                         if (deltaorg[2] > 0)
47                                 deltaorg[2] = (int) (deltaorg[2] + 0.5f);
48                         else
49                                 deltaorg[2] = (int) (deltaorg[2] - 0.5f);
50                 }
51                 if (fabs(org[0] - deltaorg[0]) > 0.01f)
52                         bits |= E_ORIGIN1;
53                 if (fabs(org[1] - deltaorg[1]) > 0.01f)
54                         bits |= E_ORIGIN2;
55                 if (fabs(org[2] - deltaorg[2]) > 0.01f)
56                         bits |= E_ORIGIN3;
57                 if ((qbyte) (ent->angles[0] * (256.0f / 360.0f)) != (qbyte) (delta->angles[0] * (256.0f / 360.0f)))
58                         bits |= E_ANGLE1;
59                 if ((qbyte) (ent->angles[1] * (256.0f / 360.0f)) != (qbyte) (delta->angles[1] * (256.0f / 360.0f)))
60                         bits |= E_ANGLE2;
61                 if ((qbyte) (ent->angles[2] * (256.0f / 360.0f)) != (qbyte) (delta->angles[2] * (256.0f / 360.0f)))
62                         bits |= E_ANGLE3;
63                 if ((ent->modelindex ^ delta->modelindex) & 0x00FF)
64                         bits |= E_MODEL1;
65                 if ((ent->modelindex ^ delta->modelindex) & 0xFF00)
66                         bits |= E_MODEL2;
67                 if ((ent->frame ^ delta->frame) & 0x00FF)
68                         bits |= E_FRAME1;
69                 if ((ent->frame ^ delta->frame) & 0xFF00)
70                         bits |= E_FRAME2;
71                 if ((ent->effects ^ delta->effects) & 0x00FF)
72                         bits |= E_EFFECTS1;
73                 if ((ent->effects ^ delta->effects) & 0xFF00)
74                         bits |= E_EFFECTS2;
75                 if (ent->colormap != delta->colormap)
76                         bits |= E_COLORMAP;
77                 if (ent->skin != delta->skin)
78                         bits |= E_SKIN;
79                 if (ent->alpha != delta->alpha)
80                         bits |= E_ALPHA;
81                 if (ent->scale != delta->scale)
82                         bits |= E_SCALE;
83                 if (ent->glowsize != delta->glowsize)
84                         bits |= E_GLOWSIZE;
85                 if (ent->glowcolor != delta->glowcolor)
86                         bits |= E_GLOWCOLOR;
87                 if (ent->flags != delta->flags)
88                         bits |= E_FLAGS;
89                 if (ent->tagindex != delta->tagindex || ent->tagentity != delta->tagentity)
90                         bits |= E_TAGATTACHMENT;
91
92                 if (bits) // don't send anything if it hasn't changed
93                 {
94                         if (bits & 0xFF000000)
95                                 bits |= E_EXTEND3;
96                         if (bits & 0x00FF0000)
97                                 bits |= E_EXTEND2;
98                         if (bits & 0x0000FF00)
99                                 bits |= E_EXTEND1;
100
101                         MSG_WriteShort(msg, ent->number);
102                         MSG_WriteByte(msg, bits & 0xFF);
103                         if (bits & E_EXTEND1)
104                         {
105                                 MSG_WriteByte(msg, (bits >> 8) & 0xFF);
106                                 if (bits & E_EXTEND2)
107                                 {
108                                         MSG_WriteByte(msg, (bits >> 16) & 0xFF);
109                                         if (bits & E_EXTEND3)
110                                                 MSG_WriteByte(msg, (bits >> 24) & 0xFF);
111                                 }
112                         }
113                         // LordHavoc: have to write flags first, as they can modify protocol
114                         if (bits & E_FLAGS)
115                                 MSG_WriteByte(msg, ent->flags);
116                         if (ent->flags & RENDER_LOWPRECISION)
117                         {
118                                 if (bits & E_ORIGIN1)
119                                         MSG_WriteShort(msg, org[0]);
120                                 if (bits & E_ORIGIN2)
121                                         MSG_WriteShort(msg, org[1]);
122                                 if (bits & E_ORIGIN3)
123                                         MSG_WriteShort(msg, org[2]);
124                         }
125                         else
126                         {
127                                 if (bits & E_ORIGIN1)
128                                         MSG_WriteFloat(msg, org[0]);
129                                 if (bits & E_ORIGIN2)
130                                         MSG_WriteFloat(msg, org[1]);
131                                 if (bits & E_ORIGIN3)
132                                         MSG_WriteFloat(msg, org[2]);
133                         }
134                         if (bits & E_ANGLE1)
135                                 MSG_WriteAngle(msg, ent->angles[0]);
136                         if (bits & E_ANGLE2)
137                                 MSG_WriteAngle(msg, ent->angles[1]);
138                         if (bits & E_ANGLE3)
139                                 MSG_WriteAngle(msg, ent->angles[2]);
140                         if (bits & E_MODEL1)
141                                 MSG_WriteByte(msg, ent->modelindex & 0xFF);
142                         if (bits & E_MODEL2)
143                                 MSG_WriteByte(msg, (ent->modelindex >> 8) & 0xFF);
144                         if (bits & E_FRAME1)
145                                 MSG_WriteByte(msg, ent->frame & 0xFF);
146                         if (bits & E_FRAME2)
147                                 MSG_WriteByte(msg, (ent->frame >> 8) & 0xFF);
148                         if (bits & E_EFFECTS1)
149                                 MSG_WriteByte(msg, ent->effects & 0xFF);
150                         if (bits & E_EFFECTS2)
151                                 MSG_WriteByte(msg, (ent->effects >> 8) & 0xFF);
152                         if (bits & E_COLORMAP)
153                                 MSG_WriteByte(msg, ent->colormap);
154                         if (bits & E_SKIN)
155                                 MSG_WriteByte(msg, ent->skin);
156                         if (bits & E_ALPHA)
157                                 MSG_WriteByte(msg, ent->alpha);
158                         if (bits & E_SCALE)
159                                 MSG_WriteByte(msg, ent->scale);
160                         if (bits & E_GLOWSIZE)
161                                 MSG_WriteByte(msg, ent->glowsize);
162                         if (bits & E_GLOWCOLOR)
163                                 MSG_WriteByte(msg, ent->glowcolor);
164                         if (bits & E_TAGATTACHMENT)
165                         {
166                                 MSG_WriteShort(msg, ent->tagentity);
167                                 MSG_WriteByte(msg, ent->tagindex);
168                         }
169                 }
170         }
171         else if (!delta->active)
172                 MSG_WriteShort(msg, ent->number | 0x8000);
173 }
174
175 void EntityState_Read(entity_state_t *e, entity_state_t *delta, int number)
176 {
177         int bits;
178         memcpy(e, delta, sizeof(*e));
179         e->active = true;
180         e->time = cl.mtime[0];
181         e->number = number;
182
183         bits = MSG_ReadByte();
184         if (bits & E_EXTEND1)
185         {
186                 bits |= MSG_ReadByte() << 8;
187                 if (bits & E_EXTEND2)
188                 {
189                         bits |= MSG_ReadByte() << 16;
190                         if (bits & E_EXTEND3)
191                                 bits |= MSG_ReadByte() << 24;
192                 }
193         }
194
195         if (dpprotocol == DPPROTOCOL_VERSION2)
196         {
197                 if (bits & E_ORIGIN1)
198                         e->origin[0] = (signed short) MSG_ReadShort();
199                 if (bits & E_ORIGIN2)
200                         e->origin[1] = (signed short) MSG_ReadShort();
201                 if (bits & E_ORIGIN3)
202                         e->origin[2] = (signed short) MSG_ReadShort();
203         }
204         else
205         {
206                 if (bits & E_FLAGS)
207                         e->flags = MSG_ReadByte();
208                 if (e->flags & RENDER_LOWPRECISION || dpprotocol == DPPROTOCOL_VERSION2)
209                 {
210                         if (bits & E_ORIGIN1)
211                                 e->origin[0] = (signed short) MSG_ReadShort();
212                         if (bits & E_ORIGIN2)
213                                 e->origin[1] = (signed short) MSG_ReadShort();
214                         if (bits & E_ORIGIN3)
215                                 e->origin[2] = (signed short) MSG_ReadShort();
216                 }
217                 else
218                 {
219                         if (bits & E_ORIGIN1)
220                                 e->origin[0] = MSG_ReadFloat();
221                         if (bits & E_ORIGIN2)
222                                 e->origin[1] = MSG_ReadFloat();
223                         if (bits & E_ORIGIN3)
224                                 e->origin[2] = MSG_ReadFloat();
225                 }
226         }
227         if (bits & E_ANGLE1)
228                 e->angles[0] = MSG_ReadAngle();
229         if (bits & E_ANGLE2)
230                 e->angles[1] = MSG_ReadAngle();
231         if (bits & E_ANGLE3)
232                 e->angles[2] = MSG_ReadAngle();
233         if (bits & E_MODEL1)
234                 e->modelindex = (e->modelindex & 0xFF00) | (unsigned int) MSG_ReadByte();
235         if (bits & E_MODEL2)
236                 e->modelindex = (e->modelindex & 0x00FF) | ((unsigned int) MSG_ReadByte() << 8);
237         if (bits & E_FRAME1)
238                 e->frame = (e->frame & 0xFF00) | (unsigned int) MSG_ReadByte();
239         if (bits & E_FRAME2)
240                 e->frame = (e->frame & 0x00FF) | ((unsigned int) MSG_ReadByte() << 8);
241         if (bits & E_EFFECTS1)
242                 e->effects = (e->effects & 0xFF00) | (unsigned int) MSG_ReadByte();
243         if (bits & E_EFFECTS2)
244                 e->effects = (e->effects & 0x00FF) | ((unsigned int) MSG_ReadByte() << 8);
245         if (bits & E_COLORMAP)
246                 e->colormap = MSG_ReadByte();
247         if (bits & E_SKIN)
248                 e->skin = MSG_ReadByte();
249         if (bits & E_ALPHA)
250                 e->alpha = MSG_ReadByte();
251         if (bits & E_SCALE)
252                 e->scale = MSG_ReadByte();
253         if (bits & E_GLOWSIZE)
254                 e->glowsize = MSG_ReadByte();
255         if (bits & E_GLOWCOLOR)
256                 e->glowcolor = MSG_ReadByte();
257         if (dpprotocol == DPPROTOCOL_VERSION2)
258                 if (bits & E_FLAGS)
259                         e->flags = MSG_ReadByte();
260         if (bits & E_TAGATTACHMENT)
261         {
262                 e->tagentity = MSG_ReadShort();
263                 e->tagindex = MSG_ReadByte();
264         }
265 }
266
267 // (server) clears the database to contain no frames (thus delta compression compresses against nothing)
268 void EntityFrame_ClearDatabase(entity_database_t *d)
269 {
270         memset(d, 0, sizeof(*d));
271 }
272
273 // (server and client) removes frames older than 'frame' from database
274 void EntityFrame_AckFrame(entity_database_t *d, int frame)
275 {
276         int i;
277         if (d->ackframe < frame)
278                 d->ackframe = frame;
279         for (i = 0;i < d->numframes && d->frames[i].framenum < frame;i++);
280         // ignore outdated frame acks (out of order packets)
281         if (i == 0)
282                 return;
283         d->numframes -= i;
284         // if some queue is left, slide it down to beginning of array
285         if (d->numframes)
286                 memmove(&d->frames[0], &d->frames[i], sizeof(d->frames[0]) * d->numframes);
287 }
288
289 // (server) clears frame, to prepare for adding entities
290 void EntityFrame_Clear(entity_frame_t *f, vec3_t eye, int framenum)
291 {
292         f->time = 0;
293         f->framenum = framenum;
294         f->numentities = 0;
295         if (eye == NULL)
296         {
297                 VectorClear(f->eye);
298         }
299         else
300         {
301                 VectorCopy(eye, f->eye);
302         }
303 }
304
305 // (server) adds an entity to frame
306 void EntityFrame_AddEntity(entity_frame_t *f, entity_state_t *s)
307 {
308         if (f->numentities < MAX_ENTITY_DATABASE)
309         {
310                 f->entitydata[f->numentities] = *s;
311                 f->entitydata[f->numentities++].active = true;
312         }
313 }
314
315 // (server and client) reads a frame from the database
316 void EntityFrame_FetchFrame(entity_database_t *d, int framenum, entity_frame_t *f)
317 {
318         int i, n;
319         EntityFrame_Clear(f, NULL, -1);
320         for (i = 0;i < d->numframes && d->frames[i].framenum < framenum;i++);
321         if (i < d->numframes && framenum == d->frames[i].framenum)
322         {
323                 f->framenum = framenum;
324                 f->numentities = d->frames[i].endentity - d->frames[i].firstentity;
325                 n = MAX_ENTITY_DATABASE - (d->frames[i].firstentity % MAX_ENTITY_DATABASE);
326                 if (n > f->numentities)
327                         n = f->numentities;
328                 memcpy(f->entitydata, d->entitydata + d->frames[i].firstentity % MAX_ENTITY_DATABASE, sizeof(*f->entitydata) * n);
329                 if (f->numentities > n)
330                         memcpy(f->entitydata + n, d->entitydata, sizeof(*f->entitydata) * (f->numentities - n));
331                 VectorCopy(d->eye, f->eye);
332         }
333 }
334
335 // (server and client) adds a entity_frame to the database, for future reference
336 void EntityFrame_AddFrame(entity_database_t *d, entity_frame_t *f)
337 {
338         int n, e;
339         entity_frameinfo_t *info;
340
341         VectorCopy(f->eye, d->eye);
342
343         // figure out how many entity slots are used already
344         if (d->numframes)
345         {
346                 n = d->frames[d->numframes - 1].endentity - d->frames[0].firstentity;
347                 if (n + f->numentities > MAX_ENTITY_DATABASE || d->numframes >= MAX_ENTITY_HISTORY)
348                 {
349                         // ran out of room, dump database
350                         EntityFrame_ClearDatabase(d);
351                 }
352         }
353
354         info = &d->frames[d->numframes];
355         info->framenum = f->framenum;
356         e = -1000;
357         // make sure we check the newly added frame as well, but we haven't incremented numframes yet
358         for (n = 0;n <= d->numframes;n++)
359         {
360                 if (e >= d->frames[n].framenum)
361                 {
362                         if (e == f->framenum)
363                                 Con_Printf("EntityFrame_AddFrame: tried to add out of sequence frame to database\n");
364                         else
365                                 Con_Printf("EntityFrame_AddFrame: out of sequence frames in database\n");
366                         return;
367                 }
368                 e = d->frames[n].framenum;
369         }
370         // if database still has frames after that...
371         if (d->numframes)
372                 info->firstentity = d->frames[d->numframes - 1].endentity;
373         else
374                 info->firstentity = 0;
375         info->endentity = info->firstentity + f->numentities;
376         d->numframes++;
377
378         n = info->firstentity % MAX_ENTITY_DATABASE;
379         e = MAX_ENTITY_DATABASE - n;
380         if (e > f->numentities)
381                 e = f->numentities;
382         memcpy(d->entitydata + n, f->entitydata, sizeof(entity_state_t) * e);
383         if (f->numentities > e)
384                 memcpy(d->entitydata, f->entitydata + e, sizeof(entity_state_t) * (f->numentities - e));
385 }
386
387 // (server) writes a frame to network stream
388 static entity_frame_t deltaframe; // FIXME?
389 void EntityFrame_Write(entity_database_t *d, entity_frame_t *f, sizebuf_t *msg)
390 {
391         int i, onum, number;
392         entity_frame_t *o = &deltaframe;
393         entity_state_t *ent, *delta, baseline;
394
395         EntityFrame_AddFrame(d, f);
396
397         ClearStateToDefault(&baseline);
398         EntityFrame_FetchFrame(d, d->ackframe > 0 ? d->ackframe : -1, o);
399         MSG_WriteByte (msg, svc_entities);
400         MSG_WriteLong (msg, o->framenum);
401         MSG_WriteLong (msg, f->framenum);
402         MSG_WriteFloat (msg, f->eye[0]);
403         MSG_WriteFloat (msg, f->eye[1]);
404         MSG_WriteFloat (msg, f->eye[2]);
405
406         onum = 0;
407         for (i = 0;i < f->numentities;i++)
408         {
409                 ent = f->entitydata + i;
410                 number = ent->number;
411                 for (;onum < o->numentities && o->entitydata[onum].number < number;onum++)
412                 {
413                         // write remove message
414                         MSG_WriteShort(msg, o->entitydata[onum].number | 0x8000);
415                 }
416                 if (onum < o->numentities && (o->entitydata[onum].number == number))
417                 {
418                         // delta from previous frame
419                         delta = o->entitydata + onum;
420                         // advance to next entity in delta frame
421                         onum++;
422                 }
423                 else
424                 {
425                         // delta from baseline
426                         delta = &baseline;
427                 }
428                 EntityState_Write(ent, msg, delta);
429         }
430         for (;onum < o->numentities;onum++)
431         {
432                 // write remove message
433                 MSG_WriteShort(msg, o->entitydata[onum].number | 0x8000);
434         }
435         MSG_WriteShort(msg, 0xFFFF);
436 }
437
438 // (client) reads a frame from network stream
439 static entity_frame_t framedata; // FIXME?
440 void EntityFrame_Read(entity_database_t *d)
441 {
442         int number, removed;
443         entity_frame_t *f = &framedata, *delta = &deltaframe;
444         entity_state_t *e, baseline, *old, *oldend, *edelta;
445
446         ClearStateToDefault(&baseline);
447
448         EntityFrame_Clear(f, NULL, -1);
449
450         // read the frame header info
451         f->time = cl.mtime[0];
452         number = MSG_ReadLong();
453         f->framenum = MSG_ReadLong();
454         f->eye[0] = MSG_ReadFloat();
455         f->eye[1] = MSG_ReadFloat();
456         f->eye[2] = MSG_ReadFloat();
457         EntityFrame_AckFrame(d, number);
458         EntityFrame_FetchFrame(d, number, delta);
459         old = delta->entitydata;
460         oldend = old + delta->numentities;
461         // read entities until we hit the magic 0xFFFF end tag
462         while ((number = (unsigned short) MSG_ReadShort()) != 0xFFFF)
463         {
464                 if (msg_badread)
465                         Host_Error("EntityFrame_Read: read error\n");
466                 removed = number & 0x8000;
467                 number &= 0x7FFF;
468                 if (number >= MAX_EDICTS)
469                         Host_Error("EntityFrame_Read: number (%i) >= MAX_EDICTS (%i)\n", number, MAX_EDICTS);
470
471                 // seek to entity, while copying any skipped entities (assume unchanged)
472                 while (old < oldend && old->number < number)
473                 {
474                         if (f->numentities >= MAX_ENTITY_DATABASE)
475                                 Host_Error("EntityFrame_Read: entity list too big\n");
476                         memcpy(f->entitydata + f->numentities, old, sizeof(entity_state_t));
477                         f->entitydata[f->numentities].time = cl.mtime[0];
478                         old++;
479                         f->numentities++;
480                 }
481                 if (removed)
482                 {
483                         if (old < oldend && old->number == number)
484                                 old++;
485                         else
486                                 Con_Printf("EntityFrame_Read: REMOVE on unused entity %i\n", number);
487                 }
488                 else
489                 {
490                         if (f->numentities >= MAX_ENTITY_DATABASE)
491                                 Host_Error("EntityFrame_Read: entity list too big\n");
492
493                         // reserve this slot
494                         e = f->entitydata + f->numentities++;
495
496                         if (old < oldend && old->number == number)
497                         {
498                                 // delta from old entity
499                                 edelta = old++;
500                         }
501                         else
502                         {
503                                 // delta from baseline
504                                 edelta = &baseline;
505                         }
506
507                         EntityState_Read(e, edelta, number);
508                 }
509         }
510         while (old < oldend)
511         {
512                 if (f->numentities >= MAX_ENTITY_DATABASE)
513                         Host_Error("EntityFrame_Read: entity list too big\n");
514                 memcpy(f->entitydata + f->numentities, old, sizeof(entity_state_t));
515                 f->entitydata[f->numentities].time = cl.mtime[0];
516                 old++;
517                 f->numentities++;
518         }
519         EntityFrame_AddFrame(d, f);
520 }
521
522
523 // (client) returns the frame number of the most recent frame recieved
524 int EntityFrame_MostRecentlyRecievedFrameNum(entity_database_t *d)
525 {
526         if (d->numframes)
527                 return d->frames[d->numframes - 1].framenum;
528         else
529                 return -1;
530 }
531
532
533
534
535
536
537 static int EntityFrame4_SV_ChooseCommitToReplace(entity_database4_t *d)
538 {
539         int i, best, bestframenum;
540         best = 0;
541         bestframenum = d->commit[0].framenum;
542         for (i = 0;i < MAX_ENTITY_HISTORY;i++)
543         {
544                 if (!d->commit[i].numentities)
545                         return i;
546                 if (bestframenum > d->commit[i].framenum)
547                 {
548                         bestframenum = d->commit[i].framenum;
549                         best = i;
550                 }
551         }
552         return best;
553 }
554
555 static entity_state_t *EntityFrame4_GetReferenceEntity(entity_database4_t *d, int number)
556 {
557         if (d->maxreferenceentities <= number)
558         {
559                 int oldmax = d->maxreferenceentities;
560                 entity_state_t *oldentity = d->referenceentity;
561                 d->maxreferenceentities = (number + 15) & ~7;
562                 d->referenceentity = Mem_Alloc(d->mempool, d->maxreferenceentities * sizeof(*d->referenceentity));
563                 if (oldentity)
564                 {
565                         memcpy(d->referenceentity, oldentity, oldmax * sizeof(*d->referenceentity));
566                         Mem_Free(oldentity);
567                 }
568                 // clear the newly created entities
569                 for (;oldmax < d->maxreferenceentities;oldmax++)
570                         ClearStateToDefault(d->referenceentity + oldmax);
571         }
572         return d->referenceentity + number;
573 }
574
575 static void EntityFrame4_AddCommitEntity(entity_database4_t *d, entity_state_t *s)
576 {
577         // resize commit's entity list if full
578         if (d->currentcommit->maxentities <= d->currentcommit->numentities)
579         {
580                 entity_state_t *oldentity = d->currentcommit->entity;
581                 d->currentcommit->maxentities += 8;
582                 d->currentcommit->entity = Mem_Alloc(d->mempool, d->currentcommit->maxentities * sizeof(*d->currentcommit->entity));
583                 if (oldentity)
584                 {
585                         memcpy(d->currentcommit->entity, oldentity, d->currentcommit->numentities * sizeof(*d->currentcommit->entity));
586                         Mem_Free(oldentity);
587                 }
588         }
589         d->currentcommit->entity[d->currentcommit->numentities++] = *s;
590 }
591
592 entity_database4_t *EntityFrame4_AllocDatabase(mempool_t *pool)
593 {
594         entity_database4_t *d;
595         d = Mem_Alloc(pool, sizeof(*d));
596         d->mempool = pool;
597         d->referenceframenum = -1;
598         return d;
599 }
600
601 void EntityFrame4_FreeDatabase(entity_database4_t *d)
602 {
603         int i;
604         for (i = 0;i < MAX_ENTITY_HISTORY;i++)
605                 if (d->commit[i].entity)
606                         Mem_Free(d->commit[i].entity);
607         if (d->referenceentity)
608                 Mem_Free(d->referenceentity);
609         Mem_Free(d);
610 }
611
612 void EntityFrame4_ResetDatabase(entity_database4_t *d)
613 {
614         int i;
615         d->referenceframenum = -1;
616         for (i = 0;i < MAX_ENTITY_HISTORY;i++)
617                 d->commit[i].numentities = 0;
618 }
619
620 void EntityFrame4_AckFrame(entity_database4_t *d, int framenum)
621 {
622         int i, foundit = false;
623         // check if client is requesting no delta compression
624         if (framenum == -1)
625         {
626                 EntityFrame4_ResetDatabase(d);
627                 return;
628         }
629         for (i = 0;i < MAX_ENTITY_HISTORY;i++)
630         {
631                 if (d->commit[i].numentities && d->commit[i].framenum <= framenum)
632                 {
633                         if (d->commit[i].framenum == framenum)
634                         {
635                                 // apply commit to database
636                                 d->referenceframenum = d->commit[i].framenum;
637                                 while (d->commit[i].numentities--)
638                                         *EntityFrame4_GetReferenceEntity(d, d->commit[i].entity[d->commit[i].numentities].number) = d->commit[i].entity[d->commit[i].numentities];
639                                 foundit = true;
640                         }
641                         d->commit[i].numentities = 0;
642                         d->commit[i].framenum = -1;
643                 }
644         }
645         if (!foundit)
646                 Con_DPrintf("EntityFrame4_AckFrame: frame %i not found in database, expect glitches!\n", framenum);
647 }
648
649 void EntityFrame4_SV_WriteFrame_Begin(entity_database4_t *d, sizebuf_t *msg, int framenum)
650 {
651         d->currentcommit = d->commit + EntityFrame4_SV_ChooseCommitToReplace(d);
652         d->currentcommit->numentities = 0;
653         d->currentcommit->framenum = framenum;
654         MSG_WriteByte(msg, svc_entities);
655         MSG_WriteLong(msg, d->referenceframenum);
656         MSG_WriteLong(msg, d->currentcommit->framenum);
657 }
658
659 int EntityFrame4_SV_WriteFrame_Entity(entity_database4_t *d, sizebuf_t *msg, int maxbytes, entity_state_t *s)
660 {
661         qbyte data[128];
662         sizebuf_t buf;
663         entity_state_t *e;
664         // prepare the buffer
665         memset(&buf, 0, sizeof(buf));
666         buf.data = data;
667         buf.maxsize = sizeof(data);
668         // make the message
669         e = EntityFrame4_GetReferenceEntity(d, s->number);
670         if (s->active)
671         {
672                 // entity exists, send an update
673                 EntityState_Write(s, &buf, e);
674         }
675         else if (e->active)
676         {
677                 // entity used to exist but doesn't anymore, send remove
678                 MSG_WriteShort(&buf, s->number | 0x8000);
679         }
680         // if the message is empty, skip out now
681         if (!buf.cursize)
682                 return true;
683         // if the commit is full, we're done
684         if (msg->cursize + buf.cursize + 2 >= min(msg->maxsize, maxbytes))
685                 return false;
686         // add the entity to the commit
687         EntityFrame4_AddCommitEntity(d, s);
688         // write the message to the packet
689         SZ_Write(msg, buf.data, buf.cursize);
690         // carry on
691         return true;
692 }
693
694 void EntityFrame4_SV_WriteFrame_End(entity_database4_t *d, sizebuf_t *msg)
695 {
696         // remove world message (invalid, and thus a good terminator)
697         MSG_WriteShort(msg, 0x8000);
698         // just to be sure
699         d->currentcommit = NULL;
700 }
701
702 void EntityFrame4_CL_ReadFrame(entity_database4_t *d)
703 {
704         int i, n, number, referenceframenum, framenum;
705         referenceframenum = MSG_ReadLong();
706         framenum = MSG_ReadLong();
707         EntityFrame4_AckFrame(d, referenceframenum);
708         for (i = 0;i < MAX_ENTITY_HISTORY;i++)
709                 if (!d->commit[i].numentities)
710                         break;
711         if (i < MAX_ENTITY_HISTORY)
712         {
713                 d->currentcommit = d->commit + i;
714                 d->currentcommit->framenum = framenum;
715                 d->currentcommit->numentities = 0;
716         }
717         else
718         {
719                 Con_Printf("EntityFrame4_CL_ReadFrame: error while decoding frame %i: database full, resetting, expect glitches!!\n", framenum);
720                 d->currentcommit = NULL;
721                 EntityFrame4_ResetDatabase(d);
722         }
723         while((n = MSG_ReadShort()) != 0x8000)
724         {
725                 number = n & 0x7FFF;
726                 cl_entities[number].state_previous = cl_entities[number].state_current;
727                 if (number & 0x8000)
728                 {
729                         ClearStateToDefault(&cl_entities[number].state_current);
730                         cl_entities[number].state_current.active = false;
731                         cl_entities[number].state_current.number = number;
732                 }
733                 else
734                         EntityState_Read(&cl_entities[number].state_current, EntityFrame4_GetReferenceEntity(d, number), number);
735                 if (d->currentcommit)
736                         EntityFrame4_AddCommitEntity(d, &cl_entities[number].state_current);
737         }
738         d->currentcommit = NULL;
739 }
740