]> git.xonotic.org Git - xonotic/darkplaces.git/blob - cl_ents.c
Now with new Travis secret key.
[xonotic/darkplaces.git] / cl_ents.c
1 #include "quakedef.h"
2 #include "protocol.h"
3
4 int EntityState_ReadExtendBits(void)
5 {
6         unsigned int bits;
7         bits = MSG_ReadByte(&cl_message);
8         if (bits & 0x00000080)
9         {
10                 bits |= MSG_ReadByte(&cl_message) << 8;
11                 if (bits & 0x00008000)
12                 {
13                         bits |= MSG_ReadByte(&cl_message) << 16;
14                         if (bits & 0x00800000)
15                                 bits |= MSG_ReadByte(&cl_message) << 24;
16                 }
17         }
18         return bits;
19 }
20
21 void EntityState_ReadFields(entity_state_t *e, unsigned int bits)
22 {
23         if (cls.protocol == PROTOCOL_DARKPLACES2)
24         {
25                 if (bits & E_ORIGIN1)
26                         e->origin[0] = MSG_ReadCoord16i(&cl_message);
27                 if (bits & E_ORIGIN2)
28                         e->origin[1] = MSG_ReadCoord16i(&cl_message);
29                 if (bits & E_ORIGIN3)
30                         e->origin[2] = MSG_ReadCoord16i(&cl_message);
31         }
32         else
33         {
34                 if (bits & E_FLAGS)
35                         e->flags = MSG_ReadByte(&cl_message);
36                 if (e->flags & RENDER_LOWPRECISION)
37                 {
38                         if (bits & E_ORIGIN1)
39                                 e->origin[0] = MSG_ReadCoord16i(&cl_message);
40                         if (bits & E_ORIGIN2)
41                                 e->origin[1] = MSG_ReadCoord16i(&cl_message);
42                         if (bits & E_ORIGIN3)
43                                 e->origin[2] = MSG_ReadCoord16i(&cl_message);
44                 }
45                 else
46                 {
47                         if (bits & E_ORIGIN1)
48                                 e->origin[0] = MSG_ReadCoord32f(&cl_message);
49                         if (bits & E_ORIGIN2)
50                                 e->origin[1] = MSG_ReadCoord32f(&cl_message);
51                         if (bits & E_ORIGIN3)
52                                 e->origin[2] = MSG_ReadCoord32f(&cl_message);
53                 }
54         }
55         if ((cls.protocol == PROTOCOL_DARKPLACES5 || cls.protocol == PROTOCOL_DARKPLACES6) && !(e->flags & RENDER_LOWPRECISION))
56         {
57                 if (bits & E_ANGLE1)
58                         e->angles[0] = MSG_ReadAngle16i(&cl_message);
59                 if (bits & E_ANGLE2)
60                         e->angles[1] = MSG_ReadAngle16i(&cl_message);
61                 if (bits & E_ANGLE3)
62                         e->angles[2] = MSG_ReadAngle16i(&cl_message);
63         }
64         else
65         {
66                 if (bits & E_ANGLE1)
67                         e->angles[0] = MSG_ReadAngle8i(&cl_message);
68                 if (bits & E_ANGLE2)
69                         e->angles[1] = MSG_ReadAngle8i(&cl_message);
70                 if (bits & E_ANGLE3)
71                         e->angles[2] = MSG_ReadAngle8i(&cl_message);
72         }
73         if (bits & E_MODEL1)
74                 e->modelindex = (e->modelindex & 0xFF00) | (unsigned int) MSG_ReadByte(&cl_message);
75         if (bits & E_MODEL2)
76                 e->modelindex = (e->modelindex & 0x00FF) | ((unsigned int) MSG_ReadByte(&cl_message) << 8);
77         if (bits & E_FRAME1)
78                 e->frame = (e->frame & 0xFF00) | (unsigned int) MSG_ReadByte(&cl_message);
79         if (bits & E_FRAME2)
80                 e->frame = (e->frame & 0x00FF) | ((unsigned int) MSG_ReadByte(&cl_message) << 8);
81         if (bits & E_EFFECTS1)
82                 e->effects = (e->effects & 0xFF00) | (unsigned int) MSG_ReadByte(&cl_message);
83         if (bits & E_EFFECTS2)
84                 e->effects = (e->effects & 0x00FF) | ((unsigned int) MSG_ReadByte(&cl_message) << 8);
85         if (bits & E_COLORMAP)
86                 e->colormap = MSG_ReadByte(&cl_message);
87         if (bits & E_SKIN)
88                 e->skin = MSG_ReadByte(&cl_message);
89         if (bits & E_ALPHA)
90                 e->alpha = MSG_ReadByte(&cl_message);
91         if (bits & E_SCALE)
92                 e->scale = MSG_ReadByte(&cl_message);
93         if (bits & E_GLOWSIZE)
94                 e->glowsize = MSG_ReadByte(&cl_message);
95         if (bits & E_GLOWCOLOR)
96                 e->glowcolor = MSG_ReadByte(&cl_message);
97         if (cls.protocol == PROTOCOL_DARKPLACES2)
98                 if (bits & E_FLAGS)
99                         e->flags = MSG_ReadByte(&cl_message);
100         if (bits & E_TAGATTACHMENT)
101         {
102                 e->tagentity = (unsigned short) MSG_ReadShort(&cl_message);
103                 e->tagindex = MSG_ReadByte(&cl_message);
104         }
105         if (bits & E_LIGHT)
106         {
107                 e->light[0] = (unsigned short) MSG_ReadShort(&cl_message);
108                 e->light[1] = (unsigned short) MSG_ReadShort(&cl_message);
109                 e->light[2] = (unsigned short) MSG_ReadShort(&cl_message);
110                 e->light[3] = (unsigned short) MSG_ReadShort(&cl_message);
111         }
112         if (bits & E_LIGHTSTYLE)
113                 e->lightstyle = MSG_ReadByte(&cl_message);
114         if (bits & E_LIGHTPFLAGS)
115                 e->lightpflags = MSG_ReadByte(&cl_message);
116
117         if (developer_networkentities.integer >= 2)
118         {
119                 Con_Printf("ReadFields e%i", e->number);
120
121                 if (bits & E_ORIGIN1)
122                         Con_Printf(" E_ORIGIN1 %f", e->origin[0]);
123                 if (bits & E_ORIGIN2)
124                         Con_Printf(" E_ORIGIN2 %f", e->origin[1]);
125                 if (bits & E_ORIGIN3)
126                         Con_Printf(" E_ORIGIN3 %f", e->origin[2]);
127                 if (bits & E_ANGLE1)
128                         Con_Printf(" E_ANGLE1 %f", e->angles[0]);
129                 if (bits & E_ANGLE2)
130                         Con_Printf(" E_ANGLE2 %f", e->angles[1]);
131                 if (bits & E_ANGLE3)
132                         Con_Printf(" E_ANGLE3 %f", e->angles[2]);
133                 if (bits & (E_MODEL1 | E_MODEL2))
134                         Con_Printf(" E_MODEL %i", e->modelindex);
135
136                 if (bits & (E_FRAME1 | E_FRAME2))
137                         Con_Printf(" E_FRAME %i", e->frame);
138                 if (bits & (E_EFFECTS1 | E_EFFECTS2))
139                         Con_Printf(" E_EFFECTS %i", e->effects);
140                 if (bits & E_ALPHA)
141                         Con_Printf(" E_ALPHA %f", e->alpha / 255.0f);
142                 if (bits & E_SCALE)
143                         Con_Printf(" E_SCALE %f", e->scale / 16.0f);
144                 if (bits & E_COLORMAP)
145                         Con_Printf(" E_COLORMAP %i", e->colormap);
146                 if (bits & E_SKIN)
147                         Con_Printf(" E_SKIN %i", e->skin);
148
149                 if (bits & E_GLOWSIZE)
150                         Con_Printf(" E_GLOWSIZE %i", e->glowsize * 4);
151                 if (bits & E_GLOWCOLOR)
152                         Con_Printf(" E_GLOWCOLOR %i", e->glowcolor);
153
154                 if (bits & E_LIGHT)
155                         Con_Printf(" E_LIGHT %i:%i:%i:%i", e->light[0], e->light[1], e->light[2], e->light[3]);
156                 if (bits & E_LIGHTPFLAGS)
157                         Con_Printf(" E_LIGHTPFLAGS %i", e->lightpflags);
158
159                 if (bits & E_TAGATTACHMENT)
160                         Con_Printf(" E_TAGATTACHMENT e%i:%i", e->tagentity, e->tagindex);
161                 if (bits & E_LIGHTSTYLE)
162                         Con_Printf(" E_LIGHTSTYLE %i", e->lightstyle);
163                 Con_Print("\n");
164         }
165 }
166
167 // (client) adds a entity_frame to the database, for future reference
168 void EntityFrame_AddFrame_Client(entityframe_database_t *d, vec3_t eye, int framenum, int numentities, const entity_state_t *entitydata)
169 {
170         int n, e;
171         entity_frameinfo_t *info;
172
173         VectorCopy(eye, d->eye);
174
175         // figure out how many entity slots are used already
176         if (d->numframes)
177         {
178                 n = d->frames[d->numframes - 1].endentity - d->frames[0].firstentity;
179                 if (n + numentities > MAX_ENTITY_DATABASE || d->numframes >= MAX_ENTITY_HISTORY)
180                 {
181                         // ran out of room, dump database
182                         EntityFrame_ClearDatabase(d);
183                 }
184         }
185
186         info = &d->frames[d->numframes];
187         info->framenum = framenum;
188         e = -1000;
189         // make sure we check the newly added frame as well, but we haven't incremented numframes yet
190         for (n = 0;n <= d->numframes;n++)
191         {
192                 if (e >= d->frames[n].framenum)
193                 {
194                         if (e == framenum)
195                                 Con_Print("EntityFrame_AddFrame: tried to add out of sequence frame to database\n");
196                         else
197                                 Con_Print("EntityFrame_AddFrame: out of sequence frames in database\n");
198                         return;
199                 }
200                 e = d->frames[n].framenum;
201         }
202         // if database still has frames after that...
203         if (d->numframes)
204                 info->firstentity = d->frames[d->numframes - 1].endentity;
205         else
206                 info->firstentity = 0;
207         info->endentity = info->firstentity + numentities;
208         d->numframes++;
209
210         n = info->firstentity % MAX_ENTITY_DATABASE;
211         e = MAX_ENTITY_DATABASE - n;
212         if (e > numentities)
213                 e = numentities;
214         memcpy(d->entitydata + n, entitydata, sizeof(entity_state_t) * e);
215         if (numentities > e)
216                 memcpy(d->entitydata, entitydata + e, sizeof(entity_state_t) * (numentities - e));
217 }
218
219 // (client) reads a frame from network stream
220 void EntityFrame_CL_ReadFrame(void)
221 {
222         int i, number, removed;
223         entity_frame_t *f, *delta;
224         entity_state_t *e, *old, *oldend;
225         entity_t *ent;
226         entityframe_database_t *d;
227         if (!cl.entitydatabase)
228                 cl.entitydatabase = EntityFrame_AllocDatabase(cls.levelmempool);
229         d = cl.entitydatabase;
230         f = &d->framedata;
231         delta = &d->deltaframe;
232
233         EntityFrame_Clear(f, NULL, -1);
234
235         // read the frame header info
236         f->time = cl.mtime[0];
237         number = MSG_ReadLong(&cl_message);
238         f->framenum = MSG_ReadLong(&cl_message);
239         CL_NewFrameReceived(f->framenum);
240         f->eye[0] = MSG_ReadFloat(&cl_message);
241         f->eye[1] = MSG_ReadFloat(&cl_message);
242         f->eye[2] = MSG_ReadFloat(&cl_message);
243         EntityFrame_AckFrame(d, number);
244         EntityFrame_FetchFrame(d, number, delta);
245         old = delta->entitydata;
246         oldend = old + delta->numentities;
247         // read entities until we hit the magic 0xFFFF end tag
248         while ((number = (unsigned short) MSG_ReadShort(&cl_message)) != 0xFFFF && !cl_message.badread)
249         {
250                 if (cl_message.badread)
251                         Host_Error("EntityFrame_Read: read error");
252                 removed = number & 0x8000;
253                 number &= 0x7FFF;
254                 if (number >= MAX_EDICTS)
255                         Host_Error("EntityFrame_Read: number (%i) >= MAX_EDICTS (%i)", number, MAX_EDICTS);
256
257                 // seek to entity, while copying any skipped entities (assume unchanged)
258                 while (old < oldend && old->number < number)
259                 {
260                         if (f->numentities >= MAX_ENTITY_DATABASE)
261                                 Host_Error("EntityFrame_Read: entity list too big");
262                         f->entitydata[f->numentities] = *old++;
263                         f->entitydata[f->numentities++].time = cl.mtime[0];
264                 }
265                 if (removed)
266                 {
267                         if (old < oldend && old->number == number)
268                                 old++;
269                         else
270                                 Con_Printf("EntityFrame_Read: REMOVE on unused entity %i\n", number);
271                 }
272                 else
273                 {
274                         if (f->numentities >= MAX_ENTITY_DATABASE)
275                                 Host_Error("EntityFrame_Read: entity list too big");
276
277                         // reserve this slot
278                         e = f->entitydata + f->numentities++;
279
280                         if (old < oldend && old->number == number)
281                         {
282                                 // delta from old entity
283                                 *e = *old++;
284                         }
285                         else
286                         {
287                                 // delta from defaults
288                                 *e = defaultstate;
289                         }
290
291                         if (cl.num_entities <= number)
292                         {
293                                 cl.num_entities = number + 1;
294                                 if (number >= cl.max_entities)
295                                         CL_ExpandEntities(number);
296                         }
297                         cl.entities_active[number] = true;
298                         e->active = ACTIVE_NETWORK;
299                         e->time = cl.mtime[0];
300                         e->number = number;
301                         EntityState_ReadFields(e, EntityState_ReadExtendBits());
302                 }
303         }
304         while (old < oldend)
305         {
306                 if (f->numentities >= MAX_ENTITY_DATABASE)
307                         Host_Error("EntityFrame_Read: entity list too big");
308                 f->entitydata[f->numentities] = *old++;
309                 f->entitydata[f->numentities++].time = cl.mtime[0];
310         }
311         EntityFrame_AddFrame_Client(d, f->eye, f->framenum, f->numentities, f->entitydata);
312
313         memset(cl.entities_active, 0, cl.num_entities * sizeof(unsigned char));
314         number = 1;
315         for (i = 0;i < f->numentities;i++)
316         {
317                 for (;number < f->entitydata[i].number && number < cl.num_entities;number++)
318                 {
319                         if (cl.entities_active[number])
320                         {
321                                 cl.entities_active[number] = false;
322                                 cl.entities[number].state_current.active = ACTIVE_NOT;
323                         }
324                 }
325                 if (number >= cl.num_entities)
326                         break;
327                 // update the entity
328                 ent = &cl.entities[number];
329                 ent->state_previous = ent->state_current;
330                 ent->state_current = f->entitydata[i];
331                 CL_MoveLerpEntityStates(ent);
332                 // the entity lives again...
333                 cl.entities_active[number] = true;
334                 number++;
335         }
336         for (;number < cl.num_entities;number++)
337         {
338                 if (cl.entities_active[number])
339                 {
340                         cl.entities_active[number] = false;
341                         cl.entities[number].state_current.active = ACTIVE_NOT;
342                 }
343         }
344 }
345
346
347 // (client) returns the frame number of the most recent frame recieved
348 int EntityFrame_MostRecentlyRecievedFrameNum(entityframe_database_t *d)
349 {
350         if (d->numframes)
351                 return d->frames[d->numframes - 1].framenum;
352         else
353                 return -1;
354 }