2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
20 // cl_parse.c -- parse a message received from the server
24 char *svc_strings[128] =
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
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
53 "OBSOLETE svc_spawnbinary",
56 "svc_temp_entity", // <variable>
62 "svc_spawnstaticsound",
64 "svc_finale", // [string] music [string] text
65 "svc_cdtrack", // [byte] track [byte] looptrack
68 "svc_showlmp", // [string] iconlabel [string] lmpfile [short] x [short] y
69 "svc_hidelmp", // [string] iconlabel
85 "svc_effect", // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
86 "svc_effect2", // [vector] org [short] modelindex [byte] startframe [byte] framecount [byte] framerate
89 //=============================================================================
91 qboolean Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
92 qboolean dpprotocol; // LordHavoc: whether or not the current network stream is the enhanced DarkPlaces protocol
98 This error checks and tracks the total number of entities
101 entity_t *CL_EntityNum (int num)
104 if (num >= cl.num_entities)
106 if (num >= MAX_EDICTS)
107 Host_Error ("CL_EntityNum: %i is an invalid number",num);
108 cl.num_entities = num;
109 // while (cl.num_entities <= num)
111 // cl_entities[cl.num_entities].colormap = -1; // no special coloring
112 // cl.num_entities++;
116 if (num >= MAX_EDICTS)
117 Host_Error ("CL_EntityNum: %i is an invalid number",num);
119 return &cl_entities[num];
125 CL_ParseStartSoundPacket
128 void CL_ParseStartSoundPacket(int largesoundindex)
138 field_mask = MSG_ReadByte();
140 if (field_mask & SND_VOLUME)
141 volume = MSG_ReadByte ();
143 volume = DEFAULT_SOUND_PACKET_VOLUME;
145 if (field_mask & SND_ATTENUATION)
146 attenuation = MSG_ReadByte () / 64.0;
148 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
150 channel = MSG_ReadShort ();
152 sound_num = (unsigned short) MSG_ReadShort ();
154 sound_num = MSG_ReadByte ();
156 if (sound_num >= MAX_SOUNDS)
157 Host_Error("CL_ParseStartSoundPacket: sound_num (%i) >= MAX_SOUNDS (%i)\n", sound_num, MAX_SOUNDS);
162 if (ent > MAX_EDICTS)
163 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
165 for (i=0 ; i<3 ; i++)
166 pos[i] = MSG_ReadCoord ();
168 S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
175 When the client is taking a long time to load stuff, send keepalive messages
176 so the server doesn't disconnect.
179 void CL_KeepaliveMessage (void)
182 static float lastmsg;
188 return; // no need if server is local
189 if (cls.demoplayback)
192 // read messages from server, should just be nops
194 memcpy (olddata, net_message.data, net_message.cursize);
198 ret = CL_GetMessage ();
202 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
204 break; // nothing waiting
206 Host_Error ("CL_KeepaliveMessage: received a message");
209 if (MSG_ReadByte() != svc_nop)
210 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
216 memcpy (net_message.data, olddata, net_message.cursize);
219 time = Sys_FloatTime ();
220 if (time - lastmsg < 5)
225 Con_Printf ("--> client to server keepalive\n");
227 MSG_WriteByte (&cls.message, clc_nop);
228 NET_SendMessage (cls.netcon, &cls.message);
229 SZ_Clear (&cls.message);
232 extern qboolean isworldmodel;
233 extern char skyname[];
234 extern void R_SetSkyBox (char *sky);
235 extern void FOG_clear();
236 extern cvar_t r_farclip;
238 void CL_ParseEntityLump(char *entdata)
241 char key[128], value[4096];
244 FOG_clear(); // LordHavoc: no fog until set
245 skyname[0] = 0; // LordHavoc: no enviroment mapped sky until set
246 r_farclip.value = 6144; // LordHavoc: default farclip distance
250 data = COM_Parse(data);
252 return; // valid exit
253 if (com_token[0] != '{')
257 data = COM_Parse(data);
260 if (com_token[0] == '}')
261 return; // since we're just parsing the first ent (worldspawn), exit
262 strcpy(key, com_token);
263 while (key[strlen(key)-1] == ' ') // remove trailing spaces
264 key[strlen(key)-1] = 0;
265 data = COM_Parse(data);
268 strcpy(value, com_token);
269 if (!strcmp("sky", key))
271 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
273 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
275 else if (!strcmp("farclip", key))
277 r_farclip.value = atof(value);
278 if (r_farclip.value < 64)
279 r_farclip.value = 64;
281 else if (!strcmp("fog", key))
283 scanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
286 else if (!strcmp("fog_density", key))
287 fog_density = atof(value);
288 else if (!strcmp("fog_red", key))
289 fog_red = atof(value);
290 else if (!strcmp("fog_green", key))
291 fog_green = atof(value);
292 else if (!strcmp("fog_blue", key))
293 fog_blue = atof(value);
294 else if (!strcmp("wad", key)) // for HalfLife maps
297 for (i = 0;i < 4096;i++)
298 if (value[i] != ';' && value[i] != '\\' && value[i] != '/' && value[i] != ':')
304 // ignore path - the \\ check is for HalfLife... stupid windoze 'programmers'...
305 if (value[i] == '\\' || value[i] == '/' || value[i] == ':')
307 else if (value[i] == ';' || value[i] == 0)
311 strcpy(wadname, "textures/");
312 strcat(wadname, &value[j]);
313 W_LoadTextureWadFile (wadname, false);
329 extern cvar_t demo_nehahra;
330 void CL_ParseServerInfo (void)
334 int nummodels, numsounds;
335 char model_precache[MAX_MODELS][MAX_QPATH];
336 char sound_precache[MAX_SOUNDS][MAX_QPATH];
338 Con_DPrintf ("Serverinfo packet received.\n");
340 // wipe the client_state_t struct
344 // parse protocol version number
346 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
348 Con_Printf ("Server returned version %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
351 Nehahrademcompatibility = false;
353 Nehahrademcompatibility = true;
354 if (cls.demoplayback && demo_nehahra.value)
355 Nehahrademcompatibility = true;
356 dpprotocol = i == DPPROTOCOL_VERSION;
359 cl.maxclients = MSG_ReadByte ();
360 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
362 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
365 cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
368 cl.gametype = MSG_ReadByte ();
370 // parse signon message
371 str = MSG_ReadString ();
372 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
374 // seperate the printfs so the server message can have a color
375 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
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);
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
388 memset (cl.model_precache, 0, sizeof(cl.model_precache));
389 for (nummodels=1 ; ; nummodels++)
391 str = MSG_ReadString ();
394 if (nummodels==MAX_MODELS)
396 Con_Printf ("Server sent too many model precaches\n");
399 if (strlen(str) >= MAX_QPATH)
400 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
401 strcpy (model_precache[nummodels], str);
402 Mod_TouchModel (str);
406 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
407 for (numsounds=1 ; ; numsounds++)
409 str = MSG_ReadString ();
412 if (numsounds==MAX_SOUNDS)
414 Con_Printf ("Server sent too many sound precaches\n");
417 if (strlen(str) >= MAX_QPATH)
418 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
419 strcpy (sound_precache[numsounds], str);
424 // now we try to load everything else until a cache allocation fails
427 for (i=1 ; i<nummodels ; i++)
429 isworldmodel = i == 1; // LordHavoc: first model is the world model
430 cl.model_precache[i] = Mod_ForName (model_precache[i], false);
431 if (cl.model_precache[i] == NULL)
433 Con_Printf("Model %s not found\n", model_precache[i]);
436 CL_KeepaliveMessage ();
439 S_BeginPrecaching ();
440 for (i=1 ; i<numsounds ; i++)
442 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
443 CL_KeepaliveMessage ();
449 cl_entities[0].render.model = cl.worldmodel = cl.model_precache[1];
453 Hunk_Check (); // make sure nothing is hurt
455 noclip_anglehack = false; // noclip is turned off at start
458 void CL_ValidateState(entity_state_t *s)
462 if (s->modelindex >= MAX_MODELS)
463 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
465 // colormap is client index + 1
466 if (s->colormap > cl.maxclients)
467 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
469 model = cl.model_precache[s->modelindex];
470 if (model && s->frame >= model->numframes)
472 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
481 Parse an entity update message from the server
482 If an entities model or origin changes from frame to frame, it must be
483 relinked. Other attributes can change without relinking.
486 byte entkill[MAX_EDICTS];
487 void CL_ParseUpdate (int bits)
492 if (cls.signon == SIGNONS - 1)
493 { // first update is the final signon stage
494 cls.signon = SIGNONS;
498 if (bits & U_MOREBITS)
499 bits |= (MSG_ReadByte()<<8);
500 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
502 bits |= MSG_ReadByte() << 16;
503 if (bits & U_EXTEND2)
504 bits |= MSG_ReadByte() << 24;
507 if (bits & U_LONGENTITY)
508 num = (unsigned) MSG_ReadShort ();
510 num = (unsigned) MSG_ReadByte ();
512 if (num >= MAX_EDICTS)
513 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
515 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
517 // mark as visible (no kill)
520 ent = CL_EntityNum (num);
522 ent->state_previous = ent->state_current;
526 if (!ent->state_current.modelindex)
527 deltadie = true; // was not present in previous frame, leave hidden until next full update
530 ent->state_current = ent->state_baseline;
532 ent->state_current.time = cl.mtime[0];
534 ent->state_current.flags = 0;
535 if (bits & U_MODEL) ent->state_current.modelindex = (ent->state_current.modelindex & 0xFF00) | MSG_ReadByte();
536 if (bits & U_FRAME) ent->state_current.frame = (ent->state_current.frame & 0xFF00) | MSG_ReadByte();
537 if (bits & U_COLORMAP) ent->state_current.colormap = MSG_ReadByte();
538 if (bits & U_SKIN) ent->state_current.skin = MSG_ReadByte();
539 if (bits & U_EFFECTS) ent->state_current.effects = (ent->state_current.effects & 0xFF00) | MSG_ReadByte();
540 if (bits & U_ORIGIN1) ent->state_current.origin[0] = MSG_ReadCoord();
541 if (bits & U_ANGLE1) ent->state_current.angles[0] = MSG_ReadAngle();
542 if (bits & U_ORIGIN2) ent->state_current.origin[1] = MSG_ReadCoord();
543 if (bits & U_ANGLE2) ent->state_current.angles[1] = MSG_ReadAngle();
544 if (bits & U_ORIGIN3) ent->state_current.origin[2] = MSG_ReadCoord();
545 if (bits & U_ANGLE3) ent->state_current.angles[2] = MSG_ReadAngle();
546 if (bits & U_STEP) ent->state_current.flags |= RENDER_STEP;
547 if (bits & U_ALPHA) ent->state_current.alpha = MSG_ReadByte();
548 if (bits & U_SCALE) ent->state_current.scale = MSG_ReadByte();
549 if (bits & U_EFFECTS2) ent->state_current.effects = (ent->state_current.effects & 0x00FF) | (MSG_ReadByte() << 8);
550 if (bits & U_GLOWSIZE) ent->state_current.glowsize = MSG_ReadByte();
551 if (bits & U_GLOWCOLOR) ent->state_current.glowcolor = MSG_ReadByte();
552 if (bits & U_GLOWTRAIL) ent->state_current.flags |= RENDER_GLOWTRAIL;
553 if (bits & U_COLORMOD) ent->state_current.colormod = MSG_ReadByte();
554 if (bits & U_FRAME2) ent->state_current.frame = (ent->state_current.frame & 0x00FF) | (MSG_ReadByte() << 8);
555 if (bits & U_MODEL2) ent->state_current.modelindex = (ent->state_current.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
556 if (bits & U_VIEWMODEL) ent->state_current.flags |= RENDER_VIEWMODEL;
558 // LordHavoc: to allow playback of the Nehahra movie
559 if (Nehahrademcompatibility && (bits & U_EXTEND1))
561 // LordHavoc: evil format
562 int i = MSG_ReadFloat();
563 int j = MSG_ReadFloat() * 255.0f;
567 ent->state_current.effects |= EF_FULLBRIGHT;
570 ent->state_current.alpha = 0;
571 else if (j == 0 || j >= 255)
572 ent->state_current.alpha = 255;
574 ent->state_current.alpha = j;
580 ent->state_current.modelindex = 0;
584 CL_ValidateState(&ent->state_current);
587 if (!ent->state_current.modelindex)
592 Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i %i\n", num, ent->state_previous.modelindex, ent->state_current.modelindex);
594 Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i\n", num, ent->state_previous.modelindex);
599 Con_Printf("CL_ParseUpdate: NULL model on %i: %i %i\n", num, ent->state_baseline.modelindex, ent->state_current.modelindex);
601 Con_Printf("CL_ParseUpdate: NULL model on %i: %i\n", num, ent->state_baseline.modelindex);
608 int entityupdatestart;
609 void CL_EntityUpdateBegin(int start)
611 if (start < 0 || start >= MAX_EDICTS)
612 Host_Error("CL_EntityUpdateBegin: start (%i) < 0 or >= MAX_EDICTS (%i)\n", start, MAX_EDICTS);
613 entityupdatestart = start;
614 memset(entkill, 1, MAX_EDICTS);
617 void CL_EntityUpdateEnd(int end)
620 if (end < 0 || end > MAX_EDICTS)
621 Host_Error("CL_EntityUpdateEnd: end (%i) < 0 or > MAX_EDICTS (%i)\n", end, MAX_EDICTS);
622 for (i = entityupdatestart;i < end;i++)
624 cl_entities[i].state_current.modelindex = 0;
632 void CL_ParseBaseline (entity_t *ent, int largemodelindex)
636 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
638 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
640 ent->state_baseline.modelindex = MSG_ReadByte ();
641 ent->state_baseline.frame = MSG_ReadByte ();
642 ent->state_baseline.colormap = MSG_ReadByte();
643 ent->state_baseline.skin = MSG_ReadByte();
644 for (i = 0;i < 3;i++)
646 ent->state_baseline.origin[i] = MSG_ReadCoord ();
647 ent->state_baseline.angles[i] = MSG_ReadAngle ();
649 ent->state_baseline.alpha = 255;
650 ent->state_baseline.scale = 16;
651 ent->state_baseline.glowsize = 0;
652 ent->state_baseline.glowcolor = 254;
653 ent->state_baseline.colormod = 255;
654 ent->state_previous = ent->state_current = ent->state_baseline;
656 CL_ValidateState(&ent->state_baseline);
664 Server information pertaining to this client only
667 void CL_ParseClientdata (int bits)
672 if (bits & SU_EXTEND1)
673 bits |= (MSG_ReadByte() << 16);
674 if (bits & SU_EXTEND2)
675 bits |= (MSG_ReadByte() << 24);
677 if (bits & SU_VIEWHEIGHT)
678 cl.viewheight = MSG_ReadChar ();
680 cl.viewheight = DEFAULT_VIEWHEIGHT;
682 if (bits & SU_IDEALPITCH)
683 cl.idealpitch = MSG_ReadChar ();
687 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
688 for (i=0 ; i<3 ; i++)
690 if (bits & (SU_PUNCH1<<i) )
693 cl.punchangle[i] = MSG_ReadPreciseAngle();
695 cl.punchangle[i] = MSG_ReadChar();
698 cl.punchangle[i] = 0;
699 if (bits & (SU_PUNCHVEC1<<i))
700 cl.punchvector[i] = MSG_ReadFloatCoord();
702 cl.punchvector[i] = 0;
703 if (bits & (SU_VELOCITY1<<i) )
704 cl.mvelocity[0][i] = MSG_ReadChar()*16;
706 cl.mvelocity[0][i] = 0;
712 for (j=0 ; j<32 ; j++)
713 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
714 cl.item_gettime[j] = cl.time;
718 cl.onground = (bits & SU_ONGROUND) != 0;
719 cl.inwater = (bits & SU_INWATER) != 0;
721 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
722 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
723 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
724 cl.stats[STAT_HEALTH] = MSG_ReadShort();
725 cl.stats[STAT_AMMO] = MSG_ReadByte();
727 cl.stats[STAT_SHELLS] = MSG_ReadByte();
728 cl.stats[STAT_NAILS] = MSG_ReadByte();
729 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
730 cl.stats[STAT_CELLS] = MSG_ReadByte();
735 cl.stats[STAT_ACTIVEWEAPON] = i;
737 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
741 =====================
743 =====================
745 void CL_ParseStatic (int largemodelindex)
749 if (cl.num_statics >= MAX_STATIC_ENTITIES)
750 Host_Error ("Too many static entities");
751 ent = &cl_static_entities[cl.num_statics++];
752 CL_ParseBaseline (ent, largemodelindex);
754 // copy it to the current state
755 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
756 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
757 ent->render.framelerp = 0;
758 ent->render.lerp_starttime = -1;
759 // make torchs play out of sync
760 ent->render.frame1start = ent->render.frame2start = -(rand() & 32767);
761 ent->render.colormap = -1; // no special coloring
762 ent->render.skinnum = ent->state_baseline.skin;
763 ent->render.effects = ent->state_baseline.effects;
764 ent->render.alpha = 1;
765 ent->render.scale = 1;
766 ent->render.alpha = 1;
767 ent->render.glowsize = 0;
768 ent->render.glowcolor = 254;
769 ent->render.colormod[0] = ent->render.colormod[1] = ent->render.colormod[2] = 1;
771 VectorCopy (ent->state_baseline.origin, ent->render.origin);
772 VectorCopy (ent->state_baseline.angles, ent->render.angles);
781 void CL_ParseStaticSound (void)
784 int sound_num, vol, atten;
787 sound_num = MSG_ReadByte ();
788 vol = MSG_ReadByte ();
789 atten = MSG_ReadByte ();
791 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
794 void CL_ParseEffect (void)
797 int modelindex, startframe, framecount, framerate;
800 modelindex = MSG_ReadByte ();
801 startframe = MSG_ReadByte ();
802 framecount = MSG_ReadByte ();
803 framerate = MSG_ReadByte ();
805 CL_Effect(org, modelindex, startframe, framecount, framerate);
808 void CL_ParseEffect2 (void)
811 int modelindex, startframe, framecount, framerate;
814 modelindex = MSG_ReadShort ();
815 startframe = MSG_ReadByte ();
816 framecount = MSG_ReadByte ();
817 framerate = MSG_ReadByte ();
819 CL_Effect(org, modelindex, startframe, framecount, framerate);
823 #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
825 extern void SHOWLMP_decodehide();
826 extern void SHOWLMP_decodeshow();
827 extern void R_SetSkyBox(char* sky);
831 =====================
832 CL_ParseServerMessage
833 =====================
835 void CL_ParseServerMessage (void)
840 char *cmdlogname[32], *temp;
841 int cmdindex, cmdcount = 0;
844 // if recording demos, copy the message out
846 if (cl_shownet.value == 1)
848 Con_Printf ("%i ",net_message.cursize);
851 else if (cl_shownet.value == 2)
853 Con_Printf ("------------------\n");
857 cl.onground = false; // unless the server says otherwise
868 Host_Error ("CL_ParseServerMessage: Bad server message");
870 cmd = MSG_ReadByte ();
874 SHOWNET("END OF MESSAGE");
875 break; // end of message
878 cmdindex = cmdcount & 31;
880 cmdlog[cmdindex] = cmd;
882 // if the high bit of the command byte is set, it is a fast update
885 // 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)
887 cmdlogname[cmdindex] = temp;
888 SHOWNET("fast update");
889 CL_ParseUpdate (cmd&127);
893 SHOWNET(svc_strings[cmd]);
894 cmdlogname[cmdindex] = svc_strings[cmd];
895 if (!cmdlogname[cmdindex])
897 // 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)
899 cmdlogname[cmdindex] = temp;
907 char description[32*64], temp[64];
909 strcpy(description, "packet dump: ");
913 count = cmdcount - i;
917 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
918 strcat(description, temp);
923 description[strlen(description)-1] = '\n'; // replace the last space with a newline
924 Con_Printf(description);
925 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
930 // Con_Printf ("svc_nop\n");
934 // handle old protocols which do not have entity update ranges
935 CL_EntityUpdateBegin(0);
937 cl.mtime[1] = cl.mtime[0];
938 cl.mtime[0] = MSG_ReadFloat ();
942 i = MSG_ReadShort ();
943 CL_ParseClientdata (i);
948 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
949 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
950 Nehahrademcompatibility = false;
952 Nehahrademcompatibility = true;
953 if (cls.demoplayback && demo_nehahra.value)
954 Nehahrademcompatibility = true;
955 dpprotocol = i == DPPROTOCOL_VERSION;
959 Host_EndGame ("Server disconnected\n");
962 Con_Printf ("%s", MSG_ReadString ());
965 case svc_centerprint:
966 SCR_CenterPrint (MSG_ReadString ());
970 Cbuf_AddText (MSG_ReadString ());
978 CL_ParseServerInfo ();
979 vid.recalc_refdef = true; // leave intermission full screen
983 for (i=0 ; i<3 ; i++)
984 cl.viewangles[i] = MSG_ReadAngle ();
988 cl.viewentity = MSG_ReadShort ();
993 if (i >= MAX_LIGHTSTYLES)
994 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
995 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
996 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
997 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1001 CL_ParseStartSoundPacket(false);
1005 CL_ParseStartSoundPacket(true);
1009 i = MSG_ReadShort();
1010 S_StopSound(i>>3, i&7);
1013 case svc_updatename:
1014 i = MSG_ReadByte ();
1015 if (i >= cl.maxclients)
1016 Host_Error ("CL_ParseServerMessage: svc_updatename >= MAX_SCOREBOARD");
1017 strcpy (cl.scores[i].name, MSG_ReadString ());
1020 case svc_updatefrags:
1021 i = MSG_ReadByte ();
1022 if (i >= cl.maxclients)
1023 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= MAX_SCOREBOARD");
1024 cl.scores[i].frags = MSG_ReadShort ();
1027 case svc_updatecolors:
1028 i = MSG_ReadByte ();
1029 if (i >= cl.maxclients)
1030 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= MAX_SCOREBOARD");
1031 cl.scores[i].colors = MSG_ReadByte ();
1035 R_ParseParticleEffect ();
1046 case svc_spawnbaseline:
1047 i = MSG_ReadShort ();
1048 // must use CL_EntityNum() to force cl.num_entities up
1049 CL_ParseBaseline (CL_EntityNum(i), false);
1051 case svc_spawnbaseline2:
1052 i = MSG_ReadShort ();
1053 // must use CL_EntityNum() to force cl.num_entities up
1054 CL_ParseBaseline (CL_EntityNum(i), false);
1056 case svc_spawnstatic:
1057 CL_ParseStatic (false);
1059 case svc_spawnstatic2:
1060 CL_ParseStatic (true);
1062 case svc_temp_entity:
1067 cl.paused = MSG_ReadByte ();
1075 i = MSG_ReadByte ();
1076 if (i <= cls.signon)
1077 Host_Error ("Received signon %i when at %i", i, cls.signon);
1082 case svc_killedmonster:
1083 cl.stats[STAT_MONSTERS]++;
1086 case svc_foundsecret:
1087 cl.stats[STAT_SECRETS]++;
1090 case svc_updatestat:
1091 i = MSG_ReadByte ();
1092 if (i < 0 || i >= MAX_CL_STATS)
1093 Host_Error ("svc_updatestat: %i is invalid", i);
1094 cl.stats[i] = MSG_ReadLong ();
1097 case svc_spawnstaticsound:
1098 CL_ParseStaticSound ();
1102 cl.cdtrack = MSG_ReadByte ();
1103 cl.looptrack = MSG_ReadByte ();
1104 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1105 CDAudio_Play ((byte)cls.forcetrack, true);
1107 CDAudio_Play ((byte)cl.cdtrack, true);
1110 case svc_intermission:
1111 cl.intermission = 1;
1112 cl.completed_time = cl.time;
1113 vid.recalc_refdef = true; // go to full screen
1117 cl.intermission = 2;
1118 cl.completed_time = cl.time;
1119 vid.recalc_refdef = true; // go to full screen
1120 SCR_CenterPrint (MSG_ReadString ());
1124 cl.intermission = 3;
1125 cl.completed_time = cl.time;
1126 vid.recalc_refdef = true; // go to full screen
1127 SCR_CenterPrint (MSG_ReadString ());
1130 case svc_sellscreen:
1131 Cmd_ExecuteString ("help", src_command);
1134 SHOWLMP_decodehide();
1137 SHOWLMP_decodeshow();
1139 case svc_entitiesbegin:
1140 // the beginning of an entity update range
1141 CL_EntityUpdateBegin((unsigned) MSG_ReadShort());
1143 case svc_entitiesend:
1144 // the end of an entity update range
1145 CL_EntityUpdateEnd((unsigned) MSG_ReadShort());
1152 CL_EntityUpdateEnd(MAX_EDICTS);