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
70 "svc_skybox", // [string] skyname
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
95 //=============================================================================
97 cvar_t demo_nehahra = {0, "demo_nehahra", "0"};
99 void CL_Parse_Init(void)
101 // LordHavoc: added demo_nehahra cvar
102 Cvar_RegisterVariable (&demo_nehahra);
103 if (gamemode == GAME_NEHAHRA)
104 Cvar_SetValue("demo_nehahra", 1);
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
114 This error checks and tracks the total number of entities
117 entity_t *CL_EntityNum (int num)
120 if (num >= cl.num_entities)
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)
127 // cl_entities[cl.num_entities].colormap = -1; // no special coloring
128 // cl.num_entities++;
132 if (num >= MAX_EDICTS)
133 Host_Error ("CL_EntityNum: %i is an invalid number",num);
135 return &cl_entities[num];
141 CL_ParseStartSoundPacket
144 void CL_ParseStartSoundPacket(int largesoundindex)
154 field_mask = MSG_ReadByte();
156 if (field_mask & SND_VOLUME)
157 volume = MSG_ReadByte ();
159 volume = DEFAULT_SOUND_PACKET_VOLUME;
161 if (field_mask & SND_ATTENUATION)
162 attenuation = MSG_ReadByte () / 64.0;
164 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
166 channel = MSG_ReadShort ();
168 sound_num = (unsigned short) MSG_ReadShort ();
170 sound_num = MSG_ReadByte ();
172 if (sound_num >= MAX_SOUNDS)
173 Host_Error("CL_ParseStartSoundPacket: sound_num (%i) >= MAX_SOUNDS (%i)\n", sound_num, MAX_SOUNDS);
178 if (ent > MAX_EDICTS)
179 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
181 for (i=0 ; i<3 ; i++)
182 pos[i] = MSG_ReadCoord ();
184 S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
191 When the client is taking a long time to load stuff, send keepalive messages
192 so the server doesn't disconnect.
195 void CL_KeepaliveMessage (void)
198 static float lastmsg;
205 return; // no need if server is local
206 if (cls.demoplayback)
209 // read messages from server, should just be nops
211 memcpy (olddata, net_message.data, net_message.cursize);
215 ret = CL_GetMessage ();
219 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
221 break; // nothing waiting
223 Host_Error ("CL_KeepaliveMessage: received a message");
228 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
234 memcpy (net_message.data, olddata, net_message.cursize);
237 time = Sys_DoubleTime ();
238 if (time - lastmsg < 5)
243 Con_Printf ("--> client to server keepalive\n");
245 MSG_WriteByte (&cls.message, clc_nop);
246 NET_SendMessage (cls.netcon, &cls.message);
247 SZ_Clear (&cls.message);
250 void CL_ParseEntityLump(char *entdata)
253 char key[128], value[4096];
254 FOG_clear(); // LordHavoc: no fog until set
255 R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set
259 data = COM_Parse(data);
262 if (com_token[0] != '{')
266 data = COM_Parse(data);
269 if (com_token[0] == '}')
270 break; // end of worldspawn
271 if (com_token[0] == '_')
272 strcpy(key, com_token + 1);
274 strcpy(key, com_token);
275 while (key[strlen(key)-1] == ' ') // remove trailing spaces
276 key[strlen(key)-1] = 0;
277 data = COM_Parse(data);
280 strcpy(value, com_token);
281 if (!strcmp("sky", key))
283 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
285 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
287 else if (!strcmp("fog", key))
288 sscanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
289 else if (!strcmp("fog_density", key))
290 fog_density = atof(value);
291 else if (!strcmp("fog_red", key))
292 fog_red = atof(value);
293 else if (!strcmp("fog_green", key))
294 fog_green = atof(value);
295 else if (!strcmp("fog_blue", key))
296 fog_blue = atof(value);
301 =====================
304 An svc_signonnum has been received, perform a client side setup
305 =====================
307 static void CL_SignonReply (void)
311 Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
316 MSG_WriteByte (&cls.message, clc_stringcmd);
317 MSG_WriteString (&cls.message, "prespawn");
321 MSG_WriteByte (&cls.message, clc_stringcmd);
322 MSG_WriteString (&cls.message, va("name \"%s\"\n", cl_name.string));
324 MSG_WriteByte (&cls.message, clc_stringcmd);
325 MSG_WriteString (&cls.message, va("color %i %i\n", cl_color.integer >> 4, cl_color.integer & 15));
327 if (cl_pmodel.integer)
329 MSG_WriteByte (&cls.message, clc_stringcmd);
330 MSG_WriteString (&cls.message, va("pmodel %i\n", cl_pmodel.integer));
333 MSG_WriteByte (&cls.message, clc_stringcmd);
334 sprintf (str, "spawn %s", cls.spawnparms);
335 MSG_WriteString (&cls.message, str);
339 MSG_WriteByte (&cls.message, clc_stringcmd);
340 MSG_WriteString (&cls.message, "begin");
344 SCR_EndLoadingPlaque (); // allow normal screen updates
355 void CL_ParseServerInfo (void)
359 int nummodels, numsounds;
360 char model_precache[MAX_MODELS][MAX_QPATH];
361 char sound_precache[MAX_SOUNDS][MAX_QPATH];
363 Con_DPrintf ("Serverinfo packet received.\n");
365 // wipe the client_state_t struct
369 // parse protocol version number
371 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
373 Con_Printf ("Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
376 Nehahrademcompatibility = false;
378 Nehahrademcompatibility = true;
379 if (cls.demoplayback && demo_nehahra.integer)
380 Nehahrademcompatibility = true;
382 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
386 cl.maxclients = MSG_ReadByte ();
387 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
389 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
392 cl.scores = Mem_Alloc(cl_scores_mempool, cl.maxclients*sizeof(*cl.scores));
395 cl.gametype = MSG_ReadByte ();
397 // parse signon message
398 str = MSG_ReadString ();
399 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
401 // seperate the printfs so the server message can have a color
402 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
404 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");
405 Con_Printf ("%c%s\n", 2, str);
409 // first we go through and touch all of the precache data that still
410 // happens to be in the cache, so precaching something else doesn't
411 // needlessly purge it
414 Mem_CheckSentinelsGlobal();
419 memset (cl.model_precache, 0, sizeof(cl.model_precache));
420 for (nummodels=1 ; ; nummodels++)
422 str = MSG_ReadString ();
425 if (nummodels==MAX_MODELS)
427 Host_Error ("Server sent too many model precaches\n");
430 if (strlen(str) >= MAX_QPATH)
431 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
432 strcpy (model_precache[nummodels], str);
433 Mod_TouchModel (str);
437 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
438 for (numsounds=1 ; ; numsounds++)
440 str = MSG_ReadString ();
443 if (numsounds==MAX_SOUNDS)
445 Host_Error ("Server sent too many sound precaches\n");
448 if (strlen(str) >= MAX_QPATH)
449 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
450 strcpy (sound_precache[numsounds], str);
457 // now we try to load everything else until a cache allocation fails
460 for (i=1 ; i<nummodels ; i++)
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);
465 if (cl.model_precache[i] == NULL)
467 Host_Error("Model %s not found\n", model_precache[i]);
470 CL_KeepaliveMessage ();
473 S_BeginPrecaching ();
474 for (i=1 ; i<numsounds ; i++)
476 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
477 CL_KeepaliveMessage ();
482 cl_entities[0].render.model = cl.worldmodel = cl.model_precache[1];
483 cl_entities[0].render.scale = 1;
484 cl_entities[0].render.alpha = 1;
490 Mem_CheckSentinelsGlobal();
492 noclip_anglehack = false; // noclip is turned off at start
495 void CL_ValidateState(entity_state_t *s)
502 if (s->modelindex >= MAX_MODELS)
503 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
505 // colormap is client index + 1
506 if (s->colormap > cl.maxclients)
507 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
509 model = cl.model_precache[s->modelindex];
510 Mod_CheckLoaded(model);
511 if (model && s->frame >= model->numframes)
513 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
516 if (model && s->skin > 0 && s->skin >= model->numskins)
518 Con_DPrintf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
527 Parse an entity update message from the server
528 If an entities model or origin changes from frame to frame, it must be
529 relinked. Other attributes can change without relinking.
532 qbyte entkill[MAX_EDICTS];
533 int bitprofile[32], bitprofilecount = 0;
534 void CL_ParseUpdate (int bits)
536 int i, num, deltadie;
540 if (bits & U_MOREBITS)
541 bits |= (MSG_ReadByte()<<8);
542 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
544 bits |= MSG_ReadByte() << 16;
545 if (bits & U_EXTEND2)
546 bits |= MSG_ReadByte() << 24;
549 if (bits & U_LONGENTITY)
550 num = (unsigned) MSG_ReadShort ();
552 num = (unsigned) MSG_ReadByte ();
554 if (num >= MAX_EDICTS)
555 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
557 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
559 // mark as visible (no kill)
562 ent = CL_EntityNum (num);
564 for (i = 0;i < 32;i++)
572 new = ent->state_current;
574 deltadie = true; // was not present in previous frame, leave hidden until next full update
577 new = ent->state_baseline;
579 new.time = cl.mtime[0];
583 if (bits & U_MODEL) new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte();
584 if (bits & U_FRAME) new.frame = (new.frame & 0xFF00) | MSG_ReadByte();
585 if (bits & U_COLORMAP) new.colormap = MSG_ReadByte();
586 if (bits & U_SKIN) new.skin = MSG_ReadByte();
587 if (bits & U_EFFECTS) new.effects = (new.effects & 0xFF00) | MSG_ReadByte();
588 if (bits & U_ORIGIN1) new.origin[0] = MSG_ReadCoord();
589 if (bits & U_ANGLE1) new.angles[0] = MSG_ReadAngle();
590 if (bits & U_ORIGIN2) new.origin[1] = MSG_ReadCoord();
591 if (bits & U_ANGLE2) new.angles[1] = MSG_ReadAngle();
592 if (bits & U_ORIGIN3) new.origin[2] = MSG_ReadCoord();
593 if (bits & U_ANGLE3) new.angles[2] = MSG_ReadAngle();
594 if (bits & U_STEP) new.flags |= RENDER_STEP;
595 if (bits & U_ALPHA) new.alpha = MSG_ReadByte();
596 if (bits & U_SCALE) new.scale = MSG_ReadByte();
597 if (bits & U_EFFECTS2) new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8);
598 if (bits & U_GLOWSIZE) new.glowsize = MSG_ReadByte();
599 if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte();
601 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);}
603 // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
604 if (bits & U_COLORMOD) MSG_ReadByte();
606 if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL;
607 if (bits & U_FRAME2) new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8);
608 if (bits & U_MODEL2) new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
609 if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL;
610 if (bits & U_EXTERIORMODEL) new.flags |= RENDER_EXTERIORMODEL;
612 // LordHavoc: to allow playback of the Nehahra movie
613 if (Nehahrademcompatibility && (bits & U_EXTEND1))
615 // LordHavoc: evil format
616 int i = MSG_ReadFloat();
617 int j = MSG_ReadFloat() * 255.0f;
622 new.effects |= EF_FULLBRIGHT;
626 else if (j == 0 || j >= 255)
638 CL_ValidateState(&new);
640 if (new.flags & RENDER_STEP) // FIXME: rename this flag?
642 // make time identical for memcmp
643 new.time = ent->state_current.time;
644 if (memcmp(&new, &ent->state_current, sizeof(entity_state_t)))
646 // set it back to what it should be
647 new.time = cl.mtime[0] + 0.1;
649 ent->state_previous = ent->state_current;
650 ent->state_current = new;
651 // assume 10fps animation
652 //ent->state_previous.time = cl.mtime[0] - 0.1;
657 ent->state_previous = ent->state_current;
658 ent->state_current = new;
662 void CL_ReadEntityFrame(void)
666 entity_frame_t entityframe;
668 EntityFrame_Read(&cl.entitydatabase);
669 EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
670 for (i = 0;i < entityframe.numentities;i++)
672 s = &entityframe.entitydata[i];
673 entkill[s->number] = 0;
674 ent = &cl_entities[s->number];
675 memcpy(&ent->state_previous, &ent->state_current, sizeof(*s));
676 memcpy(&ent->state_current, s, sizeof(*s));
677 ent->state_current.time = cl.mtime[0];
679 VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
680 VectorCopy(entityframe.eye, cl.viewentoriginnew);
683 char *bitprofilenames[32] =
707 "obsolete U_COLORMOD",
719 void CL_BitProfile_f(void)
722 Con_Printf("bitprofile: %i updates\n");
724 for (i = 0;i < 32;i++)
725 // if (bitprofile[i])
726 Con_Printf("%s: %i %3.2f%%\n", bitprofilenames[i], bitprofile[i], bitprofile[i] * 100.0 / bitprofilecount);
728 for (i = 0;i < 32;i++)
733 void CL_EntityUpdateSetup(void)
735 memset(entkill, 1, MAX_EDICTS);
738 void CL_EntityUpdateEnd(void)
741 for (i = 1;i < MAX_EDICTS;i++)
743 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
751 void CL_ParseBaseline (entity_t *ent, int large)
755 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
756 ent->state_baseline.active = true;
759 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
760 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
764 ent->state_baseline.modelindex = MSG_ReadByte ();
765 ent->state_baseline.frame = MSG_ReadByte ();
767 ent->state_baseline.colormap = MSG_ReadByte();
768 ent->state_baseline.skin = MSG_ReadByte();
769 for (i = 0;i < 3;i++)
771 ent->state_baseline.origin[i] = MSG_ReadCoord ();
772 ent->state_baseline.angles[i] = MSG_ReadAngle ();
774 ent->state_baseline.alpha = 255;
775 ent->state_baseline.scale = 16;
776 ent->state_baseline.glowsize = 0;
777 ent->state_baseline.glowcolor = 254;
778 ent->state_previous = ent->state_current = ent->state_baseline;
780 CL_ValidateState(&ent->state_baseline);
788 Server information pertaining to this client only
791 void CL_ParseClientdata (int bits)
796 if (bits & SU_EXTEND1)
797 bits |= (MSG_ReadByte() << 16);
798 if (bits & SU_EXTEND2)
799 bits |= (MSG_ReadByte() << 24);
801 if (bits & SU_VIEWHEIGHT)
802 cl.viewheight = MSG_ReadChar ();
804 cl.viewheight = DEFAULT_VIEWHEIGHT;
806 if (bits & SU_IDEALPITCH)
807 cl.idealpitch = MSG_ReadChar ();
811 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
812 for (i=0 ; i<3 ; i++)
814 if (bits & (SU_PUNCH1<<i) )
817 cl.punchangle[i] = MSG_ReadPreciseAngle();
819 cl.punchangle[i] = MSG_ReadChar();
822 cl.punchangle[i] = 0;
823 if (bits & (SU_PUNCHVEC1<<i))
824 cl.punchvector[i] = MSG_ReadCoord();
826 cl.punchvector[i] = 0;
827 if (bits & (SU_VELOCITY1<<i) )
828 cl.mvelocity[0][i] = MSG_ReadChar()*16;
830 cl.mvelocity[0][i] = 0;
836 for (j=0 ; j<32 ; j++)
837 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
838 cl.item_gettime[j] = cl.time;
842 cl.onground = (bits & SU_ONGROUND) != 0;
843 cl.inwater = (bits & SU_INWATER) != 0;
845 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
846 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
847 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
848 cl.stats[STAT_HEALTH] = MSG_ReadShort();
849 cl.stats[STAT_AMMO] = MSG_ReadByte();
851 cl.stats[STAT_SHELLS] = MSG_ReadByte();
852 cl.stats[STAT_NAILS] = MSG_ReadByte();
853 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
854 cl.stats[STAT_CELLS] = MSG_ReadByte();
858 if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
859 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
861 cl.stats[STAT_ACTIVEWEAPON] = i;
863 cl.viewzoomold = cl.viewzoomnew; // for interpolation
864 if (bits & SU_VIEWZOOM)
869 cl.viewzoomnew = (float) i * (1.0f / 255.0f);
877 =====================
879 =====================
881 void CL_ParseStatic (int large)
885 if (cl.num_statics >= MAX_STATIC_ENTITIES)
886 Host_Error ("Too many static entities");
887 ent = &cl_static_entities[cl.num_statics++];
888 CL_ParseBaseline (ent, large);
890 // copy it to the current state
891 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
892 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
893 ent->render.framelerp = 0;
894 // make torchs play out of sync
895 ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1);
896 ent->render.colormap = -1; // no special coloring
897 ent->render.skinnum = ent->state_baseline.skin;
898 ent->render.effects = ent->state_baseline.effects;
899 ent->render.alpha = 1;
900 ent->render.scale = 1;
901 ent->render.alpha = 1;
903 VectorCopy (ent->state_baseline.origin, ent->render.origin);
904 VectorCopy (ent->state_baseline.angles, ent->render.angles);
912 void CL_ParseStaticSound (int large)
915 int sound_num, vol, atten;
919 sound_num = (unsigned short) MSG_ReadShort ();
921 sound_num = MSG_ReadByte ();
922 vol = MSG_ReadByte ();
923 atten = MSG_ReadByte ();
925 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
928 void CL_ParseEffect (void)
931 int modelindex, startframe, framecount, framerate;
934 modelindex = MSG_ReadByte ();
935 startframe = MSG_ReadByte ();
936 framecount = MSG_ReadByte ();
937 framerate = MSG_ReadByte ();
939 CL_Effect(org, modelindex, startframe, framecount, framerate);
942 void CL_ParseEffect2 (void)
945 int modelindex, startframe, framecount, framerate;
948 modelindex = MSG_ReadShort ();
949 startframe = MSG_ReadShort ();
950 framecount = MSG_ReadByte ();
951 framerate = MSG_ReadByte ();
953 CL_Effect(org, modelindex, startframe, framecount, framerate);
957 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
959 static qbyte cgamenetbuffer[65536];
962 =====================
963 CL_ParseServerMessage
964 =====================
966 void CL_ParseServerMessage (void)
969 int i, entitiesupdated;
971 char *cmdlogname[32], *temp;
972 int cmdindex, cmdcount = 0;
975 // if recording demos, copy the message out
977 if (cl_shownet.integer == 1)
978 Con_Printf ("%i ",net_message.cursize);
979 else if (cl_shownet.integer == 2)
980 Con_Printf ("------------------\n");
982 cl.onground = false; // unless the server says otherwise
988 entitiesupdated = false;
989 CL_EntityUpdateSetup();
994 Host_Error ("CL_ParseServerMessage: Bad server message");
996 cmd = MSG_ReadByte ();
1000 SHOWNET("END OF MESSAGE");
1001 break; // end of message
1004 cmdindex = cmdcount & 31;
1006 cmdlog[cmdindex] = cmd;
1008 // if the high bit of the command byte is set, it is a fast update
1011 // 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)
1013 cmdlogname[cmdindex] = temp;
1014 SHOWNET("fast update");
1015 if (cls.signon == SIGNONS - 1)
1016 { // first update is the final signon stage
1017 cls.signon = SIGNONS;
1020 CL_ParseUpdate (cmd&127);
1024 SHOWNET(svc_strings[cmd]);
1025 cmdlogname[cmdindex] = svc_strings[cmd];
1026 if (!cmdlogname[cmdindex])
1028 // 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)
1030 cmdlogname[cmdindex] = temp;
1038 char description[32*64], temp[64];
1040 strcpy(description, "packet dump: ");
1044 count = cmdcount - i;
1048 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
1049 strcat(description, temp);
1054 description[strlen(description)-1] = '\n'; // replace the last space with a newline
1055 Con_Printf("%s", description);
1056 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
1061 // Con_Printf ("svc_nop\n");
1065 // handle old protocols which do not have entity update ranges
1066 entitiesupdated = true;
1067 cl.mtime[1] = cl.mtime[0];
1068 cl.mtime[0] = MSG_ReadFloat ();
1071 case svc_clientdata:
1072 i = MSG_ReadShort ();
1073 CL_ParseClientdata (i);
1077 i = MSG_ReadLong ();
1078 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
1079 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
1080 Nehahrademcompatibility = false;
1082 Nehahrademcompatibility = true;
1083 if (cls.demoplayback && demo_nehahra.integer)
1084 Nehahrademcompatibility = true;
1086 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
1090 case svc_disconnect:
1091 Host_EndGame ("Server disconnected\n");
1094 Con_Printf ("%s", MSG_ReadString ());
1097 case svc_centerprint:
1098 SCR_CenterPrint (MSG_ReadString ());
1102 Cbuf_AddText (MSG_ReadString ());
1109 case svc_serverinfo:
1110 CL_ParseServerInfo ();
1111 // vid.recalc_refdef = true; // leave intermission full screen
1115 for (i=0 ; i<3 ; i++)
1116 cl.viewangles[i] = MSG_ReadAngle ();
1120 cl.viewentity = MSG_ReadShort ();
1123 case svc_lightstyle:
1124 i = MSG_ReadByte ();
1125 if (i >= MAX_LIGHTSTYLES)
1126 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1127 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1128 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1129 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1133 CL_ParseStartSoundPacket(false);
1137 CL_ParseStartSoundPacket(true);
1141 i = MSG_ReadShort();
1142 S_StopSound(i>>3, i&7);
1145 case svc_updatename:
1146 i = MSG_ReadByte ();
1147 if (i >= cl.maxclients)
1148 Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
1149 strcpy (cl.scores[i].name, MSG_ReadString ());
1152 case svc_updatefrags:
1153 i = MSG_ReadByte ();
1154 if (i >= cl.maxclients)
1155 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
1156 cl.scores[i].frags = MSG_ReadShort ();
1159 case svc_updatecolors:
1160 i = MSG_ReadByte ();
1161 if (i >= cl.maxclients)
1162 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
1163 cl.scores[i].colors = MSG_ReadByte ();
1167 CL_ParseParticleEffect ();
1178 case svc_spawnbaseline:
1179 i = MSG_ReadShort ();
1180 // must use CL_EntityNum() to force cl.num_entities up
1181 CL_ParseBaseline (CL_EntityNum(i), false);
1183 case svc_spawnbaseline2:
1184 i = MSG_ReadShort ();
1185 // must use CL_EntityNum() to force cl.num_entities up
1186 CL_ParseBaseline (CL_EntityNum(i), true);
1188 case svc_spawnstatic:
1189 CL_ParseStatic (false);
1191 case svc_spawnstatic2:
1192 CL_ParseStatic (true);
1194 case svc_temp_entity:
1199 cl.paused = MSG_ReadByte ();
1207 i = MSG_ReadByte ();
1208 if (i <= cls.signon)
1209 Host_Error ("Received signon %i when at %i", i, cls.signon);
1214 case svc_killedmonster:
1215 cl.stats[STAT_MONSTERS]++;
1218 case svc_foundsecret:
1219 cl.stats[STAT_SECRETS]++;
1222 case svc_updatestat:
1223 i = MSG_ReadByte ();
1224 if (i < 0 || i >= MAX_CL_STATS)
1225 Host_Error ("svc_updatestat: %i is invalid", i);
1226 cl.stats[i] = MSG_ReadLong ();
1229 case svc_spawnstaticsound:
1230 CL_ParseStaticSound (false);
1233 case svc_spawnstaticsound2:
1234 CL_ParseStaticSound (true);
1238 cl.cdtrack = MSG_ReadByte ();
1239 cl.looptrack = MSG_ReadByte ();
1240 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1241 CDAudio_Play ((qbyte)cls.forcetrack, true);
1243 CDAudio_Play ((qbyte)cl.cdtrack, true);
1246 case svc_intermission:
1247 cl.intermission = 1;
1248 cl.completed_time = cl.time;
1249 // vid.recalc_refdef = true; // go to full screen
1253 cl.intermission = 2;
1254 cl.completed_time = cl.time;
1255 // vid.recalc_refdef = true; // go to full screen
1256 SCR_CenterPrint (MSG_ReadString ());
1260 cl.intermission = 3;
1261 cl.completed_time = cl.time;
1262 // vid.recalc_refdef = true; // go to full screen
1263 SCR_CenterPrint (MSG_ReadString ());
1266 case svc_sellscreen:
1267 Cmd_ExecuteString ("help", src_command);
1270 SHOWLMP_decodehide();
1273 SHOWLMP_decodeshow();
1276 R_SetSkyBox(MSG_ReadString());
1281 length = (int) ((unsigned short) MSG_ReadShort());
1283 if (cgamenetbuffersize < length)
1285 cgamenetbuffersize = length;
1287 Mem_Free(cgamenetbuffer);
1288 cgamenetbuffer = Mem_Alloc(cgamenetbuffersize);
1291 for (i = 0;i < length;i++)
1292 cgamenetbuffer[i] = MSG_ReadByte();
1294 CL_CGVM_ParseNetwork(cgamenetbuffer, length);
1298 if (cls.signon == SIGNONS - 1)
1299 { // first update is the final signon stage
1300 cls.signon = SIGNONS;
1303 CL_ReadEntityFrame();
1308 if (entitiesupdated)
1309 CL_EntityUpdateEnd();