]> git.xonotic.org Git - xonotic/darkplaces.git/blob - com_ents4.c
lhnet: Use the generic linked list
[xonotic/darkplaces.git] / com_ents4.c
1 #include "quakedef.h"
2 #include "protocol.h"
3
4 entityframe4_database_t *EntityFrame4_AllocDatabase(mempool_t *pool)
5 {
6         entityframe4_database_t *d;
7         d = (entityframe4_database_t *)Mem_Alloc(pool, sizeof(*d));
8         d->mempool = pool;
9         EntityFrame4_ResetDatabase(d);
10         return d;
11 }
12
13 void EntityFrame4_FreeDatabase(entityframe4_database_t *d)
14 {
15         int i;
16         for (i = 0;i < MAX_ENTITY_HISTORY;i++)
17                 if (d->commit[i].entity)
18                         Mem_Free(d->commit[i].entity);
19         if (d->referenceentity)
20                 Mem_Free(d->referenceentity);
21         Mem_Free(d);
22 }
23
24 void EntityFrame4_ResetDatabase(entityframe4_database_t *d)
25 {
26         int i;
27         d->referenceframenum = -1;
28         for (i = 0;i < MAX_ENTITY_HISTORY;i++)
29                 d->commit[i].numentities = 0;
30         for (i = 0;i < d->maxreferenceentities;i++)
31                 d->referenceentity[i] = defaultstate;
32 }
33
34 entity_state_t *EntityFrame4_GetReferenceEntity(entityframe4_database_t *d, int number)
35 {
36         if (d->maxreferenceentities <= number)
37         {
38                 int oldmax = d->maxreferenceentities;
39                 entity_state_t *oldentity = d->referenceentity;
40                 d->maxreferenceentities = (number + 15) & ~7;
41                 d->referenceentity = (entity_state_t *)Mem_Alloc(d->mempool, d->maxreferenceentities * sizeof(*d->referenceentity));
42                 if (oldentity)
43                 {
44                         memcpy(d->referenceentity, oldentity, oldmax * sizeof(*d->referenceentity));
45                         Mem_Free(oldentity);
46                 }
47                 // clear the newly created entities
48                 for (;oldmax < d->maxreferenceentities;oldmax++)
49                 {
50                         d->referenceentity[oldmax] = defaultstate;
51                         d->referenceentity[oldmax].number = oldmax;
52                 }
53         }
54         return d->referenceentity + number;
55 }
56
57 void EntityFrame4_AddCommitEntity(entityframe4_database_t *d, const entity_state_t *s)
58 {
59         // resize commit's entity list if full
60         if (d->currentcommit->maxentities <= d->currentcommit->numentities)
61         {
62                 entity_state_t *oldentity = d->currentcommit->entity;
63                 d->currentcommit->maxentities += 8;
64                 d->currentcommit->entity = (entity_state_t *)Mem_Alloc(d->mempool, d->currentcommit->maxentities * sizeof(*d->currentcommit->entity));
65                 if (oldentity)
66                 {
67                         memcpy(d->currentcommit->entity, oldentity, d->currentcommit->numentities * sizeof(*d->currentcommit->entity));
68                         Mem_Free(oldentity);
69                 }
70         }
71         d->currentcommit->entity[d->currentcommit->numentities++] = *s;
72 }
73
74 int EntityFrame4_AckFrame(entityframe4_database_t *d, int framenum, int servermode)
75 {
76         int i, j, found;
77         entity_database4_commit_t *commit;
78         if (framenum == -1)
79         {
80                 // reset reference, but leave commits alone
81                 d->referenceframenum = -1;
82                 for (i = 0;i < d->maxreferenceentities;i++)
83                         d->referenceentity[i] = defaultstate;
84                 // if this is the server, remove commits
85                 for (i = 0, commit = d->commit;i < MAX_ENTITY_HISTORY;i++, commit++)
86                         commit->numentities = 0;
87                 found = true;
88         }
89         else if (d->referenceframenum == framenum)
90                 found = true;
91         else
92         {
93                 found = false;
94                 for (i = 0, commit = d->commit;i < MAX_ENTITY_HISTORY;i++, commit++)
95                 {
96                         if (commit->numentities && commit->framenum <= framenum)
97                         {
98                                 if (commit->framenum == framenum)
99                                 {
100                                         found = true;
101                                         d->referenceframenum = framenum;
102                                         if (developer_networkentities.integer >= 3)
103                                         {
104                                                 for (j = 0;j < commit->numentities;j++)
105                                                 {
106                                                         entity_state_t *s = EntityFrame4_GetReferenceEntity(d, commit->entity[j].number);
107                                                         if (commit->entity[j].active != s->active)
108                                                         {
109                                                                 if (commit->entity[j].active == ACTIVE_NETWORK)
110                                                                         Con_Printf("commit entity %i has become active (modelindex %i)\n", commit->entity[j].number, commit->entity[j].modelindex);
111                                                                 else
112                                                                         Con_Printf("commit entity %i has become inactive (modelindex %i)\n", commit->entity[j].number, commit->entity[j].modelindex);
113                                                         }
114                                                         *s = commit->entity[j];
115                                                 }
116                                         }
117                                         else
118                                                 for (j = 0;j < commit->numentities;j++)
119                                                         *EntityFrame4_GetReferenceEntity(d, commit->entity[j].number) = commit->entity[j];
120                                 }
121                                 commit->numentities = 0;
122                         }
123                 }
124         }
125         if (developer_networkentities.integer >= 1)
126         {
127                 Con_Printf("ack ref:%i database updated to: ref:%i commits:", framenum, d->referenceframenum);
128                 for (i = 0;i < MAX_ENTITY_HISTORY;i++)
129                         if (d->commit[i].numentities)
130                                 Con_Printf(" %i", d->commit[i].framenum);
131                 Con_Print("\n");
132         }
133         return found;
134 }