]> git.xonotic.org Git - xonotic/darkplaces.git/blob - sv_ents.c
cl_main: Fix double free of meshentities texture pool when running gamedir
[xonotic/darkplaces.git] / sv_ents.c
1 #include "quakedef.h"
2 #include "protocol.h"
3
4 extern cvar_t sv_cullentities_trace_prediction_time;
5
6 int EntityState_DeltaBits(const entity_state_t *o, const entity_state_t *n)
7 {
8         unsigned int bits;
9         // if o is not active, delta from default
10         if (o->active != ACTIVE_NETWORK)
11                 o = &defaultstate;
12         bits = 0;
13         if (fabs(n->origin[0] - o->origin[0]) > (1.0f / 256.0f))
14                 bits |= E_ORIGIN1;
15         if (fabs(n->origin[1] - o->origin[1]) > (1.0f / 256.0f))
16                 bits |= E_ORIGIN2;
17         if (fabs(n->origin[2] - o->origin[2]) > (1.0f / 256.0f))
18                 bits |= E_ORIGIN3;
19         if ((unsigned char) (n->angles[0] * (256.0f / 360.0f)) != (unsigned char) (o->angles[0] * (256.0f / 360.0f)))
20                 bits |= E_ANGLE1;
21         if ((unsigned char) (n->angles[1] * (256.0f / 360.0f)) != (unsigned char) (o->angles[1] * (256.0f / 360.0f)))
22                 bits |= E_ANGLE2;
23         if ((unsigned char) (n->angles[2] * (256.0f / 360.0f)) != (unsigned char) (o->angles[2] * (256.0f / 360.0f)))
24                 bits |= E_ANGLE3;
25         if ((n->modelindex ^ o->modelindex) & 0x00FF)
26                 bits |= E_MODEL1;
27         if ((n->modelindex ^ o->modelindex) & 0xFF00)
28                 bits |= E_MODEL2;
29         if ((n->frame ^ o->frame) & 0x00FF)
30                 bits |= E_FRAME1;
31         if ((n->frame ^ o->frame) & 0xFF00)
32                 bits |= E_FRAME2;
33         if ((n->effects ^ o->effects) & 0x00FF)
34                 bits |= E_EFFECTS1;
35         if ((n->effects ^ o->effects) & 0xFF00)
36                 bits |= E_EFFECTS2;
37         if (n->colormap != o->colormap)
38                 bits |= E_COLORMAP;
39         if (n->skin != o->skin)
40                 bits |= E_SKIN;
41         if (n->alpha != o->alpha)
42                 bits |= E_ALPHA;
43         if (n->scale != o->scale)
44                 bits |= E_SCALE;
45         if (n->glowsize != o->glowsize)
46                 bits |= E_GLOWSIZE;
47         if (n->glowcolor != o->glowcolor)
48                 bits |= E_GLOWCOLOR;
49         if (n->flags != o->flags)
50                 bits |= E_FLAGS;
51         if (n->tagindex != o->tagindex || n->tagentity != o->tagentity)
52                 bits |= E_TAGATTACHMENT;
53         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])
54                 bits |= E_LIGHT;
55         if (n->lightstyle != o->lightstyle)
56                 bits |= E_LIGHTSTYLE;
57         if (n->lightpflags != o->lightpflags)
58                 bits |= E_LIGHTPFLAGS;
59
60         if (bits)
61         {
62                 if (bits &  0xFF000000)
63                         bits |= 0x00800000;
64                 if (bits &  0x00FF0000)
65                         bits |= 0x00008000;
66                 if (bits &  0x0000FF00)
67                         bits |= 0x00000080;
68         }
69         return bits;
70 }
71
72 void EntityState_WriteExtendBits(sizebuf_t *msg, unsigned int bits)
73 {
74         MSG_WriteByte(msg, bits & 0xFF);
75         if (bits & 0x00000080)
76         {
77                 MSG_WriteByte(msg, (bits >> 8) & 0xFF);
78                 if (bits & 0x00008000)
79                 {
80                         MSG_WriteByte(msg, (bits >> 16) & 0xFF);
81                         if (bits & 0x00800000)
82                                 MSG_WriteByte(msg, (bits >> 24) & 0xFF);
83                 }
84         }
85 }
86
87 void EntityState_WriteFields(const entity_state_t *ent, sizebuf_t *msg, unsigned int bits)
88 {
89         if (sv.protocol == PROTOCOL_DARKPLACES2)
90         {
91                 if (bits & E_ORIGIN1)
92                         MSG_WriteCoord16i(msg, ent->origin[0]);
93                 if (bits & E_ORIGIN2)
94                         MSG_WriteCoord16i(msg, ent->origin[1]);
95                 if (bits & E_ORIGIN3)
96                         MSG_WriteCoord16i(msg, ent->origin[2]);
97         }
98         else
99         {
100                 // LadyHavoc: have to write flags first, as they can modify protocol
101                 if (bits & E_FLAGS)
102                         MSG_WriteByte(msg, ent->flags);
103                 if (ent->flags & RENDER_LOWPRECISION)
104                 {
105                         if (bits & E_ORIGIN1)
106                                 MSG_WriteCoord16i(msg, ent->origin[0]);
107                         if (bits & E_ORIGIN2)
108                                 MSG_WriteCoord16i(msg, ent->origin[1]);
109                         if (bits & E_ORIGIN3)
110                                 MSG_WriteCoord16i(msg, ent->origin[2]);
111                 }
112                 else
113                 {
114                         if (bits & E_ORIGIN1)
115                                 MSG_WriteCoord32f(msg, ent->origin[0]);
116                         if (bits & E_ORIGIN2)
117                                 MSG_WriteCoord32f(msg, ent->origin[1]);
118                         if (bits & E_ORIGIN3)
119                                 MSG_WriteCoord32f(msg, ent->origin[2]);
120                 }
121         }
122         if ((sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4) && (ent->flags & RENDER_LOWPRECISION))
123         {
124                 if (bits & E_ANGLE1)
125                         MSG_WriteAngle8i(msg, ent->angles[0]);
126                 if (bits & E_ANGLE2)
127                         MSG_WriteAngle8i(msg, ent->angles[1]);
128                 if (bits & E_ANGLE3)
129                         MSG_WriteAngle8i(msg, ent->angles[2]);
130         }
131         else
132         {
133                 if (bits & E_ANGLE1)
134                         MSG_WriteAngle16i(msg, ent->angles[0]);
135                 if (bits & E_ANGLE2)
136                         MSG_WriteAngle16i(msg, ent->angles[1]);
137                 if (bits & E_ANGLE3)
138                         MSG_WriteAngle16i(msg, ent->angles[2]);
139         }
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 (sv.protocol == PROTOCOL_DARKPLACES2)
165                 if (bits & E_FLAGS)
166                         MSG_WriteByte(msg, ent->flags);
167         if (bits & E_TAGATTACHMENT)
168         {
169                 MSG_WriteShort(msg, ent->tagentity);
170                 MSG_WriteByte(msg, ent->tagindex);
171         }
172         if (bits & E_LIGHT)
173         {
174                 MSG_WriteShort(msg, ent->light[0]);
175                 MSG_WriteShort(msg, ent->light[1]);
176                 MSG_WriteShort(msg, ent->light[2]);
177                 MSG_WriteShort(msg, ent->light[3]);
178         }
179         if (bits & E_LIGHTSTYLE)
180                 MSG_WriteByte(msg, ent->lightstyle);
181         if (bits & E_LIGHTPFLAGS)
182                 MSG_WriteByte(msg, ent->lightpflags);
183 }
184
185 void EntityState_WriteUpdate(const entity_state_t *ent, sizebuf_t *msg, const entity_state_t *delta)
186 {
187         prvm_prog_t *prog = SVVM_prog;
188         unsigned int bits;
189         if (ent->active == ACTIVE_NETWORK)
190         {
191                 // entity is active, check for changes from the delta
192                 if ((bits = EntityState_DeltaBits(delta, ent)))
193                 {
194                         // write the update number, bits, and fields
195                         ENTITYSIZEPROFILING_START(msg, ent->number, bits);
196                         MSG_WriteShort(msg, ent->number);
197                         EntityState_WriteExtendBits(msg, bits);
198                         EntityState_WriteFields(ent, msg, bits);
199                         ENTITYSIZEPROFILING_END(msg, ent->number, bits);
200                 }
201         }
202         else
203         {
204                 // entity is inactive, check if the delta was active
205                 if (delta->active == ACTIVE_NETWORK)
206                 {
207                         // write the remove number
208                         ENTITYSIZEPROFILING_START(msg, ent->number, 0);
209                         MSG_WriteShort(msg, ent->number | 0x8000);
210                         ENTITYSIZEPROFILING_END(msg, ent->number, 0);
211                 }
212         }
213 }
214
215 // (server) adds a entity_frame to the database, for future reference
216 void EntityFrame_AddFrame_Server(entityframe_database_t *d, vec3_t eye, int framenum, int numentities, const entity_state_t **entitydata)
217 {
218         int n, e;
219         entity_frameinfo_t *info;
220
221         VectorCopy(eye, d->eye);
222
223         // figure out how many entity slots are used already
224         if (d->numframes)
225         {
226                 n = d->frames[d->numframes - 1].endentity - d->frames[0].firstentity;
227                 if (n + numentities > MAX_ENTITY_DATABASE || d->numframes >= MAX_ENTITY_HISTORY)
228                 {
229                         // ran out of room, dump database
230                         EntityFrame_ClearDatabase(d);
231                 }
232         }
233
234         info = &d->frames[d->numframes];
235         info->framenum = framenum;
236         e = -1000;
237         // make sure we check the newly added frame as well, but we haven't incremented numframes yet
238         for (n = 0;n <= d->numframes;n++)
239         {
240                 if (e >= d->frames[n].framenum)
241                 {
242                         if (e == framenum)
243                                 Con_Print("EntityFrame_AddFrame: tried to add out of sequence frame to database\n");
244                         else
245                                 Con_Print("EntityFrame_AddFrame: out of sequence frames in database\n");
246                         return;
247                 }
248                 e = d->frames[n].framenum;
249         }
250         // if database still has frames after that...
251         if (d->numframes)
252                 info->firstentity = d->frames[d->numframes - 1].endentity;
253         else
254                 info->firstentity = 0;
255         info->endentity = info->firstentity + numentities;
256         d->numframes++;
257
258         n = info->firstentity % MAX_ENTITY_DATABASE;
259         e = MAX_ENTITY_DATABASE - n;
260         if (e > numentities)
261                 e = numentities;
262         memcpy(d->entitydata + n, entitydata, sizeof(entity_state_t) * e);
263         if (numentities > e)
264                 memcpy(d->entitydata, entitydata + e, sizeof(entity_state_t) * (numentities - e));
265 }
266
267 // (server) writes a frame to network stream
268 qbool EntityFrame_WriteFrame(sizebuf_t *msg, int maxsize, entityframe_database_t *d, int numstates, const entity_state_t **states, int viewentnum)
269 {
270         prvm_prog_t *prog = SVVM_prog;
271         int i, onum, number;
272         entity_frame_t *o = &d->deltaframe;
273         const entity_state_t *ent, *delta;
274         vec3_t eye;
275
276         d->latestframenum++;
277
278         VectorClear(eye);
279         for (i = 0;i < numstates;i++)
280         {
281                 ent = states[i];
282                 if (ent->number == viewentnum)
283                 {
284                         VectorSet(eye, ent->origin[0], ent->origin[1], ent->origin[2] + 22);
285                         break;
286                 }
287         }
288
289         EntityFrame_AddFrame_Server(d, eye, d->latestframenum, numstates, states);
290
291         EntityFrame_FetchFrame(d, d->ackframenum, o);
292
293         MSG_WriteByte (msg, svc_entities);
294         MSG_WriteLong (msg, o->framenum);
295         MSG_WriteLong (msg, d->latestframenum);
296         MSG_WriteFloat (msg, eye[0]);
297         MSG_WriteFloat (msg, eye[1]);
298         MSG_WriteFloat (msg, eye[2]);
299
300         onum = 0;
301         for (i = 0;i < numstates;i++)
302         {
303                 ent = states[i];
304                 number = ent->number;
305
306                 if (PRVM_serveredictfunction((&prog->edicts[number]), SendEntity))
307                         continue;
308                 for (;onum < o->numentities && o->entitydata[onum].number < number;onum++)
309                 {
310                         // write remove message
311                         MSG_WriteShort(msg, o->entitydata[onum].number | 0x8000);
312                 }
313                 if (onum < o->numentities && (o->entitydata[onum].number == number))
314                 {
315                         // delta from previous frame
316                         delta = o->entitydata + onum;
317                         // advance to next entity in delta frame
318                         onum++;
319                 }
320                 else
321                 {
322                         // delta from defaults
323                         delta = &defaultstate;
324                 }
325                 EntityState_WriteUpdate(ent, msg, delta);
326         }
327         for (;onum < o->numentities;onum++)
328         {
329                 // write remove message
330                 MSG_WriteShort(msg, o->entitydata[onum].number | 0x8000);
331         }
332         MSG_WriteShort(msg, 0xFFFF);
333
334         return true;
335 }
336
337 void SV_WriteEntitiesToClient(client_t *client, prvm_edict_t *clent, sizebuf_t *msg, int maxsize)
338 {
339         prvm_prog_t *prog = SVVM_prog;
340         qbool need_empty = false;
341         int i, numsendstates, numcsqcsendstates;
342         entity_state_t *s;
343         prvm_edict_t *camera;
344         qbool success;
345         vec3_t eye;
346
347         // if there isn't enough space to accomplish anything, skip it
348         if (msg->cursize + 25 > maxsize)
349                 return;
350
351         sv.writeentitiestoclient_msg = msg;
352         sv.writeentitiestoclient_clientnumber = client - svs.clients;
353
354         sv.writeentitiestoclient_stats_culled_pvs = 0;
355         sv.writeentitiestoclient_stats_culled_trace = 0;
356         sv.writeentitiestoclient_stats_visibleentities = 0;
357         sv.writeentitiestoclient_stats_totalentities = 0;
358         sv.writeentitiestoclient_numeyes = 0;
359
360         // get eye location
361         sv.writeentitiestoclient_cliententitynumber = PRVM_EDICT_TO_PROG(clent); // LadyHavoc: for comparison purposes
362         camera = PRVM_EDICT_NUM( client->clientcamera );
363         VectorAdd(PRVM_serveredictvector(camera, origin), PRVM_serveredictvector(clent, view_ofs), eye);
364         sv.writeentitiestoclient_pvsbytes = 0;
365         // get the PVS values for the eye location, later FatPVS calls will merge
366         if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
367                 sv.writeentitiestoclient_pvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, eye, 8, sv.writeentitiestoclient_pvs, sizeof(sv.writeentitiestoclient_pvs), sv.writeentitiestoclient_pvsbytes != 0);
368
369         // add the eye to a list for SV_CanSeeBox tests
370         VectorCopy(eye, sv.writeentitiestoclient_eyes[sv.writeentitiestoclient_numeyes]);
371         sv.writeentitiestoclient_numeyes++;
372
373         // calculate predicted eye origin for SV_CanSeeBox tests
374         if (sv_cullentities_trace_prediction.integer)
375         {
376                 vec_t predtime = bound(0, host_client->ping, sv_cullentities_trace_prediction_time.value);
377                 vec3_t predeye;
378                 VectorMA(eye, predtime, PRVM_serveredictvector(camera, velocity), predeye);
379                 if (SV_CanSeeBox(1, 0, 0, 0, eye, predeye, predeye))
380                 {
381                         VectorCopy(predeye, sv.writeentitiestoclient_eyes[sv.writeentitiestoclient_numeyes]);
382                         sv.writeentitiestoclient_numeyes++;
383                 }
384                 //if (!sv.writeentitiestoclient_useprediction)
385                 //      Con_DPrintf("Trying to walk into solid in a pingtime... not predicting for culling\n");
386         }
387
388         SV_AddCameraEyes();
389
390         // build PVS from the new eyes
391         if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
392                 for(i = 1; i < sv.writeentitiestoclient_numeyes; ++i)
393                         sv.writeentitiestoclient_pvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, sv.writeentitiestoclient_eyes[i], 8, sv.writeentitiestoclient_pvs, sizeof(sv.writeentitiestoclient_pvs), sv.writeentitiestoclient_pvsbytes != 0);
394
395         sv.sententitiesmark++;
396
397         for (i = 0;i < sv.numsendentities;i++)
398                 SV_MarkWriteEntityStateToClient(sv.sendentities + i);
399
400         numsendstates = 0;
401         numcsqcsendstates = 0;
402         for (i = 0;i < sv.numsendentities;i++)
403         {
404                 s = &sv.sendentities[i];
405                 if (sv.sententities[s->number] == sv.sententitiesmark)
406                 {
407                         if(s->active == ACTIVE_NETWORK)
408                         {
409                                 if (s->exteriormodelforclient)
410                                 {
411                                         if (s->exteriormodelforclient == sv.writeentitiestoclient_cliententitynumber)
412                                                 s->flags |= RENDER_EXTERIORMODEL;
413                                         else
414                                                 s->flags &= ~RENDER_EXTERIORMODEL;
415                                 }
416                                 sv.writeentitiestoclient_sendstates[numsendstates++] = s;
417                         }
418                         else if(sv.sendentities[i].active == ACTIVE_SHARED)
419                                 sv.writeentitiestoclient_csqcsendstates[numcsqcsendstates++] = s->number;
420                         else
421                                 Con_Printf("entity %d is in sv.sendentities and marked, but not active, please breakpoint me\n", s->number);
422                 }
423         }
424
425         if (sv_cullentities_stats.integer)
426                 Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d trace\n", client->name, sv.writeentitiestoclient_stats_totalentities, sv.writeentitiestoclient_stats_visibleentities, sv.writeentitiestoclient_stats_culled_pvs + sv.writeentitiestoclient_stats_culled_trace, sv.writeentitiestoclient_stats_culled_pvs, sv.writeentitiestoclient_stats_culled_trace);
427
428         if(client->entitydatabase5)
429                 need_empty = EntityFrameCSQC_WriteFrame(msg, maxsize, numcsqcsendstates, sv.writeentitiestoclient_csqcsendstates, client->entitydatabase5->latestframenum + 1);
430         else
431                 EntityFrameCSQC_WriteFrame(msg, maxsize, numcsqcsendstates, sv.writeentitiestoclient_csqcsendstates, 0);
432
433         // force every 16th frame to be not empty (or cl_movement replay takes
434         // too long)
435         // BTW, this should normally not kick in any more due to the check
436         // below, except if the client stopped sending movement frames
437         if(client->num_skippedentityframes >= 16)
438                 need_empty = true;
439
440         // help cl_movement a bit more
441         if(client->movesequence != client->lastmovesequence)
442                 need_empty = true;
443         client->lastmovesequence = client->movesequence;
444
445         if (client->entitydatabase5)
446                 success = EntityFrame5_WriteFrame(msg, maxsize, client->entitydatabase5, numsendstates, sv.writeentitiestoclient_sendstates, client - svs.clients + 1, client->movesequence, need_empty);
447         else if (client->entitydatabase4)
448         {
449                 success = EntityFrame4_WriteFrame(msg, maxsize, client->entitydatabase4, numsendstates, sv.writeentitiestoclient_sendstates);
450                 Protocol_WriteStatsReliable();
451         }
452         else if (client->entitydatabase)
453         {
454                 success = EntityFrame_WriteFrame(msg, maxsize, client->entitydatabase, numsendstates, sv.writeentitiestoclient_sendstates, client - svs.clients + 1);
455                 Protocol_WriteStatsReliable();
456         }
457         else
458         {
459                 success = EntityFrameQuake_WriteFrame(msg, maxsize, numsendstates, sv.writeentitiestoclient_sendstates);
460                 Protocol_WriteStatsReliable();
461         }
462
463         if(success)
464                 client->num_skippedentityframes = 0;
465         else
466                 ++client->num_skippedentityframes;
467 }