]> icculus.org git repositories - divverent/darkplaces.git/blob - cl_parse.c
removed support for r_ser (also known as R_Clip or "Hidden Surface Removal") as it...
[divverent/darkplaces.git] / cl_parse.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20 // cl_parse.c  -- parse a message received from the server
21
22 #include "quakedef.h"
23
24 char *svc_strings[128] =
25 {
26         "svc_bad",
27         "svc_nop",
28         "svc_disconnect",
29         "svc_updatestat",
30         "svc_version",          // [long] server version
31         "svc_setview",          // [short] entity number
32         "svc_sound",                    // <see code>
33         "svc_time",                     // [float] server time
34         "svc_print",                    // [string] null terminated string
35         "svc_stufftext",                // [string] stuffed into client's console buffer
36                                                 // the string should be \n terminated
37         "svc_setangle",         // [vec3] set the view angle to this absolute value
38
39         "svc_serverinfo",               // [long] version
40                                                 // [string] signon string
41                                                 // [string]..[0]model cache [string]...[0]sounds cache
42                                                 // [string]..[0]item cache
43         "svc_lightstyle",               // [byte] [string]
44         "svc_updatename",               // [byte] [string]
45         "svc_updatefrags",      // [byte] [short]
46         "svc_clientdata",               // <shortbits + data>
47         "svc_stopsound",                // <see code>
48         "svc_updatecolors",     // [byte] [byte]
49         "svc_particle",         // [vec3] <variable>
50         "svc_damage",                   // [byte] impact [byte] blood [vec3] from
51
52         "svc_spawnstatic",
53         "OBSOLETE svc_spawnbinary",
54         "svc_spawnbaseline",
55
56         "svc_temp_entity",              // <variable>
57         "svc_setpause",
58         "svc_signonnum",
59         "svc_centerprint",
60         "svc_killedmonster",
61         "svc_foundsecret",
62         "svc_spawnstaticsound",
63         "svc_intermission",
64         "svc_finale",                   // [string] music [string] text
65         "svc_cdtrack",                  // [byte] track [byte] looptrack
66         "svc_sellscreen",
67         "svc_cutscene",
68         "svc_showlmp",  // [string] iconlabel [string] lmpfile [short] x [short] y
69         "svc_hidelmp",  // [string] iconlabel
70         "svc_skybox", // [string] skyname
71         "", // 38
72         "", // 39
73         "", // 40
74         "", // 41
75         "", // 42
76         "", // 43
77         "", // 44
78         "", // 45
79         "", // 46
80         "", // 47
81         "", // 48
82         "", // 49
83         "svc_cgame", //                         50              // [short] length [bytes] data
84         "svc_unusedlh1", //                     51              // unused
85         "svc_effect", //                        52              // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
86         "svc_effect2", //                       53              // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate
87         "svc_sound2", //                        54              // short soundindex instead of byte
88         "svc_spawnbaseline2", //        55              // short modelindex instead of byte
89         "svc_spawnstatic2", //          56              // short modelindex instead of byte
90         "svc_entities", //                      57              // [int] deltaframe [int] thisframe [float vector] eye [variable length] entitydata
91         "svc_unusedlh3", //                     58
92         "svc_spawnstaticsound2", //     59              // [coord3] [short] samp [byte] vol [byte] aten
93 };
94
95 //=============================================================================
96
97 cvar_t demo_nehahra = {0, "demo_nehahra", "0"};
98
99 void CL_Parse_Init(void)
100 {
101         // LordHavoc: added demo_nehahra cvar
102         Cvar_RegisterVariable (&demo_nehahra);
103         if (gamemode == GAME_NEHAHRA)
104                 Cvar_SetValue("demo_nehahra", 1);
105 }
106
107 qboolean Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
108 int dpprotocol; // LordHavoc: version of network protocol, or 0 if not DarkPlaces
109
110 /*
111 ==================
112 CL_ParseStartSoundPacket
113 ==================
114 */
115 void CL_ParseStartSoundPacket(int largesoundindex)
116 {
117     vec3_t  pos;
118     int         channel, ent;
119     int         sound_num;
120     int         volume;
121     int         field_mask;
122     float       attenuation;
123         int             i;
124                    
125     field_mask = MSG_ReadByte();
126
127     if (field_mask & SND_VOLUME)
128                 volume = MSG_ReadByte ();
129         else
130                 volume = DEFAULT_SOUND_PACKET_VOLUME;
131         
132     if (field_mask & SND_ATTENUATION)
133                 attenuation = MSG_ReadByte () / 64.0;
134         else
135                 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
136         
137         channel = MSG_ReadShort ();
138         if (largesoundindex)
139                 sound_num = (unsigned short) MSG_ReadShort ();
140         else
141                 sound_num = MSG_ReadByte ();
142
143         if (sound_num >= MAX_SOUNDS)
144                 Host_Error("CL_ParseStartSoundPacket: sound_num (%i) >= MAX_SOUNDS (%i)\n", sound_num, MAX_SOUNDS);
145
146         ent = channel >> 3;
147         channel &= 7;
148
149         if (ent > MAX_EDICTS)
150                 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
151         
152         for (i=0 ; i<3 ; i++)
153                 pos[i] = MSG_ReadCoord ();
154
155     S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
156 }
157
158 /*
159 ==================
160 CL_KeepaliveMessage
161
162 When the client is taking a long time to load stuff, send keepalive messages
163 so the server doesn't disconnect.
164 ==================
165 */
166 void CL_KeepaliveMessage (void)
167 {
168         float   time;
169         static float lastmsg;
170         int             ret;
171         int             c;
172         sizebuf_t       old;
173         qbyte           olddata[8192];
174         
175         if (sv.active)
176                 return;         // no need if server is local
177         if (cls.demoplayback)
178                 return;
179
180 // read messages from server, should just be nops
181         old = net_message;
182         memcpy (olddata, net_message.data, net_message.cursize);
183         
184         do
185         {
186                 ret = CL_GetMessage ();
187                 switch (ret)
188                 {
189                 default:
190                         Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
191                 case 0:
192                         break;  // nothing waiting
193                 case 1:
194                         Host_Error ("CL_KeepaliveMessage: received a message");
195                         break;
196                 case 2:
197                         c = MSG_ReadByte();
198                         if (c != svc_nop)
199                                 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
200                         break;
201                 }
202         } while (ret);
203
204         net_message = old;
205         memcpy (net_message.data, olddata, net_message.cursize);
206
207 // check time
208         time = Sys_DoubleTime ();
209         if (time - lastmsg < 5)
210                 return;
211         lastmsg = time;
212
213 // write out a nop
214         Con_Printf ("--> client to server keepalive\n");
215
216         MSG_WriteByte (&cls.message, clc_nop);
217         NET_SendMessage (cls.netcon, &cls.message);
218         SZ_Clear (&cls.message);
219 }
220
221 void CL_ParseEntityLump(char *entdata)
222 {
223         char *data;
224         char key[128], value[4096];
225         FOG_clear(); // LordHavoc: no fog until set
226         R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set
227         data = entdata;
228         if (!data)
229                 return;
230         data = COM_Parse(data);
231         if (!data)
232                 return; // error
233         if (com_token[0] != '{')
234                 return; // error
235         while (1)
236         {
237                 data = COM_Parse(data);
238                 if (!data)
239                         return; // error
240                 if (com_token[0] == '}')
241                         break; // end of worldspawn
242                 if (com_token[0] == '_')
243                         strcpy(key, com_token + 1);
244                 else
245                         strcpy(key, com_token);
246                 while (key[strlen(key)-1] == ' ') // remove trailing spaces
247                         key[strlen(key)-1] = 0;
248                 data = COM_Parse(data);
249                 if (!data)
250                         return; // error
251                 strcpy(value, com_token);
252                 if (!strcmp("sky", key))
253                         R_SetSkyBox(value);
254                 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
255                         R_SetSkyBox(value);
256                 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
257                         R_SetSkyBox(value);
258                 else if (!strcmp("fog", key))
259                         sscanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
260                 else if (!strcmp("fog_density", key))
261                         fog_density = atof(value);
262                 else if (!strcmp("fog_red", key))
263                         fog_red = atof(value);
264                 else if (!strcmp("fog_green", key))
265                         fog_green = atof(value);
266                 else if (!strcmp("fog_blue", key))
267                         fog_blue = atof(value);
268         }
269 }
270
271 /*
272 =====================
273 CL_SignonReply
274
275 An svc_signonnum has been received, perform a client side setup
276 =====================
277 */
278 static void CL_SignonReply (void)
279 {
280         //char  str[8192];
281
282 Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
283
284         switch (cls.signon)
285         {
286         case 1:
287                 MSG_WriteByte (&cls.message, clc_stringcmd);
288                 MSG_WriteString (&cls.message, "prespawn");
289                 break;
290
291         case 2:
292                 MSG_WriteByte (&cls.message, clc_stringcmd);
293                 MSG_WriteString (&cls.message, va("name \"%s\"\n", cl_name.string));
294
295                 MSG_WriteByte (&cls.message, clc_stringcmd);
296                 MSG_WriteString (&cls.message, va("color %i %i\n", cl_color.integer >> 4, cl_color.integer & 15));
297
298                 if (cl_pmodel.integer)
299                 {
300                         MSG_WriteByte (&cls.message, clc_stringcmd);
301                         MSG_WriteString (&cls.message, va("pmodel %i\n", cl_pmodel.integer));
302                 }
303
304                 MSG_WriteByte (&cls.message, clc_stringcmd);
305                 //sprintf (str, "spawn %s", cls.spawnparms);
306                 //MSG_WriteString (&cls.message, str);
307                 MSG_WriteString (&cls.message, "spawn");
308                 break;
309
310         case 3:
311                 MSG_WriteByte (&cls.message, clc_stringcmd);
312                 MSG_WriteString (&cls.message, "begin");
313                 break;
314
315         case 4:
316                 Con_ClearNotify();
317                 break;
318         }
319 }
320
321 /*
322 ==================
323 CL_ParseServerInfo
324 ==================
325 */
326 qbyte entlife[MAX_EDICTS];
327 void CL_ParseServerInfo (void)
328 {
329         char *str;
330         int i;
331         int nummodels, numsounds;
332         char model_precache[MAX_MODELS][MAX_QPATH];
333         char sound_precache[MAX_SOUNDS][MAX_QPATH];
334         entity_t *ent;
335
336         Con_DPrintf ("Serverinfo packet received.\n");
337 //
338 // wipe the client_state_t struct
339 //
340         CL_ClearState ();
341
342 // parse protocol version number
343         i = MSG_ReadLong ();
344         if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
345         {
346                 Con_Printf ("Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
347                 return;
348         }
349         Nehahrademcompatibility = false;
350         if (i == 250)
351                 Nehahrademcompatibility = true;
352         if (cls.demoplayback && demo_nehahra.integer)
353                 Nehahrademcompatibility = true;
354         dpprotocol = i;
355         if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
356                 dpprotocol = 0;
357
358 // parse maxclients
359         cl.maxclients = MSG_ReadByte ();
360         if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
361         {
362                 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
363                 return;
364         }
365         cl.scores = Mem_Alloc(cl_scores_mempool, cl.maxclients*sizeof(*cl.scores));
366
367 // parse gametype
368         cl.gametype = MSG_ReadByte ();
369
370 // parse signon message
371         str = MSG_ReadString ();
372         strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
373
374 // seperate the printfs so the server message can have a color
375         if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
376         {
377                 Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
378                 Con_Printf ("%c%s\n", 2, str);
379         }
380
381 //
382 // first we go through and touch all of the precache data that still
383 // happens to be in the cache, so precaching something else doesn't
384 // needlessly purge it
385 //
386
387         Mem_CheckSentinelsGlobal();
388
389         Mod_ClearUsed();
390
391 // precache models
392         memset (cl.model_precache, 0, sizeof(cl.model_precache));
393         for (nummodels=1 ; ; nummodels++)
394         {
395                 str = MSG_ReadString ();
396                 if (!str[0])
397                         break;
398                 if (nummodels==MAX_MODELS)
399                 {
400                         Host_Error ("Server sent too many model precaches\n");
401                         return;
402                 }
403                 if (strlen(str) >= MAX_QPATH)
404                         Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
405                 strcpy (model_precache[nummodels], str);
406                 Mod_TouchModel (str);
407         }
408
409 // precache sounds
410         memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
411         for (numsounds=1 ; ; numsounds++)
412         {
413                 str = MSG_ReadString ();
414                 if (!str[0])
415                         break;
416                 if (numsounds==MAX_SOUNDS)
417                 {
418                         Host_Error ("Server sent too many sound precaches\n");
419                         return;
420                 }
421                 if (strlen(str) >= MAX_QPATH)
422                         Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
423                 strcpy (sound_precache[numsounds], str);
424                 S_TouchSound (str);
425         }
426
427         Mod_PurgeUnused();
428
429 //
430 // now we try to load everything else until a cache allocation fails
431 //
432
433         for (i=1 ; i<nummodels ; i++)
434         {
435                 // LordHavoc: i == 1 means the first model is the world model
436                 cl.model_precache[i] = Mod_ForName (model_precache[i], false, false, i == 1);
437
438                 if (cl.model_precache[i] == NULL)
439                 {
440                         Host_Error("Model %s not found\n", model_precache[i]);
441                         return;
442                 }
443                 CL_KeepaliveMessage ();
444         }
445
446         S_BeginPrecaching ();
447         for (i=1 ; i<numsounds ; i++)
448         {
449                 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i], true);
450                 CL_KeepaliveMessage ();
451         }
452         S_EndPrecaching ();
453
454 // local state
455         ent = &cl_entities[0];
456         // entire entity array was cleared, so just fill in a few fields
457         ent->state_current.active = true;
458         ent->render.model = cl.worldmodel = cl.model_precache[1];
459         ent->render.scale = 1;
460         ent->render.alpha = 1;
461         VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins);
462         VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs);
463         // clear entlife array
464         memset(entlife, 0, MAX_EDICTS);
465
466         cl_num_entities = 1;
467
468         R_NewMap ();
469
470         CL_CGVM_Start();
471
472         Mem_CheckSentinelsGlobal();
473
474         noclip_anglehack = false;               // noclip is turned off at start
475 }
476
477 void CL_ValidateState(entity_state_t *s)
478 {
479         model_t *model;
480
481         if (!s->active)
482                 return;
483
484         if (s->modelindex >= MAX_MODELS)
485                 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
486
487         // colormap is client index + 1
488         if (s->colormap > cl.maxclients)
489                 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
490
491         model = cl.model_precache[s->modelindex];
492         Mod_CheckLoaded(model);
493         if (model && s->frame >= model->numframes)
494         {
495                 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
496                 s->frame = 0;
497         }
498         if (model && s->skin > 0 && s->skin >= model->numskins)
499         {
500                 Con_DPrintf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
501                 s->skin = 0;
502         }
503 }
504
505 /*
506 ==================
507 CL_ParseUpdate
508
509 Parse an entity update message from the server
510 If an entities model or origin changes from frame to frame, it must be
511 relinked.  Other attributes can change without relinking.
512 ==================
513 */
514 int bitprofile[32], bitprofilecount = 0;
515 void CL_ParseUpdate (int bits)
516 {
517         int i, num;
518         entity_t *ent;
519         entity_state_t new;
520
521         if (bits & U_MOREBITS)
522                 bits |= (MSG_ReadByte()<<8);
523         if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
524         {
525                 bits |= MSG_ReadByte() << 16;
526                 if (bits & U_EXTEND2)
527                         bits |= MSG_ReadByte() << 24;
528         }
529
530         if (bits & U_LONGENTITY)
531                 num = (unsigned) MSG_ReadShort ();
532         else
533                 num = (unsigned) MSG_ReadByte ();
534
535         if (num >= MAX_EDICTS)
536                 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
537         if (num < 1)
538                 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
539
540         ent = cl_entities + num;
541
542         for (i = 0;i < 32;i++)
543                 if (bits & (1 << i))
544                         bitprofile[i]++;
545         bitprofilecount++;
546
547         // note: this inherits the 'active' state of the baseline chosen
548         // (state_baseline is always active, state_current may not be active if
549         // the entity was missing in the last frame)
550         if (bits & U_DELTA)
551                 new = ent->state_current;
552         else
553                 new = ent->state_baseline;
554
555         new.number = num;
556         new.time = cl.mtime[0];
557         new.flags = 0;
558         if (bits & U_MODEL)             new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte();
559         if (bits & U_FRAME)             new.frame = (new.frame & 0xFF00) | MSG_ReadByte();
560         if (bits & U_COLORMAP)  new.colormap = MSG_ReadByte();
561         if (bits & U_SKIN)              new.skin = MSG_ReadByte();
562         if (bits & U_EFFECTS)   new.effects = (new.effects & 0xFF00) | MSG_ReadByte();
563         if (bits & U_ORIGIN1)   new.origin[0] = MSG_ReadCoord();
564         if (bits & U_ANGLE1)    new.angles[0] = MSG_ReadAngle();
565         if (bits & U_ORIGIN2)   new.origin[1] = MSG_ReadCoord();
566         if (bits & U_ANGLE2)    new.angles[1] = MSG_ReadAngle();
567         if (bits & U_ORIGIN3)   new.origin[2] = MSG_ReadCoord();
568         if (bits & U_ANGLE3)    new.angles[2] = MSG_ReadAngle();
569         if (bits & U_STEP)              new.flags |= RENDER_STEP;
570         if (bits & U_ALPHA)             new.alpha = MSG_ReadByte();
571         if (bits & U_SCALE)             new.scale = MSG_ReadByte();
572         if (bits & U_EFFECTS2)  new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8);
573         if (bits & U_GLOWSIZE)  new.glowsize = MSG_ReadByte();
574         if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte();
575         // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
576         if (bits & U_COLORMOD)  MSG_ReadByte();
577         if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL;
578         if (bits & U_FRAME2)    new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8);
579         if (bits & U_MODEL2)    new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
580         if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL;
581         if (bits & U_EXTERIORMODEL)     new.flags |= RENDER_EXTERIORMODEL;
582
583         // LordHavoc: to allow playback of the Nehahra movie
584         if (Nehahrademcompatibility && (bits & U_EXTEND1))
585         {
586                 // LordHavoc: evil format
587                 int i = MSG_ReadFloat();
588                 int j = MSG_ReadFloat() * 255.0f;
589                 if (i == 2)
590                 {
591                         i = MSG_ReadFloat();
592                         if (i)
593                                 new.effects |= EF_FULLBRIGHT;
594                 }
595                 if (j < 0)
596                         new.alpha = 0;
597                 else if (j == 0 || j >= 255)
598                         new.alpha = 255;
599                 else
600                         new.alpha = j;
601         }
602
603         if (new.active)
604                 CL_ValidateState(&new);
605
606         if (new.flags & RENDER_STEP) // FIXME: rename this flag?
607         {
608                 // make time identical for memcmp
609                 new.time = ent->state_current.time;
610                 if (memcmp(&new, &ent->state_current, sizeof(entity_state_t)))
611                 {
612                         // set it back to what it should be
613                         new.time = cl.mtime[0] + 0.1;
614                         // state has changed
615                         ent->state_previous = ent->state_current;
616                         ent->state_current = new;
617                         // assume 10fps animation
618                         //ent->state_previous.time = cl.mtime[0] - 0.1;
619                 }
620         }
621         else
622         {
623                 ent->state_previous = ent->state_current;
624                 ent->state_current = new;
625         }
626         if (ent->state_current.active)
627         {
628                 cl_entities_active[ent->state_current.number] = true;
629                 // mark as visible (no kill this frame)
630                 entlife[ent->state_current.number] = 2;
631         }
632 }
633
634 void CL_ReadEntityFrame(void)
635 {
636         entity_t *ent;
637         entity_frame_t entityframe;
638         int i;
639         EntityFrame_Read(&cl.entitydatabase);
640         EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
641         for (i = 0;i < entityframe.numentities;i++)
642         {
643                 // copy the states
644                 ent = &cl_entities[entityframe.entitydata[i].number];
645                 ent->state_previous = ent->state_current;
646                 ent->state_current = entityframe.entitydata[i];
647                 ent->state_current.time = cl.mtime[0];
648                 // the entity lives again...
649                 entlife[ent->state_current.number] = 2;
650                 cl_entities_active[ent->state_current.number] = true;
651         }
652         VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
653         VectorCopy(entityframe.eye, cl.viewentoriginnew);
654 }
655
656 char *bitprofilenames[32] =
657 {
658         "U_MOREBITS",
659         "U_ORIGIN1",
660         "U_ORIGIN2",
661         "U_ORIGIN3",
662         "U_ANGLE2",
663         "U_STEP",
664         "U_FRAME",
665         "U_SIGNAL",
666         "U_ANGLE1",
667         "U_ANGLE3",
668         "U_MODEL",
669         "U_COLORMAP",
670         "U_SKIN",
671         "U_EFFECTS",
672         "U_LONGENTITY",
673         "U_EXTEND1",
674         "U_DELTA",
675         "U_ALPHA",
676         "U_SCALE",
677         "U_EFFECTS2",
678         "U_GLOWSIZE",
679         "U_GLOWCOLOR",
680         "obsolete U_COLORMOD",
681         "U_EXTEND2",
682         "U_GLOWTRAIL",
683         "U_VIEWMODEL",
684         "U_FRAME2",
685         "U_MODEL2",
686         "U_EXTERIORMODEL",
687         "U_UNUSED29",
688         "U_UNUSED30",
689         "U_EXTEND3",
690 };
691
692 void CL_BitProfile_f(void)
693 {
694         int i;
695         Con_Printf("bitprofile: %i updates\n");
696         if (bitprofilecount)
697                 for (i = 0;i < 32;i++)
698                         Con_Printf("%s: %i %3.2f%%\n", bitprofilenames[i], bitprofile[i], bitprofile[i] * 100.0 / bitprofilecount);
699         Con_Printf("\n");
700         for (i = 0;i < 32;i++)
701                 bitprofile[i] = 0;
702         bitprofilecount = 0;
703 }
704
705 void CL_EntityUpdateSetup(void)
706 {
707 }
708
709 void CL_EntityUpdateEnd(void)
710 {
711         int i;
712         // disable entities that disappeared this frame
713         for (i = 1;i < MAX_EDICTS;i++)
714         {
715                 // clear only the entities that were active last frame but not this
716                 // frame, don't waste time clearing all entities (which would cause
717                 // cache misses)
718                 if (entlife[i])
719                 {
720                         entlife[i]--;
721                         if (!entlife[i])
722                                 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
723                 }
724         }
725 }
726
727 /*
728 ==================
729 CL_ParseBaseline
730 ==================
731 */
732 void CL_ParseBaseline (entity_t *ent, int large)
733 {
734         int i;
735
736         memset(&ent->state_baseline, 0, sizeof(entity_state_t));
737         ent->state_baseline.active = true;
738         if (large)
739         {
740                 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
741                 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
742         }
743         else
744         {
745                 ent->state_baseline.modelindex = MSG_ReadByte ();
746                 ent->state_baseline.frame = MSG_ReadByte ();
747         }
748         ent->state_baseline.colormap = MSG_ReadByte();
749         ent->state_baseline.skin = MSG_ReadByte();
750         for (i = 0;i < 3;i++)
751         {
752                 ent->state_baseline.origin[i] = MSG_ReadCoord ();
753                 ent->state_baseline.angles[i] = MSG_ReadAngle ();
754         }
755         ent->state_baseline.alpha = 255;
756         ent->state_baseline.scale = 16;
757         ent->state_baseline.glowsize = 0;
758         ent->state_baseline.glowcolor = 254;
759         ent->state_previous = ent->state_current = ent->state_baseline;
760
761         CL_ValidateState(&ent->state_baseline);
762 }
763
764
765 /*
766 ==================
767 CL_ParseClientdata
768
769 Server information pertaining to this client only
770 ==================
771 */
772 void CL_ParseClientdata (int bits)
773 {
774         int i, j;
775
776         bits &= 0xFFFF;
777         if (bits & SU_EXTEND1)
778                 bits |= (MSG_ReadByte() << 16);
779         if (bits & SU_EXTEND2)
780                 bits |= (MSG_ReadByte() << 24);
781
782         if (bits & SU_VIEWHEIGHT)
783                 cl.viewheight = MSG_ReadChar ();
784         else
785                 cl.viewheight = DEFAULT_VIEWHEIGHT;
786
787         if (bits & SU_IDEALPITCH)
788                 cl.idealpitch = MSG_ReadChar ();
789         else
790                 cl.idealpitch = 0;
791
792         VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
793         for (i=0 ; i<3 ; i++)
794         {
795                 if (bits & (SU_PUNCH1<<i) )
796                 {
797                         if (dpprotocol)
798                                 cl.punchangle[i] = MSG_ReadPreciseAngle();
799                         else
800                                 cl.punchangle[i] = MSG_ReadChar();
801                 }
802                 else
803                         cl.punchangle[i] = 0;
804                 if (bits & (SU_PUNCHVEC1<<i))
805                         cl.punchvector[i] = MSG_ReadCoord();
806                 else
807                         cl.punchvector[i] = 0;
808                 if (bits & (SU_VELOCITY1<<i) )
809                         cl.mvelocity[0][i] = MSG_ReadChar()*16;
810                 else
811                         cl.mvelocity[0][i] = 0;
812         }
813
814         i = MSG_ReadLong ();
815         if (cl.items != i)
816         {       // set flash times
817                 for (j=0 ; j<32 ; j++)
818                         if ( (i & (1<<j)) && !(cl.items & (1<<j)))
819                                 cl.item_gettime[j] = cl.time;
820                 cl.items = i;
821         }
822
823         cl.onground = (bits & SU_ONGROUND) != 0;
824         cl.inwater = (bits & SU_INWATER) != 0;
825
826         cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
827         cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
828         cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
829         cl.stats[STAT_HEALTH] = MSG_ReadShort();
830         cl.stats[STAT_AMMO] = MSG_ReadByte();
831
832         cl.stats[STAT_SHELLS] = MSG_ReadByte();
833         cl.stats[STAT_NAILS] = MSG_ReadByte();
834         cl.stats[STAT_ROCKETS] = MSG_ReadByte();
835         cl.stats[STAT_CELLS] = MSG_ReadByte();
836
837         i = MSG_ReadByte ();
838
839         if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
840                 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
841         else
842                 cl.stats[STAT_ACTIVEWEAPON] = i;
843
844         cl.viewzoomold = cl.viewzoomnew; // for interpolation
845         if (bits & SU_VIEWZOOM)
846         {
847                 i = MSG_ReadByte();
848                 if (i < 2)
849                         i = 2;
850                 cl.viewzoomnew = (float) i * (1.0f / 255.0f);
851         }
852         else
853                 cl.viewzoomnew = 1;
854
855 }
856
857 /*
858 =====================
859 CL_ParseStatic
860 =====================
861 */
862 void CL_ParseStatic (int large)
863 {
864         entity_t *ent;
865
866         if (cl_num_static_entities >= cl_max_static_entities)
867                 Host_Error ("Too many static entities");
868         ent = &cl_static_entities[cl_num_static_entities++];
869         CL_ParseBaseline (ent, large);
870
871 // copy it to the current state
872         ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
873         ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
874         ent->render.framelerp = 0;
875         // make torchs play out of sync
876         ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1);
877         ent->render.colormap = -1; // no special coloring
878         ent->render.skinnum = ent->state_baseline.skin;
879         ent->render.effects = ent->state_baseline.effects;
880         ent->render.alpha = 1;
881         ent->render.scale = 1;
882         ent->render.alpha = 1;
883
884         VectorCopy (ent->state_baseline.origin, ent->render.origin);
885         VectorCopy (ent->state_baseline.angles, ent->render.angles);
886
887         if (ent->render.angles[0] || ent->render.angles[2])
888         {
889                 // pitch or roll
890                 VectorAdd(ent->render.origin, ent->render.model->rotatedmins, ent->render.mins);
891                 VectorAdd(ent->render.origin, ent->render.model->rotatedmaxs, ent->render.maxs);
892         }
893         else if (ent->render.angles[1])
894         {
895                 // yaw
896                 VectorAdd(ent->render.origin, ent->render.model->yawmins, ent->render.mins);
897                 VectorAdd(ent->render.origin, ent->render.model->yawmaxs, ent->render.maxs);
898         }
899         else
900         {
901                 VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins);
902                 VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs);
903         }
904
905         // This is definitely cheating...
906         if (ent->render.model == NULL)
907                 cl_num_static_entities--;
908 }
909
910 /*
911 ===================
912 CL_ParseStaticSound
913 ===================
914 */
915 void CL_ParseStaticSound (int large)
916 {
917         vec3_t          org;
918         int                     sound_num, vol, atten;
919
920         MSG_ReadVector(org);
921         if (large)
922                 sound_num = (unsigned short) MSG_ReadShort ();
923         else
924                 sound_num = MSG_ReadByte ();
925         vol = MSG_ReadByte ();
926         atten = MSG_ReadByte ();
927
928         S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
929 }
930
931 void CL_ParseEffect (void)
932 {
933         vec3_t          org;
934         int                     modelindex, startframe, framecount, framerate;
935
936         MSG_ReadVector(org);
937         modelindex = MSG_ReadByte ();
938         startframe = MSG_ReadByte ();
939         framecount = MSG_ReadByte ();
940         framerate = MSG_ReadByte ();
941
942         CL_Effect(org, modelindex, startframe, framecount, framerate);
943 }
944
945 void CL_ParseEffect2 (void)
946 {
947         vec3_t          org;
948         int                     modelindex, startframe, framecount, framerate;
949
950         MSG_ReadVector(org);
951         modelindex = MSG_ReadShort ();
952         startframe = MSG_ReadShort ();
953         framecount = MSG_ReadByte ();
954         framerate = MSG_ReadByte ();
955
956         CL_Effect(org, modelindex, startframe, framecount, framerate);
957 }
958
959
960 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
961
962 static qbyte cgamenetbuffer[65536];
963
964 /*
965 =====================
966 CL_ParseServerMessage
967 =====================
968 */
969 void CL_ParseServerMessage (void)
970 {
971         int                     cmd;
972         int                     i, entitiesupdated;
973         qbyte           cmdlog[32];
974         char            *cmdlogname[32], *temp;
975         int                     cmdindex, cmdcount = 0;
976
977 //
978 // if recording demos, copy the message out
979 //
980         if (cl_shownet.integer == 1)
981                 Con_Printf ("%i ",net_message.cursize);
982         else if (cl_shownet.integer == 2)
983                 Con_Printf ("------------------\n");
984
985         cl.onground = false;    // unless the server says otherwise
986 //
987 // parse the message
988 //
989         MSG_BeginReading ();
990
991         entitiesupdated = false;
992
993         while (1)
994         {
995                 if (msg_badread)
996                         Host_Error ("CL_ParseServerMessage: Bad server message");
997
998                 cmd = MSG_ReadByte ();
999
1000                 if (cmd == -1)
1001                 {
1002                         SHOWNET("END OF MESSAGE");
1003                         break;          // end of message
1004                 }
1005
1006                 cmdindex = cmdcount & 31;
1007                 cmdcount++;
1008                 cmdlog[cmdindex] = cmd;
1009
1010                 // if the high bit of the command byte is set, it is a fast update
1011                 if (cmd & 128)
1012                 {
1013                         // LordHavoc: fix for bizarre problem in MSVC that I do not understand (if I assign the string pointer directly it ends up storing a NULL pointer)
1014                         temp = "entity";
1015                         cmdlogname[cmdindex] = temp;
1016                         SHOWNET("fast update");
1017                         if (cls.signon == SIGNONS - 1)
1018                         {
1019                                 // first update is the final signon stage
1020                                 cls.signon = SIGNONS;
1021                                 CL_SignonReply ();
1022                         }
1023                         CL_ParseUpdate (cmd&127);
1024                         continue;
1025                 }
1026
1027                 SHOWNET(svc_strings[cmd]);
1028                 cmdlogname[cmdindex] = svc_strings[cmd];
1029                 if (!cmdlogname[cmdindex])
1030                 {
1031                         // LordHavoc: fix for bizarre problem in MSVC that I do not understand (if I assign the string pointer directly it ends up storing a NULL pointer)
1032                         temp = "<unknown>";
1033                         cmdlogname[cmdindex] = temp;
1034                 }
1035
1036                 // other commands
1037                 switch (cmd)
1038                 {
1039                 default:
1040                         {
1041                                 char description[32*64], temp[64];
1042                                 int count;
1043                                 strcpy(description, "packet dump: ");
1044                                 i = cmdcount - 32;
1045                                 if (i < 0)
1046                                         i = 0;
1047                                 count = cmdcount - i;
1048                                 i &= 31;
1049                                 while(count > 0)
1050                                 {
1051                                         sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
1052                                         strcat(description, temp);
1053                                         count--;
1054                                         i++;
1055                                         i &= 31;
1056                                 }
1057                                 description[strlen(description)-1] = '\n'; // replace the last space with a newline
1058                                 Con_Printf("%s", description);
1059                                 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
1060                         }
1061                         break;
1062
1063                 case svc_nop:
1064                         break;
1065
1066                 case svc_time:
1067                         if (!entitiesupdated)
1068                         {
1069                                 // this is a new frame, we'll be seeing entities,
1070                                 // so prepare for entity updates
1071                                 CL_EntityUpdateSetup();
1072                                 entitiesupdated = true;
1073                         }
1074                         cl.mtime[1] = cl.mtime[0];
1075                         cl.mtime[0] = MSG_ReadFloat ();
1076                         break;
1077
1078                 case svc_clientdata:
1079                         i = MSG_ReadShort ();
1080                         CL_ParseClientdata (i);
1081                         break;
1082
1083                 case svc_version:
1084                         i = MSG_ReadLong ();
1085                         if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
1086                                 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
1087                         Nehahrademcompatibility = false;
1088                         if (i == 250)
1089                                 Nehahrademcompatibility = true;
1090                         if (cls.demoplayback && demo_nehahra.integer)
1091                                 Nehahrademcompatibility = true;
1092                         dpprotocol = i;
1093                         if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
1094                                 dpprotocol = 0;
1095                         break;
1096
1097                 case svc_disconnect:
1098                         Host_EndGame ("Server disconnected\n");
1099
1100                 case svc_print:
1101                         Con_Printf ("%s", MSG_ReadString ());
1102                         break;
1103
1104                 case svc_centerprint:
1105                         SCR_CenterPrint (MSG_ReadString ());
1106                         break;
1107
1108                 case svc_stufftext:
1109                         Cbuf_AddText (MSG_ReadString ());
1110                         break;
1111
1112                 case svc_damage:
1113                         V_ParseDamage ();
1114                         break;
1115
1116                 case svc_serverinfo:
1117                         CL_ParseServerInfo ();
1118                         break;
1119
1120                 case svc_setangle:
1121                         for (i=0 ; i<3 ; i++)
1122                                 cl.viewangles[i] = MSG_ReadAngle ();
1123                         break;
1124
1125                 case svc_setview:
1126                         cl.viewentity = MSG_ReadShort ();
1127                         // LordHavoc: assume first setview recieved is the real player entity
1128                         if (!cl.playerentity)
1129                                 cl.playerentity = cl.viewentity;
1130                         break;
1131
1132                 case svc_lightstyle:
1133                         i = MSG_ReadByte ();
1134                         if (i >= MAX_LIGHTSTYLES)
1135                                 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1136                         strncpy (cl_lightstyle[i].map,  MSG_ReadString(), MAX_STYLESTRING - 1);
1137                         cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1138                         cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1139                         break;
1140
1141                 case svc_sound:
1142                         CL_ParseStartSoundPacket(false);
1143                         break;
1144
1145                 case svc_sound2:
1146                         CL_ParseStartSoundPacket(true);
1147                         break;
1148
1149                 case svc_stopsound:
1150                         i = MSG_ReadShort();
1151                         S_StopSound(i>>3, i&7);
1152                         break;
1153
1154                 case svc_updatename:
1155                         i = MSG_ReadByte ();
1156                         if (i >= cl.maxclients)
1157                                 Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
1158                         strcpy (cl.scores[i].name, MSG_ReadString ());
1159                         break;
1160
1161                 case svc_updatefrags:
1162                         i = MSG_ReadByte ();
1163                         if (i >= cl.maxclients)
1164                                 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
1165                         cl.scores[i].frags = MSG_ReadShort ();
1166                         break;
1167
1168                 case svc_updatecolors:
1169                         i = MSG_ReadByte ();
1170                         if (i >= cl.maxclients)
1171                                 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
1172                         cl.scores[i].colors = MSG_ReadByte ();
1173                         break;
1174
1175                 case svc_particle:
1176                         CL_ParseParticleEffect ();
1177                         break;
1178
1179                 case svc_effect:
1180                         CL_ParseEffect ();
1181                         break;
1182
1183                 case svc_effect2:
1184                         CL_ParseEffect2 ();
1185                         break;
1186
1187                 case svc_spawnbaseline:
1188                         i = MSG_ReadShort ();
1189                         if (i < 0 || i >= MAX_EDICTS)
1190                                 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
1191                         CL_ParseBaseline (cl_entities + i, false);
1192                         break;
1193                 case svc_spawnbaseline2:
1194                         i = MSG_ReadShort ();
1195                         if (i < 0 || i >= MAX_EDICTS)
1196                                 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline2: invalid entity number %i", i);
1197                         CL_ParseBaseline (cl_entities + i, true);
1198                         break;
1199                 case svc_spawnstatic:
1200                         CL_ParseStatic (false);
1201                         break;
1202                 case svc_spawnstatic2:
1203                         CL_ParseStatic (true);
1204                         break;
1205                 case svc_temp_entity:
1206                         CL_ParseTEnt ();
1207                         break;
1208
1209                 case svc_setpause:
1210                         cl.paused = MSG_ReadByte ();
1211                         if (cl.paused)
1212                                 CDAudio_Pause ();
1213                         else
1214                                 CDAudio_Resume ();
1215                         break;
1216
1217                 case svc_signonnum:
1218                         i = MSG_ReadByte ();
1219                         if (i <= cls.signon)
1220                                 Host_Error ("Received signon %i when at %i", i, cls.signon);
1221                         cls.signon = i;
1222                         CL_SignonReply ();
1223                         break;
1224
1225                 case svc_killedmonster:
1226                         cl.stats[STAT_MONSTERS]++;
1227                         break;
1228
1229                 case svc_foundsecret:
1230                         cl.stats[STAT_SECRETS]++;
1231                         break;
1232
1233                 case svc_updatestat:
1234                         i = MSG_ReadByte ();
1235                         if (i < 0 || i >= MAX_CL_STATS)
1236                                 Host_Error ("svc_updatestat: %i is invalid", i);
1237                         cl.stats[i] = MSG_ReadLong ();
1238                         break;
1239
1240                 case svc_spawnstaticsound:
1241                         CL_ParseStaticSound (false);
1242                         break;
1243
1244                 case svc_spawnstaticsound2:
1245                         CL_ParseStaticSound (true);
1246                         break;
1247
1248                 case svc_cdtrack:
1249                         cl.cdtrack = MSG_ReadByte ();
1250                         cl.looptrack = MSG_ReadByte ();
1251                         if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1252                                 CDAudio_Play ((qbyte)cls.forcetrack, true);
1253                         else
1254                                 CDAudio_Play ((qbyte)cl.cdtrack, true);
1255                         break;
1256
1257                 case svc_intermission:
1258                         cl.intermission = 1;
1259                         cl.completed_time = cl.time;
1260                         break;
1261
1262                 case svc_finale:
1263                         cl.intermission = 2;
1264                         cl.completed_time = cl.time;
1265                         SCR_CenterPrint (MSG_ReadString ());
1266                         break;
1267
1268                 case svc_cutscene:
1269                         cl.intermission = 3;
1270                         cl.completed_time = cl.time;
1271                         SCR_CenterPrint (MSG_ReadString ());
1272                         break;
1273
1274                 case svc_sellscreen:
1275                         Cmd_ExecuteString ("help", src_command);
1276                         break;
1277                 case svc_hidelmp:
1278                         SHOWLMP_decodehide();
1279                         break;
1280                 case svc_showlmp:
1281                         SHOWLMP_decodeshow();
1282                         break;
1283                 case svc_skybox:
1284                         R_SetSkyBox(MSG_ReadString());
1285                         break;
1286                 case svc_cgame:
1287                         {
1288                                 int length;
1289                                 length = (int) ((unsigned short) MSG_ReadShort());
1290                                 for (i = 0;i < length;i++)
1291                                         cgamenetbuffer[i] = MSG_ReadByte();
1292                                 if (!msg_badread)
1293                                         CL_CGVM_ParseNetwork(cgamenetbuffer, length);
1294                         }
1295                         break;
1296                 case svc_entities:
1297                         if (cls.signon == SIGNONS - 1)
1298                         {
1299                                 // first update is the final signon stage
1300                                 cls.signon = SIGNONS;
1301                                 CL_SignonReply ();
1302                         }
1303                         CL_ReadEntityFrame();
1304                         break;
1305                 }
1306         }
1307
1308         if (entitiesupdated)
1309                 CL_EntityUpdateEnd();
1310 }
1311