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_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
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;
204 return; // no need if server is local
205 if (cls.demoplayback)
208 // read messages from server, should just be nops
210 memcpy (olddata, net_message.data, net_message.cursize);
214 ret = CL_GetMessage ();
218 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
220 break; // nothing waiting
222 Host_Error ("CL_KeepaliveMessage: received a message");
225 if (MSG_ReadByte() != svc_nop)
226 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
232 memcpy (net_message.data, olddata, net_message.cursize);
235 time = Sys_DoubleTime ();
236 if (time - lastmsg < 5)
241 Con_Printf ("--> client to server keepalive\n");
243 MSG_WriteByte (&cls.message, clc_nop);
244 NET_SendMessage (cls.netcon, &cls.message);
245 SZ_Clear (&cls.message);
248 void CL_ParseEntityLump(char *entdata)
251 char key[128], value[4096];
252 FOG_clear(); // LordHavoc: no fog until set
253 R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set
257 data = COM_Parse(data);
260 if (com_token[0] != '{')
264 data = COM_Parse(data);
267 if (com_token[0] == '}')
268 break; // end of worldspawn
269 if (com_token[0] == '_')
270 strcpy(key, com_token + 1);
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);
278 strcpy(value, com_token);
279 if (!strcmp("sky", key))
281 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
283 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
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);
299 =====================
302 An svc_signonnum has been received, perform a client side setup
303 =====================
305 static void CL_SignonReply (void)
309 Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
314 MSG_WriteByte (&cls.message, clc_stringcmd);
315 MSG_WriteString (&cls.message, "prespawn");
319 MSG_WriteByte (&cls.message, clc_stringcmd);
320 MSG_WriteString (&cls.message, va("name \"%s\"\n", cl_name.string));
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));
325 if (cl_pmodel.integer)
327 MSG_WriteByte (&cls.message, clc_stringcmd);
328 MSG_WriteString (&cls.message, va("pmodel %i\n", cl_pmodel.integer));
331 MSG_WriteByte (&cls.message, clc_stringcmd);
332 sprintf (str, "spawn %s", cls.spawnparms);
333 MSG_WriteString (&cls.message, str);
337 MSG_WriteByte (&cls.message, clc_stringcmd);
338 MSG_WriteString (&cls.message, "begin");
342 // SCR_EndLoadingPlaque (); // allow normal screen updates
353 void CL_ParseServerInfo (void)
357 int nummodels, numsounds;
358 char model_precache[MAX_MODELS][MAX_QPATH];
359 char sound_precache[MAX_SOUNDS][MAX_QPATH];
361 Con_DPrintf ("Serverinfo packet received.\n");
363 // wipe the client_state_t struct
367 // parse protocol version number
369 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != 250)
371 Con_Printf ("Server is protocol %i, not %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, PROTOCOL_VERSION);
374 Nehahrademcompatibility = false;
376 Nehahrademcompatibility = true;
377 if (cls.demoplayback && demo_nehahra.integer)
378 Nehahrademcompatibility = true;
380 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2)
384 cl.maxclients = MSG_ReadByte ();
385 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
387 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
390 cl.scores = Mem_Alloc(cl_scores_mempool, cl.maxclients*sizeof(*cl.scores));
393 cl.gametype = MSG_ReadByte ();
395 // parse signon message
396 str = MSG_ReadString ();
397 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
399 // seperate the printfs so the server message can have a color
400 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
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);
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
412 Mem_CheckSentinelsGlobal();
417 memset (cl.model_precache, 0, sizeof(cl.model_precache));
418 for (nummodels=1 ; ; nummodels++)
420 str = MSG_ReadString ();
423 if (nummodels==MAX_MODELS)
425 Host_Error ("Server sent too many model precaches\n");
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);
435 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
436 for (numsounds=1 ; ; numsounds++)
438 str = MSG_ReadString ();
441 if (numsounds==MAX_SOUNDS)
443 Host_Error ("Server sent too many sound precaches\n");
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);
455 // now we try to load everything else until a cache allocation fails
458 Mem_CheckSentinelsGlobal();
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 Mem_CheckSentinelsGlobal();
475 S_BeginPrecaching ();
476 for (i=1 ; i<numsounds ; i++)
478 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
479 CL_KeepaliveMessage ();
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;
490 Mem_CheckSentinelsGlobal();
494 Mem_CheckSentinelsGlobal();
496 noclip_anglehack = false; // noclip is turned off at start
499 void CL_ValidateState(entity_state_t *s)
506 if (s->modelindex >= MAX_MODELS)
507 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
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);
513 model = cl.model_precache[s->modelindex];
514 Mod_CheckLoaded(model);
515 if (model && s->frame >= model->numframes)
517 Con_Printf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
520 if (model && s->skin > 0 && s->skin >= model->numskins)
522 Con_Printf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
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.
536 byte entkill[MAX_EDICTS];
537 int bitprofile[32], bitprofilecount = 0;
538 void CL_ParseUpdate (int bits)
540 int i, num, deltadie;
544 if (bits & U_MOREBITS)
545 bits |= (MSG_ReadByte()<<8);
546 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
548 bits |= MSG_ReadByte() << 16;
549 if (bits & U_EXTEND2)
550 bits |= MSG_ReadByte() << 24;
553 if (bits & U_LONGENTITY)
554 num = (unsigned) MSG_ReadShort ();
556 num = (unsigned) MSG_ReadByte ();
558 if (num >= MAX_EDICTS)
559 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
561 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
563 // mark as visible (no kill)
566 ent = CL_EntityNum (num);
568 for (i = 0;i < 32;i++)
576 new = ent->state_current;
578 deltadie = true; // was not present in previous frame, leave hidden until next full update
581 new = ent->state_baseline;
583 new.time = cl.mtime[0];
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();
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);}
607 // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
608 if (bits & U_COLORMOD) MSG_ReadByte();
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;
616 // LordHavoc: to allow playback of the Nehahra movie
617 if (Nehahrademcompatibility && (bits & U_EXTEND1))
619 // LordHavoc: evil format
620 int i = MSG_ReadFloat();
621 int j = MSG_ReadFloat() * 255.0f;
625 new.effects |= EF_FULLBRIGHT;
629 else if (j == 0 || j >= 255)
641 CL_ValidateState(&new);
643 if (new.flags & RENDER_STEP) // FIXME: rename this flag?
645 // make time identical for memcmp
646 new.time = ent->state_current.time;
647 if (memcmp(&new, &ent->state_current, sizeof(entity_state_t)))
649 // set it back to what it should be
650 new.time = cl.mtime[0] + 0.1;
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;
660 ent->state_previous = ent->state_current;
661 ent->state_current = new;
665 void CL_ReadEntityFrame(void)
669 entity_frame_t entityframe;
671 EntityFrame_Read(&cl.entitydatabase);
672 EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
673 for (i = 0;i < entityframe.numentities;i++)
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];
682 VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
683 VectorCopy(entityframe.eye, cl.viewentoriginnew);
686 char *bitprofilenames[32] =
710 "obsolete U_COLORMOD",
722 void CL_BitProfile_f(void)
725 Con_Printf("bitprofile: %i updates\n");
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);
731 for (i = 0;i < 32;i++)
736 void CL_EntityUpdateSetup(void)
738 memset(entkill, 1, MAX_EDICTS);
741 void CL_EntityUpdateEnd(void)
744 for (i = 1;i < MAX_EDICTS;i++)
746 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
754 void CL_ParseBaseline (entity_t *ent, int large)
758 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
759 ent->state_baseline.active = true;
762 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
763 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
767 ent->state_baseline.modelindex = MSG_ReadByte ();
768 ent->state_baseline.frame = MSG_ReadByte ();
770 ent->state_baseline.colormap = MSG_ReadByte();
771 ent->state_baseline.skin = MSG_ReadByte();
772 for (i = 0;i < 3;i++)
774 ent->state_baseline.origin[i] = MSG_ReadCoord ();
775 ent->state_baseline.angles[i] = MSG_ReadAngle ();
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;
783 CL_ValidateState(&ent->state_baseline);
791 Server information pertaining to this client only
794 void CL_ParseClientdata (int bits)
799 if (bits & SU_EXTEND1)
800 bits |= (MSG_ReadByte() << 16);
801 if (bits & SU_EXTEND2)
802 bits |= (MSG_ReadByte() << 24);
804 if (bits & SU_VIEWHEIGHT)
805 cl.viewheight = MSG_ReadChar ();
807 cl.viewheight = DEFAULT_VIEWHEIGHT;
809 if (bits & SU_IDEALPITCH)
810 cl.idealpitch = MSG_ReadChar ();
814 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
815 for (i=0 ; i<3 ; i++)
817 if (bits & (SU_PUNCH1<<i) )
820 cl.punchangle[i] = MSG_ReadPreciseAngle();
822 cl.punchangle[i] = MSG_ReadChar();
825 cl.punchangle[i] = 0;
826 if (bits & (SU_PUNCHVEC1<<i))
827 cl.punchvector[i] = MSG_ReadCoord();
829 cl.punchvector[i] = 0;
830 if (bits & (SU_VELOCITY1<<i) )
831 cl.mvelocity[0][i] = MSG_ReadChar()*16;
833 cl.mvelocity[0][i] = 0;
839 for (j=0 ; j<32 ; j++)
840 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
841 cl.item_gettime[j] = cl.time;
845 cl.onground = (bits & SU_ONGROUND) != 0;
846 cl.inwater = (bits & SU_INWATER) != 0;
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();
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();
861 if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
862 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
864 cl.stats[STAT_ACTIVEWEAPON] = i;
866 cl.viewzoomold = cl.viewzoomnew; // for interpolation
867 if (bits & SU_VIEWZOOM)
872 cl.viewzoomnew = (float) i * (1.0f / 255.0f);
880 =====================
882 =====================
884 void CL_ParseStatic (int large)
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);
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;
906 VectorCopy (ent->state_baseline.origin, ent->render.origin);
907 VectorCopy (ent->state_baseline.angles, ent->render.angles);
915 void CL_ParseStaticSound (int large)
918 int sound_num, vol, atten;
922 sound_num = (unsigned short) MSG_ReadShort ();
924 sound_num = MSG_ReadByte ();
925 vol = MSG_ReadByte ();
926 atten = MSG_ReadByte ();
928 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
931 void CL_ParseEffect (void)
934 int modelindex, startframe, framecount, framerate;
937 modelindex = MSG_ReadByte ();
938 startframe = MSG_ReadByte ();
939 framecount = MSG_ReadByte ();
940 framerate = MSG_ReadByte ();
942 CL_Effect(org, modelindex, startframe, framecount, framerate);
945 void CL_ParseEffect2 (void)
948 int modelindex, startframe, framecount, framerate;
951 modelindex = MSG_ReadShort ();
952 startframe = MSG_ReadShort ();
953 framecount = MSG_ReadByte ();
954 framerate = MSG_ReadByte ();
956 CL_Effect(org, modelindex, startframe, framecount, framerate);
960 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
962 static byte cgamenetbuffer[65536];
965 =====================
966 CL_ParseServerMessage
967 =====================
969 void CL_ParseServerMessage (void)
972 int i, entitiesupdated;
974 char *cmdlogname[32], *temp;
975 int cmdindex, cmdcount = 0;
978 // if recording demos, copy the message out
980 if (cl_shownet.integer == 1)
981 Con_Printf ("%i ",net_message.cursize);
982 else if (cl_shownet.integer == 2)
983 Con_Printf ("------------------\n");
985 cl.onground = false; // unless the server says otherwise
991 entitiesupdated = false;
992 CL_EntityUpdateSetup();
997 Host_Error ("CL_ParseServerMessage: Bad server message");
999 cmd = MSG_ReadByte ();
1003 SHOWNET("END OF MESSAGE");
1004 break; // end of message
1007 cmdindex = cmdcount & 31;
1009 cmdlog[cmdindex] = cmd;
1011 // if the high bit of the command byte is set, it is a fast update
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)
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;
1023 CL_ParseUpdate (cmd&127);
1027 SHOWNET(svc_strings[cmd]);
1028 cmdlogname[cmdindex] = svc_strings[cmd];
1029 if (!cmdlogname[cmdindex])
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)
1033 cmdlogname[cmdindex] = temp;
1041 char description[32*64], temp[64];
1043 strcpy(description, "packet dump: ");
1047 count = cmdcount - i;
1051 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
1052 strcat(description, temp);
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");
1064 // Con_Printf ("svc_nop\n");
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 ();
1074 case svc_clientdata:
1075 i = MSG_ReadShort ();
1076 CL_ParseClientdata (i);
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;
1085 Nehahrademcompatibility = true;
1086 if (cls.demoplayback && demo_nehahra.integer)
1087 Nehahrademcompatibility = true;
1089 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2)
1093 case svc_disconnect:
1094 Host_EndGame ("Server disconnected\n");
1097 Con_Printf ("%s", MSG_ReadString ());
1100 case svc_centerprint:
1101 SCR_CenterPrint (MSG_ReadString ());
1105 Cbuf_AddText (MSG_ReadString ());
1112 case svc_serverinfo:
1113 CL_ParseServerInfo ();
1114 // vid.recalc_refdef = true; // leave intermission full screen
1118 for (i=0 ; i<3 ; i++)
1119 cl.viewangles[i] = MSG_ReadAngle ();
1123 cl.viewentity = MSG_ReadShort ();
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);
1136 CL_ParseStartSoundPacket(false);
1140 CL_ParseStartSoundPacket(true);
1144 i = MSG_ReadShort();
1145 S_StopSound(i>>3, i&7);
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 ());
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 ();
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 ();
1170 CL_ParseParticleEffect ();
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);
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);
1191 case svc_spawnstatic:
1192 CL_ParseStatic (false);
1194 case svc_spawnstatic2:
1195 CL_ParseStatic (true);
1197 case svc_temp_entity:
1202 cl.paused = MSG_ReadByte ();
1210 i = MSG_ReadByte ();
1211 if (i <= cls.signon)
1212 Host_Error ("Received signon %i when at %i", i, cls.signon);
1217 case svc_killedmonster:
1218 cl.stats[STAT_MONSTERS]++;
1221 case svc_foundsecret:
1222 cl.stats[STAT_SECRETS]++;
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 ();
1232 case svc_spawnstaticsound:
1233 CL_ParseStaticSound (false);
1236 case svc_spawnstaticsound2:
1237 CL_ParseStaticSound (true);
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);
1246 CDAudio_Play ((byte)cl.cdtrack, true);
1249 case svc_intermission:
1250 cl.intermission = 1;
1251 cl.completed_time = cl.time;
1252 // vid.recalc_refdef = true; // go to full screen
1256 cl.intermission = 2;
1257 cl.completed_time = cl.time;
1258 // vid.recalc_refdef = true; // go to full screen
1259 SCR_CenterPrint (MSG_ReadString ());
1263 cl.intermission = 3;
1264 cl.completed_time = cl.time;
1265 // vid.recalc_refdef = true; // go to full screen
1266 SCR_CenterPrint (MSG_ReadString ());
1269 case svc_sellscreen:
1270 Cmd_ExecuteString ("help", src_command);
1273 SHOWLMP_decodehide();
1276 SHOWLMP_decodeshow();
1279 R_SetSkyBox(MSG_ReadString());
1284 length = (int) ((unsigned short) MSG_ReadShort());
1286 if (cgamenetbuffersize < length)
1288 cgamenetbuffersize = length;
1290 Mem_Free(cgamenetbuffer);
1291 cgamenetbuffer = Mem_Alloc(cgamenetbuffersize);
1294 for (i = 0;i < length;i++)
1295 cgamenetbuffer[i] = MSG_ReadByte();
1297 CL_CGVM_ParseNetwork(cgamenetbuffer, length);
1301 if (cls.signon == SIGNONS - 1)
1302 { // first update is the final signon stage
1303 cls.signon = SIGNONS;
1306 CL_ReadEntityFrame();
1311 if (entitiesupdated)
1312 CL_EntityUpdateEnd();