]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - cl_ents5.c
cmd: Use reentrant mutex for cbufs. Fixes deadlock when expanding aliases in some...
[xonotic/darkplaces.git] / cl_ents5.c
1 #include "quakedef.h"
2 #include "protocol.h"
3
4 static void EntityState5_ReadUpdate(entity_state_t *s, int number)
5 {
6         int bits;
7         int startoffset = cl_message.readcount;
8         int bytes = 0;
9         bits = MSG_ReadByte(&cl_message);
10         if (bits & E5_EXTEND1)
11         {
12                 bits |= MSG_ReadByte(&cl_message) << 8;
13                 if (bits & E5_EXTEND2)
14                 {
15                         bits |= MSG_ReadByte(&cl_message) << 16;
16                         if (bits & E5_EXTEND3)
17                                 bits |= MSG_ReadByte(&cl_message) << 24;
18                 }
19         }
20         if (bits & E5_FULLUPDATE)
21         {
22                 *s = defaultstate;
23                 s->active = ACTIVE_NETWORK;
24         }
25         if (bits & E5_FLAGS)
26                 s->flags = MSG_ReadByte(&cl_message);
27         if (bits & E5_ORIGIN)
28         {
29                 if (bits & E5_ORIGIN32)
30                 {
31                         s->origin[0] = MSG_ReadCoord32f(&cl_message);
32                         s->origin[1] = MSG_ReadCoord32f(&cl_message);
33                         s->origin[2] = MSG_ReadCoord32f(&cl_message);
34                 }
35                 else
36                 {
37                         s->origin[0] = MSG_ReadCoord13i(&cl_message);
38                         s->origin[1] = MSG_ReadCoord13i(&cl_message);
39                         s->origin[2] = MSG_ReadCoord13i(&cl_message);
40                 }
41         }
42         if (bits & E5_ANGLES)
43         {
44                 if (bits & E5_ANGLES16)
45                 {
46                         s->angles[0] = MSG_ReadAngle16i(&cl_message);
47                         s->angles[1] = MSG_ReadAngle16i(&cl_message);
48                         s->angles[2] = MSG_ReadAngle16i(&cl_message);
49                 }
50                 else
51                 {
52                         s->angles[0] = MSG_ReadAngle8i(&cl_message);
53                         s->angles[1] = MSG_ReadAngle8i(&cl_message);
54                         s->angles[2] = MSG_ReadAngle8i(&cl_message);
55                 }
56         }
57         if (bits & E5_MODEL)
58         {
59                 if (bits & E5_MODEL16)
60                         s->modelindex = (unsigned short) MSG_ReadShort(&cl_message);
61                 else
62                         s->modelindex = MSG_ReadByte(&cl_message);
63         }
64         if (bits & E5_FRAME)
65         {
66                 if (bits & E5_FRAME16)
67                         s->frame = (unsigned short) MSG_ReadShort(&cl_message);
68                 else
69                         s->frame = MSG_ReadByte(&cl_message);
70         }
71         if (bits & E5_SKIN)
72                 s->skin = MSG_ReadByte(&cl_message);
73         if (bits & E5_EFFECTS)
74         {
75                 if (bits & E5_EFFECTS32)
76                         s->effects = (unsigned int) MSG_ReadLong(&cl_message);
77                 else if (bits & E5_EFFECTS16)
78                         s->effects = (unsigned short) MSG_ReadShort(&cl_message);
79                 else
80                         s->effects = MSG_ReadByte(&cl_message);
81         }
82         if (bits & E5_ALPHA)
83                 s->alpha = MSG_ReadByte(&cl_message);
84         if (bits & E5_SCALE)
85                 s->scale = MSG_ReadByte(&cl_message);
86         if (bits & E5_COLORMAP)
87                 s->colormap = MSG_ReadByte(&cl_message);
88         if (bits & E5_ATTACHMENT)
89         {
90                 s->tagentity = (unsigned short) MSG_ReadShort(&cl_message);
91                 s->tagindex = MSG_ReadByte(&cl_message);
92         }
93         if (bits & E5_LIGHT)
94         {
95                 s->light[0] = (unsigned short) MSG_ReadShort(&cl_message);
96                 s->light[1] = (unsigned short) MSG_ReadShort(&cl_message);
97                 s->light[2] = (unsigned short) MSG_ReadShort(&cl_message);
98                 s->light[3] = (unsigned short) MSG_ReadShort(&cl_message);
99                 s->lightstyle = MSG_ReadByte(&cl_message);
100                 s->lightpflags = MSG_ReadByte(&cl_message);
101         }
102         if (bits & E5_GLOW)
103         {
104                 s->glowsize = MSG_ReadByte(&cl_message);
105                 s->glowcolor = MSG_ReadByte(&cl_message);
106         }
107         if (bits & E5_COLORMOD)
108         {
109                 s->colormod[0] = MSG_ReadByte(&cl_message);
110                 s->colormod[1] = MSG_ReadByte(&cl_message);
111                 s->colormod[2] = MSG_ReadByte(&cl_message);
112         }
113         if (bits & E5_GLOWMOD)
114         {
115                 s->glowmod[0] = MSG_ReadByte(&cl_message);
116                 s->glowmod[1] = MSG_ReadByte(&cl_message);
117                 s->glowmod[2] = MSG_ReadByte(&cl_message);
118         }
119         if (bits & E5_COMPLEXANIMATION)
120         {
121                 skeleton_t *skeleton;
122                 const dp_model_t *model;
123                 int modelindex;
124                 int type;
125                 int bonenum;
126                 int numbones;
127                 short pose7s[7];
128                 type = MSG_ReadByte(&cl_message);
129                 switch(type)
130                 {
131                 case 0:
132                         s->framegroupblend[0].frame = MSG_ReadShort(&cl_message);
133                         s->framegroupblend[1].frame = 0;
134                         s->framegroupblend[2].frame = 0;
135                         s->framegroupblend[3].frame = 0;
136                         s->framegroupblend[0].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
137                         s->framegroupblend[1].start = 0;
138                         s->framegroupblend[2].start = 0;
139                         s->framegroupblend[3].start = 0;
140                         s->framegroupblend[0].lerp = 1;
141                         s->framegroupblend[1].lerp = 0;
142                         s->framegroupblend[2].lerp = 0;
143                         s->framegroupblend[3].lerp = 0;
144                         break;
145                 case 1:
146                         s->framegroupblend[0].frame = MSG_ReadShort(&cl_message);
147                         s->framegroupblend[1].frame = MSG_ReadShort(&cl_message);
148                         s->framegroupblend[2].frame = 0;
149                         s->framegroupblend[3].frame = 0;
150                         s->framegroupblend[0].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
151                         s->framegroupblend[1].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
152                         s->framegroupblend[2].start = 0;
153                         s->framegroupblend[3].start = 0;
154                         s->framegroupblend[0].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
155                         s->framegroupblend[1].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
156                         s->framegroupblend[2].lerp = 0;
157                         s->framegroupblend[3].lerp = 0;
158                         break;
159                 case 2:
160                         s->framegroupblend[0].frame = MSG_ReadShort(&cl_message);
161                         s->framegroupblend[1].frame = MSG_ReadShort(&cl_message);
162                         s->framegroupblend[2].frame = MSG_ReadShort(&cl_message);
163                         s->framegroupblend[3].frame = 0;
164                         s->framegroupblend[0].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
165                         s->framegroupblend[1].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
166                         s->framegroupblend[2].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
167                         s->framegroupblend[3].start = 0;
168                         s->framegroupblend[0].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
169                         s->framegroupblend[1].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
170                         s->framegroupblend[2].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
171                         s->framegroupblend[3].lerp = 0;
172                         break;
173                 case 3:
174                         s->framegroupblend[0].frame = MSG_ReadShort(&cl_message);
175                         s->framegroupblend[1].frame = MSG_ReadShort(&cl_message);
176                         s->framegroupblend[2].frame = MSG_ReadShort(&cl_message);
177                         s->framegroupblend[3].frame = MSG_ReadShort(&cl_message);
178                         s->framegroupblend[0].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
179                         s->framegroupblend[1].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
180                         s->framegroupblend[2].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
181                         s->framegroupblend[3].start = cl.time - (unsigned short)MSG_ReadShort(&cl_message) * (1.0f / 1000.0f);
182                         s->framegroupblend[0].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
183                         s->framegroupblend[1].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
184                         s->framegroupblend[2].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
185                         s->framegroupblend[3].lerp = MSG_ReadByte(&cl_message) * (1.0f / 255.0f);
186                         break;
187                 case 4:
188                         if (!cl.engineskeletonobjects)
189                                 cl.engineskeletonobjects = (skeleton_t *) Mem_Alloc(cls.levelmempool, sizeof(*cl.engineskeletonobjects) * MAX_EDICTS);
190                         skeleton = &cl.engineskeletonobjects[number];
191                         modelindex = MSG_ReadShort(&cl_message);
192                         model = CL_GetModelByIndex(modelindex);
193                         numbones = MSG_ReadByte(&cl_message);
194                         if (model && numbones != model->num_bones)
195                                 Host_Error("E5_COMPLEXANIMATION: model has different number of bones than network packet describes\n");
196                         if (!skeleton->relativetransforms || skeleton->model != model)
197                         {
198                                 skeleton->model = model;
199                                 skeleton->relativetransforms = (matrix4x4_t *) Mem_Realloc(cls.levelmempool, skeleton->relativetransforms, sizeof(*skeleton->relativetransforms) * numbones);
200                                 for (bonenum = 0;bonenum < numbones;bonenum++)
201                                         skeleton->relativetransforms[bonenum] = identitymatrix;
202                         }
203                         for (bonenum = 0;bonenum < numbones;bonenum++)
204                         {
205                                 pose7s[0] = (short)MSG_ReadShort(&cl_message);
206                                 pose7s[1] = (short)MSG_ReadShort(&cl_message);
207                                 pose7s[2] = (short)MSG_ReadShort(&cl_message);
208                                 pose7s[3] = (short)MSG_ReadShort(&cl_message);
209                                 pose7s[4] = (short)MSG_ReadShort(&cl_message);
210                                 pose7s[5] = (short)MSG_ReadShort(&cl_message);
211                                 pose7s[6] = (short)MSG_ReadShort(&cl_message);
212                                 Matrix4x4_FromBonePose7s(skeleton->relativetransforms + bonenum, 1.0f / 64.0f, pose7s);
213                         }
214                         s->skeletonobject = *skeleton;
215                         break;
216                 default:
217                         Host_Error("E5_COMPLEXANIMATION: Parse error - unknown type %i\n", type);
218                         break;
219                 }
220         }
221         if (bits & E5_TRAILEFFECTNUM)
222                 s->traileffectnum = (unsigned short) MSG_ReadShort(&cl_message);
223
224
225         bytes = cl_message.readcount - startoffset;
226         if (developer_networkentities.integer >= 2)
227         {
228                 Con_Printf("ReadFields e%i (%i bytes)", number, bytes);
229
230                 if (bits & E5_ORIGIN)
231                         Con_Printf(" E5_ORIGIN %f %f %f", s->origin[0], s->origin[1], s->origin[2]);
232                 if (bits & E5_ANGLES)
233                         Con_Printf(" E5_ANGLES %f %f %f", s->angles[0], s->angles[1], s->angles[2]);
234                 if (bits & E5_MODEL)
235                         Con_Printf(" E5_MODEL %i", s->modelindex);
236                 if (bits & E5_FRAME)
237                         Con_Printf(" E5_FRAME %i", s->frame);
238                 if (bits & E5_SKIN)
239                         Con_Printf(" E5_SKIN %i", s->skin);
240                 if (bits & E5_EFFECTS)
241                         Con_Printf(" E5_EFFECTS %i", s->effects);
242                 if (bits & E5_FLAGS)
243                 {
244                         Con_Printf(" E5_FLAGS %i (", s->flags);
245                         if (s->flags & RENDER_STEP)
246                                 Con_Print(" STEP");
247                         if (s->flags & RENDER_GLOWTRAIL)
248                                 Con_Print(" GLOWTRAIL");
249                         if (s->flags & RENDER_VIEWMODEL)
250                                 Con_Print(" VIEWMODEL");
251                         if (s->flags & RENDER_EXTERIORMODEL)
252                                 Con_Print(" EXTERIORMODEL");
253                         if (s->flags & RENDER_LOWPRECISION)
254                                 Con_Print(" LOWPRECISION");
255                         if (s->flags & RENDER_COLORMAPPED)
256                                 Con_Print(" COLORMAPPED");
257                         if (s->flags & RENDER_SHADOW)
258                                 Con_Print(" SHADOW");
259                         if (s->flags & RENDER_LIGHT)
260                                 Con_Print(" LIGHT");
261                         if (s->flags & RENDER_NOSELFSHADOW)
262                                 Con_Print(" NOSELFSHADOW");
263                         Con_Print(")");
264                 }
265                 if (bits & E5_ALPHA)
266                         Con_Printf(" E5_ALPHA %f", s->alpha / 255.0f);
267                 if (bits & E5_SCALE)
268                         Con_Printf(" E5_SCALE %f", s->scale / 16.0f);
269                 if (bits & E5_COLORMAP)
270                         Con_Printf(" E5_COLORMAP %i", s->colormap);
271                 if (bits & E5_ATTACHMENT)
272                         Con_Printf(" E5_ATTACHMENT e%i:%i", s->tagentity, s->tagindex);
273                 if (bits & E5_LIGHT)
274                         Con_Printf(" E5_LIGHT %i:%i:%i:%i %i:%i", s->light[0], s->light[1], s->light[2], s->light[3], s->lightstyle, s->lightpflags);
275                 if (bits & E5_GLOW)
276                         Con_Printf(" E5_GLOW %i:%i", s->glowsize * 4, s->glowcolor);
277                 if (bits & E5_COLORMOD)
278                         Con_Printf(" E5_COLORMOD %f:%f:%f", s->colormod[0] / 32.0f, s->colormod[1] / 32.0f, s->colormod[2] / 32.0f);
279                 if (bits & E5_GLOWMOD)
280                         Con_Printf(" E5_GLOWMOD %f:%f:%f", s->glowmod[0] / 32.0f, s->glowmod[1] / 32.0f, s->glowmod[2] / 32.0f);
281                 if (bits & E5_COMPLEXANIMATION)
282                         Con_Printf(" E5_COMPLEXANIMATION");
283                 if (bits & E5_TRAILEFFECTNUM)
284                         Con_Printf(" E5_TRAILEFFECTNUM %i", s->traileffectnum);
285                 Con_Print("\n");
286         }
287 }
288
289 void EntityFrame5_CL_ReadFrame(void)
290 {
291         int n, enumber, framenum;
292         entity_t *ent;
293         entity_state_t *s;
294         // read the number of this frame to echo back in next input packet
295         framenum = MSG_ReadLong(&cl_message);
296         CL_NewFrameReceived(framenum);
297         if (cls.protocol != PROTOCOL_QUAKE && cls.protocol != PROTOCOL_QUAKEDP && cls.protocol != PROTOCOL_NEHAHRAMOVIE && cls.protocol != PROTOCOL_DARKPLACES1 && cls.protocol != PROTOCOL_DARKPLACES2 && cls.protocol != PROTOCOL_DARKPLACES3 && cls.protocol != PROTOCOL_DARKPLACES4 && cls.protocol != PROTOCOL_DARKPLACES5 && cls.protocol != PROTOCOL_DARKPLACES6)
298                 cls.servermovesequence = MSG_ReadLong(&cl_message);
299         // read entity numbers until we find a 0x8000
300         // (which would be remove world entity, but is actually a terminator)
301         while ((n = (unsigned short)MSG_ReadShort(&cl_message)) != 0x8000 && !cl_message.badread)
302         {
303                 // get the entity number
304                 enumber = n & 0x7FFF;
305                 // we may need to expand the array
306                 if (cl.num_entities <= enumber)
307                 {
308                         cl.num_entities = enumber + 1;
309                         if (enumber >= cl.max_entities)
310                                 CL_ExpandEntities(enumber);
311                 }
312                 // look up the entity
313                 ent = cl.entities + enumber;
314                 // slide the current into the previous slot
315                 ent->state_previous = ent->state_current;
316                 // read the update
317                 s = &ent->state_current;
318                 if (n & 0x8000)
319                 {
320                         // remove entity
321                         *s = defaultstate;
322                 }
323                 else
324                 {
325                         // update entity
326                         EntityState5_ReadUpdate(s, enumber);
327                 }
328                 // set the cl.entities_active flag
329                 cl.entities_active[enumber] = (s->active == ACTIVE_NETWORK);
330                 // set the update time
331                 s->time = cl.mtime[0];
332                 // fix the number (it gets wiped occasionally by copying from defaultstate)
333                 s->number = enumber;
334                 // check if we need to update the lerp stuff
335                 if (s->active == ACTIVE_NETWORK)
336                         CL_MoveLerpEntityStates(&cl.entities[enumber]);
337                 // print extra messages if desired
338                 if (developer_networkentities.integer >= 2 && cl.entities[enumber].state_current.active != cl.entities[enumber].state_previous.active)
339                 {
340                         if (cl.entities[enumber].state_current.active == ACTIVE_NETWORK)
341                                 Con_Printf("entity #%i has become active\n", enumber);
342                         else if (cl.entities[enumber].state_previous.active)
343                                 Con_Printf("entity #%i has become inactive\n", enumber);
344                 }
345         }
346 }