]> icculus.org git repositories - divverent/darkplaces.git/blob - cl_parse.c
major cleanup to pusher and SV_Move code, major fixes to pusher code (everything...
[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_fog", //                           51              // unfinished and obsolete
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_EntityNum
113
114 This error checks and tracks the total number of entities
115 ===============
116 */
117 entity_t        *CL_EntityNum (int num)
118 {
119         /*
120         if (num >= cl.num_entities)
121         {
122                 if (num >= MAX_EDICTS)
123                         Host_Error ("CL_EntityNum: %i is an invalid number",num);
124                 cl.num_entities = num;
125 //              while (cl.num_entities <= num)
126 //              {
127 //                      cl_entities[cl.num_entities].colormap = -1; // no special coloring
128 //                      cl.num_entities++;
129 //              }
130         }
131         */
132         if (num >= MAX_EDICTS)
133                 Host_Error ("CL_EntityNum: %i is an invalid number",num);
134                 
135         return &cl_entities[num];
136 }
137
138
139 /*
140 ==================
141 CL_ParseStartSoundPacket
142 ==================
143 */
144 void CL_ParseStartSoundPacket(int largesoundindex)
145 {
146     vec3_t  pos;
147     int         channel, ent;
148     int         sound_num;
149     int         volume;
150     int         field_mask;
151     float       attenuation;
152         int             i;
153                    
154     field_mask = MSG_ReadByte(); 
155
156     if (field_mask & SND_VOLUME)
157                 volume = MSG_ReadByte ();
158         else
159                 volume = DEFAULT_SOUND_PACKET_VOLUME;
160         
161     if (field_mask & SND_ATTENUATION)
162                 attenuation = MSG_ReadByte () / 64.0;
163         else
164                 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
165         
166         channel = MSG_ReadShort ();
167         if (largesoundindex)
168                 sound_num = (unsigned short) MSG_ReadShort ();
169         else
170                 sound_num = MSG_ReadByte ();
171
172         if (sound_num >= MAX_SOUNDS)
173                 Host_Error("CL_ParseStartSoundPacket: sound_num (%i) >= MAX_SOUNDS (%i)\n", sound_num, MAX_SOUNDS);
174
175         ent = channel >> 3;
176         channel &= 7;
177
178         if (ent > MAX_EDICTS)
179                 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
180         
181         for (i=0 ; i<3 ; i++)
182                 pos[i] = MSG_ReadCoord ();
183
184     S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
185 }       
186
187 /*
188 ==================
189 CL_KeepaliveMessage
190
191 When the client is taking a long time to load stuff, send keepalive messages
192 so the server doesn't disconnect.
193 ==================
194 */
195 void CL_KeepaliveMessage (void)
196 {
197         float   time;
198         static float lastmsg;
199         int             ret;
200         sizebuf_t       old;
201         byte            olddata[8192];
202         
203         if (sv.active)
204                 return;         // no need if server is local
205         if (cls.demoplayback)
206                 return;
207
208 // read messages from server, should just be nops
209         old = net_message;
210         memcpy (olddata, net_message.data, net_message.cursize);
211         
212         do
213         {
214                 ret = CL_GetMessage ();
215                 switch (ret)
216                 {
217                 default:
218                         Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");               
219                 case 0:
220                         break;  // nothing waiting
221                 case 1:
222                         Host_Error ("CL_KeepaliveMessage: received a message");
223                         break;
224                 case 2:
225                         if (MSG_ReadByte() != svc_nop)
226                                 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
227                         break;
228                 }
229         } while (ret);
230
231         net_message = old;
232         memcpy (net_message.data, olddata, net_message.cursize);
233
234 // check time
235         time = Sys_DoubleTime ();
236         if (time - lastmsg < 5)
237                 return;
238         lastmsg = time;
239
240 // write out a nop
241         Con_Printf ("--> client to server keepalive\n");
242
243         MSG_WriteByte (&cls.message, clc_nop);
244         NET_SendMessage (cls.netcon, &cls.message);
245         SZ_Clear (&cls.message);
246 }
247
248 void CL_ParseEntityLump(char *entdata)
249 {
250         char *data;
251         char key[128], value[4096];
252         FOG_clear(); // LordHavoc: no fog until set
253         R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set
254         data = entdata;
255         if (!data)
256                 return;
257         data = COM_Parse(data);
258         if (!data)
259                 return; // error
260         if (com_token[0] != '{')
261                 return; // error
262         while (1)
263         {
264                 data = COM_Parse(data);
265                 if (!data)
266                         return; // error
267                 if (com_token[0] == '}')
268                         break; // end of worldspawn
269                 if (com_token[0] == '_')
270                         strcpy(key, com_token + 1);
271                 else
272                         strcpy(key, com_token);
273                 while (key[strlen(key)-1] == ' ') // remove trailing spaces
274                         key[strlen(key)-1] = 0;
275                 data = COM_Parse(data);
276                 if (!data)
277                         return; // error
278                 strcpy(value, com_token);
279                 if (!strcmp("sky", key))
280                         R_SetSkyBox(value);
281                 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
282                         R_SetSkyBox(value);
283                 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
284                         R_SetSkyBox(value);
285                 else if (!strcmp("fog", key))
286                         sscanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
287                 else if (!strcmp("fog_density", key))
288                         fog_density = atof(value);
289                 else if (!strcmp("fog_red", key))
290                         fog_red = atof(value);
291                 else if (!strcmp("fog_green", key))
292                         fog_green = atof(value);
293                 else if (!strcmp("fog_blue", key))
294                         fog_blue = atof(value);
295         }
296 }
297
298 /*
299 =====================
300 CL_SignonReply
301
302 An svc_signonnum has been received, perform a client side setup
303 =====================
304 */
305 static void CL_SignonReply (void)
306 {
307         char    str[8192];
308
309 Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
310
311         switch (cls.signon)
312         {
313         case 1:
314                 MSG_WriteByte (&cls.message, clc_stringcmd);
315                 MSG_WriteString (&cls.message, "prespawn");
316                 break;
317
318         case 2:
319                 MSG_WriteByte (&cls.message, clc_stringcmd);
320                 MSG_WriteString (&cls.message, va("name \"%s\"\n", cl_name.string));
321
322                 MSG_WriteByte (&cls.message, clc_stringcmd);
323                 MSG_WriteString (&cls.message, va("color %i %i\n", cl_color.integer >> 4, cl_color.integer & 15));
324
325                 if (cl_pmodel.integer)
326                 {
327                         MSG_WriteByte (&cls.message, clc_stringcmd);
328                         MSG_WriteString (&cls.message, va("pmodel %i\n", cl_pmodel.integer));
329                 }
330
331                 MSG_WriteByte (&cls.message, clc_stringcmd);
332                 sprintf (str, "spawn %s", cls.spawnparms);
333                 MSG_WriteString (&cls.message, str);
334                 break;
335
336         case 3:
337                 MSG_WriteByte (&cls.message, clc_stringcmd);
338                 MSG_WriteString (&cls.message, "begin");
339                 break;
340
341         case 4:
342 //              SCR_EndLoadingPlaque ();                // allow normal screen updates
343                 Con_ClearNotify();
344                 break;
345         }
346 }
347
348 /*
349 ==================
350 CL_ParseServerInfo
351 ==================
352 */
353 void CL_ParseServerInfo (void)
354 {
355         char    *str;
356         int             i;
357         int             nummodels, numsounds;
358         char    model_precache[MAX_MODELS][MAX_QPATH];
359         char    sound_precache[MAX_SOUNDS][MAX_QPATH];
360
361         Con_DPrintf ("Serverinfo packet received.\n");
362 //
363 // wipe the client_state_t struct
364 //
365         CL_ClearState ();
366
367 // parse protocol version number
368         i = MSG_ReadLong ();
369         if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != 250)
370         {
371                 Con_Printf ("Server is protocol %i, not %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, PROTOCOL_VERSION);
372                 return;
373         }
374         Nehahrademcompatibility = false;
375         if (i == 250)
376                 Nehahrademcompatibility = true;
377         if (cls.demoplayback && demo_nehahra.integer)
378                 Nehahrademcompatibility = true;
379         dpprotocol = i;
380         if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2)
381                 dpprotocol = 0;
382
383 // parse maxclients
384         cl.maxclients = MSG_ReadByte ();
385         if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
386         {
387                 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
388                 return;
389         }
390         cl.scores = Mem_Alloc(cl_scores_mempool, cl.maxclients*sizeof(*cl.scores));
391
392 // parse gametype
393         cl.gametype = MSG_ReadByte ();
394
395 // parse signon message
396         str = MSG_ReadString ();
397         strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
398
399 // seperate the printfs so the server message can have a color
400         if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
401         {
402                 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");
403                 Con_Printf ("%c%s\n", 2, str);
404         }
405
406 //
407 // first we go through and touch all of the precache data that still
408 // happens to be in the cache, so precaching something else doesn't
409 // needlessly purge it
410 //
411
412         Mem_CheckSentinelsGlobal();
413
414         Mod_ClearUsed();
415
416 // precache models
417         memset (cl.model_precache, 0, sizeof(cl.model_precache));
418         for (nummodels=1 ; ; nummodels++)
419         {
420                 str = MSG_ReadString ();
421                 if (!str[0])
422                         break;
423                 if (nummodels==MAX_MODELS)
424                 {
425                         Host_Error ("Server sent too many model precaches\n");
426                         return;
427                 }
428                 if (strlen(str) >= MAX_QPATH)
429                         Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
430                 strcpy (model_precache[nummodels], str);
431                 Mod_TouchModel (str);
432         }
433
434 // precache sounds
435         memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
436         for (numsounds=1 ; ; numsounds++)
437         {
438                 str = MSG_ReadString ();
439                 if (!str[0])
440                         break;
441                 if (numsounds==MAX_SOUNDS)
442                 {
443                         Host_Error ("Server sent too many sound precaches\n");
444                         return;
445                 }
446                 if (strlen(str) >= MAX_QPATH)
447                         Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
448                 strcpy (sound_precache[numsounds], str);
449                 S_TouchSound (str);
450         }
451
452         Mod_PurgeUnused();
453
454 //
455 // now we try to load everything else until a cache allocation fails
456 //
457
458         Mem_CheckSentinelsGlobal();
459
460         for (i=1 ; i<nummodels ; i++)
461         {
462                 // LordHavoc: i == 1 means the first model is the world model
463                 cl.model_precache[i] = Mod_ForName (model_precache[i], false, false, i == 1);
464
465                 if (cl.model_precache[i] == NULL)
466                 {
467                         Host_Error("Model %s not found\n", model_precache[i]);
468                         return;
469                 }
470                 CL_KeepaliveMessage ();
471         }
472
473         Mem_CheckSentinelsGlobal();
474
475         S_BeginPrecaching ();
476         for (i=1 ; i<numsounds ; i++)
477         {
478                 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
479                 CL_KeepaliveMessage ();
480         }
481         S_EndPrecaching ();
482
483 // local state
484         cl_entities[0].render.model = cl.worldmodel = cl.model_precache[1];
485         cl_entities[0].render.scale = 1;
486         cl_entities[0].render.alpha = 1;
487
488         R_NewMap ();
489
490         Mem_CheckSentinelsGlobal();
491
492         CL_CGVM_Start();
493
494         Mem_CheckSentinelsGlobal();
495
496         noclip_anglehack = false;               // noclip is turned off at start
497 }
498
499 void CL_ValidateState(entity_state_t *s)
500 {
501         model_t *model;
502
503         if (!s->active)
504                 return;
505
506         if (s->modelindex >= MAX_MODELS)
507                 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
508
509         // colormap is client index + 1
510         if (s->colormap > cl.maxclients)
511                 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
512
513         model = cl.model_precache[s->modelindex];
514         Mod_CheckLoaded(model);
515         if (model && s->frame >= model->numframes)
516         {
517                 Con_Printf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
518                 s->frame = 0;
519         }
520         if (model && s->skin > 0 && s->skin >= model->numskins)
521         {
522                 Con_Printf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
523                 s->skin = 0;
524         }
525 }
526
527 /*
528 ==================
529 CL_ParseUpdate
530
531 Parse an entity update message from the server
532 If an entities model or origin changes from frame to frame, it must be
533 relinked.  Other attributes can change without relinking.
534 ==================
535 */
536 byte entkill[MAX_EDICTS];
537 int bitprofile[32], bitprofilecount = 0;
538 void CL_ParseUpdate (int bits)
539 {
540         int i, num, deltadie;
541         entity_t *ent;
542         entity_state_t new;
543
544         if (bits & U_MOREBITS)
545                 bits |= (MSG_ReadByte()<<8);
546         if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
547         {
548                 bits |= MSG_ReadByte() << 16;
549                 if (bits & U_EXTEND2)
550                         bits |= MSG_ReadByte() << 24;
551         }
552
553         if (bits & U_LONGENTITY)
554                 num = (unsigned) MSG_ReadShort ();
555         else
556                 num = (unsigned) MSG_ReadByte ();
557
558         if (num >= MAX_EDICTS)
559                 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
560         if (num < 1)
561                 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
562
563         // mark as visible (no kill)
564         entkill[num] = 0;
565
566         ent = CL_EntityNum (num);
567
568         for (i = 0;i < 32;i++)
569                 if (bits & (1 << i))
570                         bitprofile[i]++;
571         bitprofilecount++;
572
573         deltadie = false;
574         if (bits & U_DELTA)
575         {
576                 new = ent->state_current;
577                 if (!new.active)
578                         deltadie = true; // was not present in previous frame, leave hidden until next full update
579         }
580         else
581                 new = ent->state_baseline;
582
583         new.time = cl.mtime[0];
584
585         new.flags = 0;
586         new.active = true;
587         if (bits & U_MODEL)             new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte();
588         if (bits & U_FRAME)             new.frame = (new.frame & 0xFF00) | MSG_ReadByte();
589         if (bits & U_COLORMAP)  new.colormap = MSG_ReadByte();
590         if (bits & U_SKIN)              new.skin = MSG_ReadByte();
591         if (bits & U_EFFECTS)   new.effects = (new.effects & 0xFF00) | MSG_ReadByte();
592         if (bits & U_ORIGIN1)   new.origin[0] = MSG_ReadCoord();
593         if (bits & U_ANGLE1)    new.angles[0] = MSG_ReadAngle();
594         if (bits & U_ORIGIN2)   new.origin[1] = MSG_ReadCoord();
595         if (bits & U_ANGLE2)    new.angles[1] = MSG_ReadAngle();
596         if (bits & U_ORIGIN3)   new.origin[2] = MSG_ReadCoord();
597         if (bits & U_ANGLE3)    new.angles[2] = MSG_ReadAngle();
598         if (bits & U_STEP)              new.flags |= RENDER_STEP;
599         if (bits & U_ALPHA)             new.alpha = MSG_ReadByte();
600         if (bits & U_SCALE)             new.scale = MSG_ReadByte();
601         if (bits & U_EFFECTS2)  new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8);
602         if (bits & U_GLOWSIZE)  new.glowsize = MSG_ReadByte();
603         if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte();
604 #if 0
605         if (bits & U_COLORMOD)  {int i = MSG_ReadByte();float r = (((int) i >> 5) & 7) * 1.0 / 7, g = (((int) i >> 2) & 7) * 1.0 / 7, b = ((int) i & 3) * 1.0 / 3;Con_Printf("warning: U_COLORMOD %i (%1.2f %1.2f %1.2f) ignored\n", i, r, g, b);}
606 #else
607         // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
608         if (bits & U_COLORMOD)  MSG_ReadByte();
609 #endif
610         if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL;
611         if (bits & U_FRAME2)    new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8);
612         if (bits & U_MODEL2)    new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
613         if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL;
614         if (bits & U_EXTERIORMODEL)     new.flags |= RENDER_EXTERIORMODEL;
615
616         // LordHavoc: to allow playback of the Nehahra movie
617         if (Nehahrademcompatibility && (bits & U_EXTEND1))
618         {
619                 // LordHavoc: evil format
620                 int i = MSG_ReadFloat();
621                 int j = MSG_ReadFloat() * 255.0f;
622                 if (i == 2)
623                 {
624                         if (MSG_ReadFloat())
625                                 new.effects |= EF_FULLBRIGHT;
626                 }
627                 if (j < 0)
628                         new.alpha = 0;
629                 else if (j == 0 || j >= 255)
630                         new.alpha = 255;
631                 else
632                         new.alpha = j;
633         }
634
635         if (deltadie)
636         {
637                 // hide the entity
638                 new.active = false;
639         }
640         else
641                 CL_ValidateState(&new);
642
643         if (new.flags & RENDER_STEP) // FIXME: rename this flag?
644         {
645                 // make time identical for memcmp
646                 new.time = ent->state_current.time;
647                 if (memcmp(&new, &ent->state_current, sizeof(entity_state_t)))
648                 {
649                         // set it back to what it should be
650                         new.time = cl.mtime[0] + 0.1;
651                         // state has changed
652                         ent->state_previous = ent->state_current;
653                         ent->state_current = new;
654                         // assume 10fps animation
655                         //ent->state_previous.time = cl.mtime[0] - 0.1;
656                 }
657         }
658         else
659         {
660                 ent->state_previous = ent->state_current;
661                 ent->state_current = new;
662         }
663 }
664
665 void CL_ReadEntityFrame(void)
666 {
667         entity_t *ent;
668         entity_state_t *s;
669         entity_frame_t entityframe;
670         int i;
671         EntityFrame_Read(&cl.entitydatabase);
672         EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
673         for (i = 0;i < entityframe.numentities;i++)
674         {
675                 s = &entityframe.entitydata[i];
676                 entkill[s->number] = 0;
677                 ent = &cl_entities[s->number];
678                 memcpy(&ent->state_previous, &ent->state_current, sizeof(*s));
679                 memcpy(&ent->state_current, s, sizeof(*s));
680                 ent->state_current.time = cl.mtime[0];
681         }
682         VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
683         VectorCopy(entityframe.eye, cl.viewentoriginnew);
684 }
685
686 char *bitprofilenames[32] =
687 {
688         "U_MOREBITS",
689         "U_ORIGIN1",
690         "U_ORIGIN2",
691         "U_ORIGIN3",
692         "U_ANGLE2",
693         "U_STEP",
694         "U_FRAME",
695         "U_SIGNAL",
696         "U_ANGLE1",
697         "U_ANGLE3",
698         "U_MODEL",
699         "U_COLORMAP",
700         "U_SKIN",
701         "U_EFFECTS",
702         "U_LONGENTITY",
703         "U_EXTEND1",
704         "U_DELTA",
705         "U_ALPHA",
706         "U_SCALE",
707         "U_EFFECTS2",
708         "U_GLOWSIZE",
709         "U_GLOWCOLOR",
710         "obsolete U_COLORMOD",
711         "U_EXTEND2",
712         "U_GLOWTRAIL",
713         "U_VIEWMODEL",
714         "U_FRAME2",
715         "U_MODEL2",
716         "U_EXTERIORMODEL",
717         "U_UNUSED29",
718         "U_UNUSED30",
719         "U_EXTEND3",
720 };
721
722 void CL_BitProfile_f(void)
723 {
724         int i;
725         Con_Printf("bitprofile: %i updates\n");
726         if (bitprofilecount)
727                 for (i = 0;i < 32;i++)
728 //                      if (bitprofile[i])
729                                 Con_Printf("%s: %i %3.2f%%\n", bitprofilenames[i], bitprofile[i], bitprofile[i] * 100.0 / bitprofilecount);
730         Con_Printf("\n");
731         for (i = 0;i < 32;i++)
732                 bitprofile[i] = 0;
733         bitprofilecount = 0;
734 }
735
736 void CL_EntityUpdateSetup(void)
737 {
738         memset(entkill, 1, MAX_EDICTS);
739 }
740
741 void CL_EntityUpdateEnd(void)
742 {
743         int i;
744         for (i = 1;i < MAX_EDICTS;i++)
745                 if (entkill[i])
746                         cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
747 }
748
749 /*
750 ==================
751 CL_ParseBaseline
752 ==================
753 */
754 void CL_ParseBaseline (entity_t *ent, int large)
755 {
756         int i;
757
758         memset(&ent->state_baseline, 0, sizeof(entity_state_t));
759         ent->state_baseline.active = true;
760         if (large)
761         {
762                 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
763                 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
764         }
765         else
766         {
767                 ent->state_baseline.modelindex = MSG_ReadByte ();
768                 ent->state_baseline.frame = MSG_ReadByte ();
769         }
770         ent->state_baseline.colormap = MSG_ReadByte();
771         ent->state_baseline.skin = MSG_ReadByte();
772         for (i = 0;i < 3;i++)
773         {
774                 ent->state_baseline.origin[i] = MSG_ReadCoord ();
775                 ent->state_baseline.angles[i] = MSG_ReadAngle ();
776         }
777         ent->state_baseline.alpha = 255;
778         ent->state_baseline.scale = 16;
779         ent->state_baseline.glowsize = 0;
780         ent->state_baseline.glowcolor = 254;
781         ent->state_previous = ent->state_current = ent->state_baseline;
782
783         CL_ValidateState(&ent->state_baseline);
784 }
785
786
787 /*
788 ==================
789 CL_ParseClientdata
790
791 Server information pertaining to this client only
792 ==================
793 */
794 void CL_ParseClientdata (int bits)
795 {
796         int i, j;
797
798         bits &= 0xFFFF;
799         if (bits & SU_EXTEND1)
800                 bits |= (MSG_ReadByte() << 16);
801         if (bits & SU_EXTEND2)
802                 bits |= (MSG_ReadByte() << 24);
803
804         if (bits & SU_VIEWHEIGHT)
805                 cl.viewheight = MSG_ReadChar ();
806         else
807                 cl.viewheight = DEFAULT_VIEWHEIGHT;
808
809         if (bits & SU_IDEALPITCH)
810                 cl.idealpitch = MSG_ReadChar ();
811         else
812                 cl.idealpitch = 0;
813
814         VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
815         for (i=0 ; i<3 ; i++)
816         {
817                 if (bits & (SU_PUNCH1<<i) )
818                 {
819                         if (dpprotocol)
820                                 cl.punchangle[i] = MSG_ReadPreciseAngle();
821                         else
822                                 cl.punchangle[i] = MSG_ReadChar();
823                 }
824                 else
825                         cl.punchangle[i] = 0;
826                 if (bits & (SU_PUNCHVEC1<<i))
827                         cl.punchvector[i] = MSG_ReadCoord();
828                 else
829                         cl.punchvector[i] = 0;
830                 if (bits & (SU_VELOCITY1<<i) )
831                         cl.mvelocity[0][i] = MSG_ReadChar()*16;
832                 else
833                         cl.mvelocity[0][i] = 0;
834         }
835
836         i = MSG_ReadLong ();
837         if (cl.items != i)
838         {       // set flash times
839                 for (j=0 ; j<32 ; j++)
840                         if ( (i & (1<<j)) && !(cl.items & (1<<j)))
841                                 cl.item_gettime[j] = cl.time;
842                 cl.items = i;
843         }
844
845         cl.onground = (bits & SU_ONGROUND) != 0;
846         cl.inwater = (bits & SU_INWATER) != 0;
847
848         cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
849         cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
850         cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
851         cl.stats[STAT_HEALTH] = MSG_ReadShort();
852         cl.stats[STAT_AMMO] = MSG_ReadByte();
853
854         cl.stats[STAT_SHELLS] = MSG_ReadByte();
855         cl.stats[STAT_NAILS] = MSG_ReadByte();
856         cl.stats[STAT_ROCKETS] = MSG_ReadByte();
857         cl.stats[STAT_CELLS] = MSG_ReadByte();
858
859         i = MSG_ReadByte ();
860
861         if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
862                 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
863         else
864                 cl.stats[STAT_ACTIVEWEAPON] = i;
865
866         cl.viewzoomold = cl.viewzoomnew; // for interpolation
867         if (bits & SU_VIEWZOOM)
868         {
869                 i = MSG_ReadByte();
870                 if (i < 2)
871                         i = 2;
872                 cl.viewzoomnew = (float) i * (1.0f / 255.0f);
873         }
874         else
875                 cl.viewzoomnew = 1;
876
877 }
878
879 /*
880 =====================
881 CL_ParseStatic
882 =====================
883 */
884 void CL_ParseStatic (int large)
885 {
886         entity_t *ent;
887
888         if (cl.num_statics >= MAX_STATIC_ENTITIES)
889                 Host_Error ("Too many static entities");
890         ent = &cl_static_entities[cl.num_statics++];
891         CL_ParseBaseline (ent, large);
892
893 // copy it to the current state
894         ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
895         ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
896         ent->render.framelerp = 0;
897         // make torchs play out of sync
898         ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1);
899         ent->render.colormap = -1; // no special coloring
900         ent->render.skinnum = ent->state_baseline.skin;
901         ent->render.effects = ent->state_baseline.effects;
902         ent->render.alpha = 1;
903         ent->render.scale = 1;
904         ent->render.alpha = 1;
905
906         VectorCopy (ent->state_baseline.origin, ent->render.origin);
907         VectorCopy (ent->state_baseline.angles, ent->render.angles);    
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 byte cgamenetbuffer[65536];
963
964 /*
965 =====================
966 CL_ParseServerMessage
967 =====================
968 */
969 void CL_ParseServerMessage (void)
970 {
971         int                     cmd;
972         int                     i, entitiesupdated;
973         byte            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         CL_EntityUpdateSetup();
993
994         while (1)
995         {
996                 if (msg_badread)
997                         Host_Error ("CL_ParseServerMessage: Bad server message");
998
999                 cmd = MSG_ReadByte ();
1000
1001                 if (cmd == -1)
1002                 {
1003                         SHOWNET("END OF MESSAGE");
1004                         break;          // end of message
1005                 }
1006
1007                 cmdindex = cmdcount & 31;
1008                 cmdcount++;
1009                 cmdlog[cmdindex] = cmd;
1010
1011                 // if the high bit of the command byte is set, it is a fast update
1012                 if (cmd & 128)
1013                 {
1014                         // 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)
1015                         temp = "entity";
1016                         cmdlogname[cmdindex] = temp;
1017                         SHOWNET("fast update");
1018                         if (cls.signon == SIGNONS - 1)
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 //                      Con_Printf ("svc_nop\n");
1065                         break;
1066
1067                 case svc_time:
1068                         // handle old protocols which do not have entity update ranges
1069                         entitiesupdated = true;
1070                         cl.mtime[1] = cl.mtime[0];
1071                         cl.mtime[0] = MSG_ReadFloat ();
1072                         break;
1073
1074                 case svc_clientdata:
1075                         i = MSG_ReadShort ();
1076                         CL_ParseClientdata (i);
1077                         break;
1078
1079                 case svc_version:
1080                         i = MSG_ReadLong ();
1081                         if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != 250)
1082                                 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, PROTOCOL_VERSION);
1083                         Nehahrademcompatibility = false;
1084                         if (i == 250)
1085                                 Nehahrademcompatibility = true;
1086                         if (cls.demoplayback && demo_nehahra.integer)
1087                                 Nehahrademcompatibility = true;
1088                         dpprotocol = i;
1089                         if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2)
1090                                 dpprotocol = 0;
1091                         break;
1092
1093                 case svc_disconnect:
1094                         Host_EndGame ("Server disconnected\n");
1095
1096                 case svc_print:
1097                         Con_Printf ("%s", MSG_ReadString ());
1098                         break;
1099
1100                 case svc_centerprint:
1101                         SCR_CenterPrint (MSG_ReadString ());
1102                         break;
1103
1104                 case svc_stufftext:
1105                         Cbuf_AddText (MSG_ReadString ());
1106                         break;
1107
1108                 case svc_damage:
1109                         V_ParseDamage ();
1110                         break;
1111
1112                 case svc_serverinfo:
1113                         CL_ParseServerInfo ();
1114 //                      vid.recalc_refdef = true;       // leave intermission full screen
1115                         break;
1116
1117                 case svc_setangle:
1118                         for (i=0 ; i<3 ; i++)
1119                                 cl.viewangles[i] = MSG_ReadAngle ();
1120                         break;
1121
1122                 case svc_setview:
1123                         cl.viewentity = MSG_ReadShort ();
1124                         break;
1125
1126                 case svc_lightstyle:
1127                         i = MSG_ReadByte ();
1128                         if (i >= MAX_LIGHTSTYLES)
1129                                 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1130                         strncpy (cl_lightstyle[i].map,  MSG_ReadString(), MAX_STYLESTRING - 1);
1131                         cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1132                         cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1133                         break;
1134
1135                 case svc_sound:
1136                         CL_ParseStartSoundPacket(false);
1137                         break;
1138
1139                 case svc_sound2:
1140                         CL_ParseStartSoundPacket(true);
1141                         break;
1142
1143                 case svc_stopsound:
1144                         i = MSG_ReadShort();
1145                         S_StopSound(i>>3, i&7);
1146                         break;
1147
1148                 case svc_updatename:
1149                         i = MSG_ReadByte ();
1150                         if (i >= cl.maxclients)
1151                                 Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
1152                         strcpy (cl.scores[i].name, MSG_ReadString ());
1153                         break;
1154
1155                 case svc_updatefrags:
1156                         i = MSG_ReadByte ();
1157                         if (i >= cl.maxclients)
1158                                 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
1159                         cl.scores[i].frags = MSG_ReadShort ();
1160                         break;
1161
1162                 case svc_updatecolors:
1163                         i = MSG_ReadByte ();
1164                         if (i >= cl.maxclients)
1165                                 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
1166                         cl.scores[i].colors = MSG_ReadByte ();
1167                         break;
1168
1169                 case svc_particle:
1170                         CL_ParseParticleEffect ();
1171                         break;
1172
1173                 case svc_effect:
1174                         CL_ParseEffect ();
1175                         break;
1176
1177                 case svc_effect2:
1178                         CL_ParseEffect2 ();
1179                         break;
1180
1181                 case svc_spawnbaseline:
1182                         i = MSG_ReadShort ();
1183                         // must use CL_EntityNum() to force cl.num_entities up
1184                         CL_ParseBaseline (CL_EntityNum(i), false);
1185                         break;
1186                 case svc_spawnbaseline2:
1187                         i = MSG_ReadShort ();
1188                         // must use CL_EntityNum() to force cl.num_entities up
1189                         CL_ParseBaseline (CL_EntityNum(i), true);
1190                         break;
1191                 case svc_spawnstatic:
1192                         CL_ParseStatic (false);
1193                         break;
1194                 case svc_spawnstatic2:
1195                         CL_ParseStatic (true);
1196                         break;
1197                 case svc_temp_entity:
1198                         CL_ParseTEnt ();
1199                         break;
1200
1201                 case svc_setpause:
1202                         cl.paused = MSG_ReadByte ();
1203                         if (cl.paused)
1204                                 CDAudio_Pause ();
1205                         else
1206                                 CDAudio_Resume ();
1207                         break;
1208
1209                 case svc_signonnum:
1210                         i = MSG_ReadByte ();
1211                         if (i <= cls.signon)
1212                                 Host_Error ("Received signon %i when at %i", i, cls.signon);
1213                         cls.signon = i;
1214                         CL_SignonReply ();
1215                         break;
1216
1217                 case svc_killedmonster:
1218                         cl.stats[STAT_MONSTERS]++;
1219                         break;
1220
1221                 case svc_foundsecret:
1222                         cl.stats[STAT_SECRETS]++;
1223                         break;
1224
1225                 case svc_updatestat:
1226                         i = MSG_ReadByte ();
1227                         if (i < 0 || i >= MAX_CL_STATS)
1228                                 Host_Error ("svc_updatestat: %i is invalid", i);
1229                         cl.stats[i] = MSG_ReadLong ();
1230                         break;
1231
1232                 case svc_spawnstaticsound:
1233                         CL_ParseStaticSound (false);
1234                         break;
1235
1236                 case svc_spawnstaticsound2:
1237                         CL_ParseStaticSound (true);
1238                         break;
1239
1240                 case svc_cdtrack:
1241                         cl.cdtrack = MSG_ReadByte ();
1242                         cl.looptrack = MSG_ReadByte ();
1243                         if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1244                                 CDAudio_Play ((byte)cls.forcetrack, true);
1245                         else
1246                                 CDAudio_Play ((byte)cl.cdtrack, true);
1247                         break;
1248
1249                 case svc_intermission:
1250                         cl.intermission = 1;
1251                         cl.completed_time = cl.time;
1252 //                      vid.recalc_refdef = true;       // go to full screen
1253                         break;
1254
1255                 case svc_finale:
1256                         cl.intermission = 2;
1257                         cl.completed_time = cl.time;
1258 //                      vid.recalc_refdef = true;       // go to full screen
1259                         SCR_CenterPrint (MSG_ReadString ());
1260                         break;
1261
1262                 case svc_cutscene:
1263                         cl.intermission = 3;
1264                         cl.completed_time = cl.time;
1265 //                      vid.recalc_refdef = true;       // go to full screen
1266                         SCR_CenterPrint (MSG_ReadString ());
1267                         break;
1268
1269                 case svc_sellscreen:
1270                         Cmd_ExecuteString ("help", src_command);
1271                         break;
1272                 case svc_hidelmp:
1273                         SHOWLMP_decodehide();
1274                         break;
1275                 case svc_showlmp:
1276                         SHOWLMP_decodeshow();
1277                         break;
1278                 case svc_skybox:
1279                         R_SetSkyBox(MSG_ReadString());
1280                         break;
1281                 case svc_cgame:
1282                         {
1283                                 int length;
1284                                 length = (int) ((unsigned short) MSG_ReadShort());
1285                                 /*
1286                                 if (cgamenetbuffersize < length)
1287                                 {
1288                                         cgamenetbuffersize = length;
1289                                         if (cgamenetbuffer)
1290                                                 Mem_Free(cgamenetbuffer);
1291                                         cgamenetbuffer = Mem_Alloc(cgamenetbuffersize);
1292                                 }
1293                                 */
1294                                 for (i = 0;i < length;i++)
1295                                         cgamenetbuffer[i] = MSG_ReadByte();
1296                                 if (!msg_badread)
1297                                         CL_CGVM_ParseNetwork(cgamenetbuffer, length);
1298                         }
1299                         break;
1300                 case svc_entities:
1301                         if (cls.signon == SIGNONS - 1)
1302                         {       // first update is the final signon stage
1303                                 cls.signon = SIGNONS;
1304                                 CL_SignonReply ();
1305                         }
1306                         CL_ReadEntityFrame();
1307                         break;
1308                 }
1309         }
1310
1311         if (entitiesupdated)
1312                 CL_EntityUpdateEnd();
1313 }