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 for (i=1 ; i<nummodels ; i++)
460 // LordHavoc: i == 1 means the first model is the world model
461 cl.model_precache[i] = Mod_ForName (model_precache[i], false, false, i == 1);
463 if (cl.model_precache[i] == NULL)
465 Host_Error("Model %s not found\n", model_precache[i]);
468 CL_KeepaliveMessage ();
471 S_BeginPrecaching ();
472 for (i=1 ; i<numsounds ; i++)
474 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
475 CL_KeepaliveMessage ();
480 cl_entities[0].render.model = cl.worldmodel = cl.model_precache[1];
481 cl_entities[0].render.scale = 1;
482 cl_entities[0].render.alpha = 1;
488 Mem_CheckSentinelsGlobal();
490 noclip_anglehack = false; // noclip is turned off at start
493 void CL_ValidateState(entity_state_t *s)
500 if (s->modelindex >= MAX_MODELS)
501 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
503 // colormap is client index + 1
504 if (s->colormap > cl.maxclients)
505 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
507 model = cl.model_precache[s->modelindex];
508 Mod_CheckLoaded(model);
509 if (model && s->frame >= model->numframes)
511 Con_Printf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
514 if (model && s->skin > 0 && s->skin >= model->numskins)
516 Con_Printf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
525 Parse an entity update message from the server
526 If an entities model or origin changes from frame to frame, it must be
527 relinked. Other attributes can change without relinking.
530 qbyte entkill[MAX_EDICTS];
531 int bitprofile[32], bitprofilecount = 0;
532 void CL_ParseUpdate (int bits)
534 int i, num, deltadie;
538 if (bits & U_MOREBITS)
539 bits |= (MSG_ReadByte()<<8);
540 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
542 bits |= MSG_ReadByte() << 16;
543 if (bits & U_EXTEND2)
544 bits |= MSG_ReadByte() << 24;
547 if (bits & U_LONGENTITY)
548 num = (unsigned) MSG_ReadShort ();
550 num = (unsigned) MSG_ReadByte ();
552 if (num >= MAX_EDICTS)
553 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
555 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
557 // mark as visible (no kill)
560 ent = CL_EntityNum (num);
562 for (i = 0;i < 32;i++)
570 new = ent->state_current;
572 deltadie = true; // was not present in previous frame, leave hidden until next full update
575 new = ent->state_baseline;
577 new.time = cl.mtime[0];
581 if (bits & U_MODEL) new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte();
582 if (bits & U_FRAME) new.frame = (new.frame & 0xFF00) | MSG_ReadByte();
583 if (bits & U_COLORMAP) new.colormap = MSG_ReadByte();
584 if (bits & U_SKIN) new.skin = MSG_ReadByte();
585 if (bits & U_EFFECTS) new.effects = (new.effects & 0xFF00) | MSG_ReadByte();
586 if (bits & U_ORIGIN1) new.origin[0] = MSG_ReadCoord();
587 if (bits & U_ANGLE1) new.angles[0] = MSG_ReadAngle();
588 if (bits & U_ORIGIN2) new.origin[1] = MSG_ReadCoord();
589 if (bits & U_ANGLE2) new.angles[1] = MSG_ReadAngle();
590 if (bits & U_ORIGIN3) new.origin[2] = MSG_ReadCoord();
591 if (bits & U_ANGLE3) new.angles[2] = MSG_ReadAngle();
592 if (bits & U_STEP) new.flags |= RENDER_STEP;
593 if (bits & U_ALPHA) new.alpha = MSG_ReadByte();
594 if (bits & U_SCALE) new.scale = MSG_ReadByte();
595 if (bits & U_EFFECTS2) new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8);
596 if (bits & U_GLOWSIZE) new.glowsize = MSG_ReadByte();
597 if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte();
599 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);}
601 // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
602 if (bits & U_COLORMOD) MSG_ReadByte();
604 if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL;
605 if (bits & U_FRAME2) new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8);
606 if (bits & U_MODEL2) new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
607 if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL;
608 if (bits & U_EXTERIORMODEL) new.flags |= RENDER_EXTERIORMODEL;
610 // LordHavoc: to allow playback of the Nehahra movie
611 if (Nehahrademcompatibility && (bits & U_EXTEND1))
613 // LordHavoc: evil format
614 int i = MSG_ReadFloat();
615 int j = MSG_ReadFloat() * 255.0f;
619 new.effects |= EF_FULLBRIGHT;
623 else if (j == 0 || j >= 255)
635 CL_ValidateState(&new);
637 if (new.flags & RENDER_STEP) // FIXME: rename this flag?
639 // make time identical for memcmp
640 new.time = ent->state_current.time;
641 if (memcmp(&new, &ent->state_current, sizeof(entity_state_t)))
643 // set it back to what it should be
644 new.time = cl.mtime[0] + 0.1;
646 ent->state_previous = ent->state_current;
647 ent->state_current = new;
648 // assume 10fps animation
649 //ent->state_previous.time = cl.mtime[0] - 0.1;
654 ent->state_previous = ent->state_current;
655 ent->state_current = new;
659 void CL_ReadEntityFrame(void)
663 entity_frame_t entityframe;
665 EntityFrame_Read(&cl.entitydatabase);
666 EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
667 for (i = 0;i < entityframe.numentities;i++)
669 s = &entityframe.entitydata[i];
670 entkill[s->number] = 0;
671 ent = &cl_entities[s->number];
672 memcpy(&ent->state_previous, &ent->state_current, sizeof(*s));
673 memcpy(&ent->state_current, s, sizeof(*s));
674 ent->state_current.time = cl.mtime[0];
676 VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
677 VectorCopy(entityframe.eye, cl.viewentoriginnew);
680 char *bitprofilenames[32] =
704 "obsolete U_COLORMOD",
716 void CL_BitProfile_f(void)
719 Con_Printf("bitprofile: %i updates\n");
721 for (i = 0;i < 32;i++)
722 // if (bitprofile[i])
723 Con_Printf("%s: %i %3.2f%%\n", bitprofilenames[i], bitprofile[i], bitprofile[i] * 100.0 / bitprofilecount);
725 for (i = 0;i < 32;i++)
730 void CL_EntityUpdateSetup(void)
732 memset(entkill, 1, MAX_EDICTS);
735 void CL_EntityUpdateEnd(void)
738 for (i = 1;i < MAX_EDICTS;i++)
740 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
748 void CL_ParseBaseline (entity_t *ent, int large)
752 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
753 ent->state_baseline.active = true;
756 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
757 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
761 ent->state_baseline.modelindex = MSG_ReadByte ();
762 ent->state_baseline.frame = MSG_ReadByte ();
764 ent->state_baseline.colormap = MSG_ReadByte();
765 ent->state_baseline.skin = MSG_ReadByte();
766 for (i = 0;i < 3;i++)
768 ent->state_baseline.origin[i] = MSG_ReadCoord ();
769 ent->state_baseline.angles[i] = MSG_ReadAngle ();
771 ent->state_baseline.alpha = 255;
772 ent->state_baseline.scale = 16;
773 ent->state_baseline.glowsize = 0;
774 ent->state_baseline.glowcolor = 254;
775 ent->state_previous = ent->state_current = ent->state_baseline;
777 CL_ValidateState(&ent->state_baseline);
785 Server information pertaining to this client only
788 void CL_ParseClientdata (int bits)
793 if (bits & SU_EXTEND1)
794 bits |= (MSG_ReadByte() << 16);
795 if (bits & SU_EXTEND2)
796 bits |= (MSG_ReadByte() << 24);
798 if (bits & SU_VIEWHEIGHT)
799 cl.viewheight = MSG_ReadChar ();
801 cl.viewheight = DEFAULT_VIEWHEIGHT;
803 if (bits & SU_IDEALPITCH)
804 cl.idealpitch = MSG_ReadChar ();
808 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
809 for (i=0 ; i<3 ; i++)
811 if (bits & (SU_PUNCH1<<i) )
814 cl.punchangle[i] = MSG_ReadPreciseAngle();
816 cl.punchangle[i] = MSG_ReadChar();
819 cl.punchangle[i] = 0;
820 if (bits & (SU_PUNCHVEC1<<i))
821 cl.punchvector[i] = MSG_ReadCoord();
823 cl.punchvector[i] = 0;
824 if (bits & (SU_VELOCITY1<<i) )
825 cl.mvelocity[0][i] = MSG_ReadChar()*16;
827 cl.mvelocity[0][i] = 0;
833 for (j=0 ; j<32 ; j++)
834 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
835 cl.item_gettime[j] = cl.time;
839 cl.onground = (bits & SU_ONGROUND) != 0;
840 cl.inwater = (bits & SU_INWATER) != 0;
842 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
843 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
844 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
845 cl.stats[STAT_HEALTH] = MSG_ReadShort();
846 cl.stats[STAT_AMMO] = MSG_ReadByte();
848 cl.stats[STAT_SHELLS] = MSG_ReadByte();
849 cl.stats[STAT_NAILS] = MSG_ReadByte();
850 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
851 cl.stats[STAT_CELLS] = MSG_ReadByte();
855 if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
856 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
858 cl.stats[STAT_ACTIVEWEAPON] = i;
860 cl.viewzoomold = cl.viewzoomnew; // for interpolation
861 if (bits & SU_VIEWZOOM)
866 cl.viewzoomnew = (float) i * (1.0f / 255.0f);
874 =====================
876 =====================
878 void CL_ParseStatic (int large)
882 if (cl.num_statics >= MAX_STATIC_ENTITIES)
883 Host_Error ("Too many static entities");
884 ent = &cl_static_entities[cl.num_statics++];
885 CL_ParseBaseline (ent, large);
887 // copy it to the current state
888 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
889 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
890 ent->render.framelerp = 0;
891 // make torchs play out of sync
892 ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1);
893 ent->render.colormap = -1; // no special coloring
894 ent->render.skinnum = ent->state_baseline.skin;
895 ent->render.effects = ent->state_baseline.effects;
896 ent->render.alpha = 1;
897 ent->render.scale = 1;
898 ent->render.alpha = 1;
900 VectorCopy (ent->state_baseline.origin, ent->render.origin);
901 VectorCopy (ent->state_baseline.angles, ent->render.angles);
909 void CL_ParseStaticSound (int large)
912 int sound_num, vol, atten;
916 sound_num = (unsigned short) MSG_ReadShort ();
918 sound_num = MSG_ReadByte ();
919 vol = MSG_ReadByte ();
920 atten = MSG_ReadByte ();
922 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
925 void CL_ParseEffect (void)
928 int modelindex, startframe, framecount, framerate;
931 modelindex = MSG_ReadByte ();
932 startframe = MSG_ReadByte ();
933 framecount = MSG_ReadByte ();
934 framerate = MSG_ReadByte ();
936 CL_Effect(org, modelindex, startframe, framecount, framerate);
939 void CL_ParseEffect2 (void)
942 int modelindex, startframe, framecount, framerate;
945 modelindex = MSG_ReadShort ();
946 startframe = MSG_ReadShort ();
947 framecount = MSG_ReadByte ();
948 framerate = MSG_ReadByte ();
950 CL_Effect(org, modelindex, startframe, framecount, framerate);
954 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
956 static qbyte cgamenetbuffer[65536];
959 =====================
960 CL_ParseServerMessage
961 =====================
963 void CL_ParseServerMessage (void)
966 int i, entitiesupdated;
968 char *cmdlogname[32], *temp;
969 int cmdindex, cmdcount = 0;
972 // if recording demos, copy the message out
974 if (cl_shownet.integer == 1)
975 Con_Printf ("%i ",net_message.cursize);
976 else if (cl_shownet.integer == 2)
977 Con_Printf ("------------------\n");
979 cl.onground = false; // unless the server says otherwise
985 entitiesupdated = false;
986 CL_EntityUpdateSetup();
991 Host_Error ("CL_ParseServerMessage: Bad server message");
993 cmd = MSG_ReadByte ();
997 SHOWNET("END OF MESSAGE");
998 break; // end of message
1001 cmdindex = cmdcount & 31;
1003 cmdlog[cmdindex] = cmd;
1005 // if the high bit of the command byte is set, it is a fast update
1008 // 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)
1010 cmdlogname[cmdindex] = temp;
1011 SHOWNET("fast update");
1012 if (cls.signon == SIGNONS - 1)
1013 { // first update is the final signon stage
1014 cls.signon = SIGNONS;
1017 CL_ParseUpdate (cmd&127);
1021 SHOWNET(svc_strings[cmd]);
1022 cmdlogname[cmdindex] = svc_strings[cmd];
1023 if (!cmdlogname[cmdindex])
1025 // 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)
1027 cmdlogname[cmdindex] = temp;
1035 char description[32*64], temp[64];
1037 strcpy(description, "packet dump: ");
1041 count = cmdcount - i;
1045 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
1046 strcat(description, temp);
1051 description[strlen(description)-1] = '\n'; // replace the last space with a newline
1052 Con_Printf("%s", description);
1053 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
1058 // Con_Printf ("svc_nop\n");
1062 // handle old protocols which do not have entity update ranges
1063 entitiesupdated = true;
1064 cl.mtime[1] = cl.mtime[0];
1065 cl.mtime[0] = MSG_ReadFloat ();
1068 case svc_clientdata:
1069 i = MSG_ReadShort ();
1070 CL_ParseClientdata (i);
1074 i = MSG_ReadLong ();
1075 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != 250)
1076 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, PROTOCOL_VERSION);
1077 Nehahrademcompatibility = false;
1079 Nehahrademcompatibility = true;
1080 if (cls.demoplayback && demo_nehahra.integer)
1081 Nehahrademcompatibility = true;
1083 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2)
1087 case svc_disconnect:
1088 Host_EndGame ("Server disconnected\n");
1091 Con_Printf ("%s", MSG_ReadString ());
1094 case svc_centerprint:
1095 SCR_CenterPrint (MSG_ReadString ());
1099 Cbuf_AddText (MSG_ReadString ());
1106 case svc_serverinfo:
1107 CL_ParseServerInfo ();
1108 // vid.recalc_refdef = true; // leave intermission full screen
1112 for (i=0 ; i<3 ; i++)
1113 cl.viewangles[i] = MSG_ReadAngle ();
1117 cl.viewentity = MSG_ReadShort ();
1120 case svc_lightstyle:
1121 i = MSG_ReadByte ();
1122 if (i >= MAX_LIGHTSTYLES)
1123 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1124 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1125 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1126 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1130 CL_ParseStartSoundPacket(false);
1134 CL_ParseStartSoundPacket(true);
1138 i = MSG_ReadShort();
1139 S_StopSound(i>>3, i&7);
1142 case svc_updatename:
1143 i = MSG_ReadByte ();
1144 if (i >= cl.maxclients)
1145 Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
1146 strcpy (cl.scores[i].name, MSG_ReadString ());
1149 case svc_updatefrags:
1150 i = MSG_ReadByte ();
1151 if (i >= cl.maxclients)
1152 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
1153 cl.scores[i].frags = MSG_ReadShort ();
1156 case svc_updatecolors:
1157 i = MSG_ReadByte ();
1158 if (i >= cl.maxclients)
1159 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
1160 cl.scores[i].colors = MSG_ReadByte ();
1164 CL_ParseParticleEffect ();
1175 case svc_spawnbaseline:
1176 i = MSG_ReadShort ();
1177 // must use CL_EntityNum() to force cl.num_entities up
1178 CL_ParseBaseline (CL_EntityNum(i), false);
1180 case svc_spawnbaseline2:
1181 i = MSG_ReadShort ();
1182 // must use CL_EntityNum() to force cl.num_entities up
1183 CL_ParseBaseline (CL_EntityNum(i), true);
1185 case svc_spawnstatic:
1186 CL_ParseStatic (false);
1188 case svc_spawnstatic2:
1189 CL_ParseStatic (true);
1191 case svc_temp_entity:
1196 cl.paused = MSG_ReadByte ();
1204 i = MSG_ReadByte ();
1205 if (i <= cls.signon)
1206 Host_Error ("Received signon %i when at %i", i, cls.signon);
1211 case svc_killedmonster:
1212 cl.stats[STAT_MONSTERS]++;
1215 case svc_foundsecret:
1216 cl.stats[STAT_SECRETS]++;
1219 case svc_updatestat:
1220 i = MSG_ReadByte ();
1221 if (i < 0 || i >= MAX_CL_STATS)
1222 Host_Error ("svc_updatestat: %i is invalid", i);
1223 cl.stats[i] = MSG_ReadLong ();
1226 case svc_spawnstaticsound:
1227 CL_ParseStaticSound (false);
1230 case svc_spawnstaticsound2:
1231 CL_ParseStaticSound (true);
1235 cl.cdtrack = MSG_ReadByte ();
1236 cl.looptrack = MSG_ReadByte ();
1237 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1238 CDAudio_Play ((qbyte)cls.forcetrack, true);
1240 CDAudio_Play ((qbyte)cl.cdtrack, true);
1243 case svc_intermission:
1244 cl.intermission = 1;
1245 cl.completed_time = cl.time;
1246 // vid.recalc_refdef = true; // go to full screen
1250 cl.intermission = 2;
1251 cl.completed_time = cl.time;
1252 // vid.recalc_refdef = true; // go to full screen
1253 SCR_CenterPrint (MSG_ReadString ());
1257 cl.intermission = 3;
1258 cl.completed_time = cl.time;
1259 // vid.recalc_refdef = true; // go to full screen
1260 SCR_CenterPrint (MSG_ReadString ());
1263 case svc_sellscreen:
1264 Cmd_ExecuteString ("help", src_command);
1267 SHOWLMP_decodehide();
1270 SHOWLMP_decodeshow();
1273 R_SetSkyBox(MSG_ReadString());
1278 length = (int) ((unsigned short) MSG_ReadShort());
1280 if (cgamenetbuffersize < length)
1282 cgamenetbuffersize = length;
1284 Mem_Free(cgamenetbuffer);
1285 cgamenetbuffer = Mem_Alloc(cgamenetbuffersize);
1288 for (i = 0;i < length;i++)
1289 cgamenetbuffer[i] = MSG_ReadByte();
1291 CL_CGVM_ParseNetwork(cgamenetbuffer, length);
1295 if (cls.signon == SIGNONS - 1)
1296 { // first update is the final signon stage
1297 cls.signon = SIGNONS;
1300 CL_ReadEntityFrame();
1305 if (entitiesupdated)
1306 CL_EntityUpdateEnd();