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)
119 if (num >= MAX_EDICTS)
120 Host_Error ("CL_EntityNum: %i is an invalid number",num);
122 return &cl_entities[num];
128 CL_ParseStartSoundPacket
131 void CL_ParseStartSoundPacket(int largesoundindex)
141 field_mask = MSG_ReadByte();
143 if (field_mask & SND_VOLUME)
144 volume = MSG_ReadByte ();
146 volume = DEFAULT_SOUND_PACKET_VOLUME;
148 if (field_mask & SND_ATTENUATION)
149 attenuation = MSG_ReadByte () / 64.0;
151 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
153 channel = MSG_ReadShort ();
155 sound_num = (unsigned short) MSG_ReadShort ();
157 sound_num = MSG_ReadByte ();
159 if (sound_num >= MAX_SOUNDS)
160 Host_Error("CL_ParseStartSoundPacket: sound_num (%i) >= MAX_SOUNDS (%i)\n", sound_num, MAX_SOUNDS);
165 if (ent > MAX_EDICTS)
166 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
168 for (i=0 ; i<3 ; i++)
169 pos[i] = MSG_ReadCoord ();
171 S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
178 When the client is taking a long time to load stuff, send keepalive messages
179 so the server doesn't disconnect.
182 void CL_KeepaliveMessage (void)
185 static float lastmsg;
192 return; // no need if server is local
193 if (cls.demoplayback)
196 // read messages from server, should just be nops
198 memcpy (olddata, net_message.data, net_message.cursize);
202 ret = CL_GetMessage ();
206 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
208 break; // nothing waiting
210 Host_Error ("CL_KeepaliveMessage: received a message");
215 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
221 memcpy (net_message.data, olddata, net_message.cursize);
224 time = Sys_DoubleTime ();
225 if (time - lastmsg < 5)
230 Con_Printf ("--> client to server keepalive\n");
232 MSG_WriteByte (&cls.message, clc_nop);
233 NET_SendMessage (cls.netcon, &cls.message);
234 SZ_Clear (&cls.message);
237 void CL_ParseEntityLump(char *entdata)
240 char key[128], value[4096];
241 FOG_clear(); // LordHavoc: no fog until set
242 R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set
246 data = COM_Parse(data);
249 if (com_token[0] != '{')
253 data = COM_Parse(data);
256 if (com_token[0] == '}')
257 break; // end of worldspawn
258 if (com_token[0] == '_')
259 strcpy(key, com_token + 1);
261 strcpy(key, com_token);
262 while (key[strlen(key)-1] == ' ') // remove trailing spaces
263 key[strlen(key)-1] = 0;
264 data = COM_Parse(data);
267 strcpy(value, com_token);
268 if (!strcmp("sky", key))
270 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
272 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
274 else if (!strcmp("fog", key))
275 sscanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
276 else if (!strcmp("fog_density", key))
277 fog_density = atof(value);
278 else if (!strcmp("fog_red", key))
279 fog_red = atof(value);
280 else if (!strcmp("fog_green", key))
281 fog_green = atof(value);
282 else if (!strcmp("fog_blue", key))
283 fog_blue = atof(value);
288 =====================
291 An svc_signonnum has been received, perform a client side setup
292 =====================
294 static void CL_SignonReply (void)
298 Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
303 MSG_WriteByte (&cls.message, clc_stringcmd);
304 MSG_WriteString (&cls.message, "prespawn");
308 MSG_WriteByte (&cls.message, clc_stringcmd);
309 MSG_WriteString (&cls.message, va("name \"%s\"\n", cl_name.string));
311 MSG_WriteByte (&cls.message, clc_stringcmd);
312 MSG_WriteString (&cls.message, va("color %i %i\n", cl_color.integer >> 4, cl_color.integer & 15));
314 if (cl_pmodel.integer)
316 MSG_WriteByte (&cls.message, clc_stringcmd);
317 MSG_WriteString (&cls.message, va("pmodel %i\n", cl_pmodel.integer));
320 MSG_WriteByte (&cls.message, clc_stringcmd);
321 //sprintf (str, "spawn %s", cls.spawnparms);
322 //MSG_WriteString (&cls.message, str);
323 MSG_WriteString (&cls.message, "spawn");
327 MSG_WriteByte (&cls.message, clc_stringcmd);
328 MSG_WriteString (&cls.message, "begin");
342 qbyte entlife[MAX_EDICTS];
343 void CL_ParseServerInfo (void)
347 int nummodels, numsounds;
348 char model_precache[MAX_MODELS][MAX_QPATH];
349 char sound_precache[MAX_SOUNDS][MAX_QPATH];
352 Con_DPrintf ("Serverinfo packet received.\n");
354 // wipe the client_state_t struct
358 // parse protocol version number
360 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
362 Con_Printf ("Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
365 Nehahrademcompatibility = false;
367 Nehahrademcompatibility = true;
368 if (cls.demoplayback && demo_nehahra.integer)
369 Nehahrademcompatibility = true;
371 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
375 cl.maxclients = MSG_ReadByte ();
376 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
378 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
381 cl.scores = Mem_Alloc(cl_scores_mempool, cl.maxclients*sizeof(*cl.scores));
384 cl.gametype = MSG_ReadByte ();
386 // parse signon message
387 str = MSG_ReadString ();
388 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
390 // seperate the printfs so the server message can have a color
391 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
393 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");
394 Con_Printf ("%c%s\n", 2, str);
398 // first we go through and touch all of the precache data that still
399 // happens to be in the cache, so precaching something else doesn't
400 // needlessly purge it
403 Mem_CheckSentinelsGlobal();
408 memset (cl.model_precache, 0, sizeof(cl.model_precache));
409 for (nummodels=1 ; ; nummodels++)
411 str = MSG_ReadString ();
414 if (nummodels==MAX_MODELS)
416 Host_Error ("Server sent too many model precaches\n");
419 if (strlen(str) >= MAX_QPATH)
420 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
421 strcpy (model_precache[nummodels], str);
422 Mod_TouchModel (str);
426 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
427 for (numsounds=1 ; ; numsounds++)
429 str = MSG_ReadString ();
432 if (numsounds==MAX_SOUNDS)
434 Host_Error ("Server sent too many sound precaches\n");
437 if (strlen(str) >= MAX_QPATH)
438 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
439 strcpy (sound_precache[numsounds], str);
446 // now we try to load everything else until a cache allocation fails
449 for (i=1 ; i<nummodels ; i++)
451 // LordHavoc: i == 1 means the first model is the world model
452 cl.model_precache[i] = Mod_ForName (model_precache[i], false, false, i == 1);
454 if (cl.model_precache[i] == NULL)
456 Host_Error("Model %s not found\n", model_precache[i]);
459 CL_KeepaliveMessage ();
462 S_BeginPrecaching ();
463 for (i=1 ; i<numsounds ; i++)
465 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i], true);
466 CL_KeepaliveMessage ();
471 ent = &cl_entities[0];
472 // entire entity array was cleared, so just fill in a few fields
473 ent->render.model = cl.worldmodel = cl.model_precache[1];
474 ent->render.scale = 1;
475 ent->render.alpha = 1;
476 VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins);
477 VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs);
478 // clear entlife array
479 memset(entlife, 0, MAX_EDICTS);
487 Mem_CheckSentinelsGlobal();
489 noclip_anglehack = false; // noclip is turned off at start
492 void CL_ValidateState(entity_state_t *s)
499 if (s->modelindex >= MAX_MODELS)
500 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
502 // colormap is client index + 1
503 if (s->colormap > cl.maxclients)
504 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
506 model = cl.model_precache[s->modelindex];
507 Mod_CheckLoaded(model);
508 if (model && s->frame >= model->numframes)
510 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
513 if (model && s->skin > 0 && s->skin >= model->numskins)
515 Con_DPrintf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
524 Parse an entity update message from the server
525 If an entities model or origin changes from frame to frame, it must be
526 relinked. Other attributes can change without relinking.
529 int bitprofile[32], bitprofilecount = 0;
530 void CL_ParseUpdate (int bits)
536 if (bits & U_MOREBITS)
537 bits |= (MSG_ReadByte()<<8);
538 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
540 bits |= MSG_ReadByte() << 16;
541 if (bits & U_EXTEND2)
542 bits |= MSG_ReadByte() << 24;
545 if (bits & U_LONGENTITY)
546 num = (unsigned) MSG_ReadShort ();
548 num = (unsigned) MSG_ReadByte ();
550 if (num >= MAX_EDICTS)
551 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
553 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
555 // mark as visible (no kill this frame)
558 ent = CL_EntityNum (num);
560 for (i = 0;i < 32;i++)
565 // note: this inherits the 'active' state of the baseline chosen
566 // (state_baseline is always active, state_current may not be active if
567 // the entity was missing in the last frame)
569 new = ent->state_current;
571 new = ent->state_baseline;
573 new.time = cl.mtime[0];
576 if (bits & U_MODEL) new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte();
577 if (bits & U_FRAME) new.frame = (new.frame & 0xFF00) | MSG_ReadByte();
578 if (bits & U_COLORMAP) new.colormap = MSG_ReadByte();
579 if (bits & U_SKIN) new.skin = MSG_ReadByte();
580 if (bits & U_EFFECTS) new.effects = (new.effects & 0xFF00) | MSG_ReadByte();
581 if (bits & U_ORIGIN1) new.origin[0] = MSG_ReadCoord();
582 if (bits & U_ANGLE1) new.angles[0] = MSG_ReadAngle();
583 if (bits & U_ORIGIN2) new.origin[1] = MSG_ReadCoord();
584 if (bits & U_ANGLE2) new.angles[1] = MSG_ReadAngle();
585 if (bits & U_ORIGIN3) new.origin[2] = MSG_ReadCoord();
586 if (bits & U_ANGLE3) new.angles[2] = MSG_ReadAngle();
587 if (bits & U_STEP) new.flags |= RENDER_STEP;
588 if (bits & U_ALPHA) new.alpha = MSG_ReadByte();
589 if (bits & U_SCALE) new.scale = MSG_ReadByte();
590 if (bits & U_EFFECTS2) new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8);
591 if (bits & U_GLOWSIZE) new.glowsize = MSG_ReadByte();
592 if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte();
593 // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
594 if (bits & U_COLORMOD) MSG_ReadByte();
595 if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL;
596 if (bits & U_FRAME2) new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8);
597 if (bits & U_MODEL2) new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
598 if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL;
599 if (bits & U_EXTERIORMODEL) new.flags |= RENDER_EXTERIORMODEL;
601 // LordHavoc: to allow playback of the Nehahra movie
602 if (Nehahrademcompatibility && (bits & U_EXTEND1))
604 // LordHavoc: evil format
605 int i = MSG_ReadFloat();
606 int j = MSG_ReadFloat() * 255.0f;
611 new.effects |= EF_FULLBRIGHT;
615 else if (j == 0 || j >= 255)
622 CL_ValidateState(&new);
624 if (new.flags & RENDER_STEP) // FIXME: rename this flag?
626 // make time identical for memcmp
627 new.time = ent->state_current.time;
628 if (memcmp(&new, &ent->state_current, sizeof(entity_state_t)))
630 // set it back to what it should be
631 new.time = cl.mtime[0] + 0.1;
633 ent->state_previous = ent->state_current;
634 ent->state_current = new;
635 // assume 10fps animation
636 //ent->state_previous.time = cl.mtime[0] - 0.1;
641 ent->state_previous = ent->state_current;
642 ent->state_current = new;
646 void CL_ReadEntityFrame(void)
649 entity_frame_t entityframe;
651 EntityFrame_Read(&cl.entitydatabase);
652 EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
653 for (i = 0;i < entityframe.numentities;i++)
655 // the entity lives again...
656 entlife[entityframe.entitydata[i].number] = 2;
658 ent = &cl_entities[entityframe.entitydata[i].number];
659 ent->state_previous = ent->state_current;
660 ent->state_current = entityframe.entitydata[i];
661 ent->state_current.time = cl.mtime[0];
663 VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
664 VectorCopy(entityframe.eye, cl.viewentoriginnew);
667 char *bitprofilenames[32] =
691 "obsolete U_COLORMOD",
703 void CL_BitProfile_f(void)
706 Con_Printf("bitprofile: %i updates\n");
708 for (i = 0;i < 32;i++)
709 Con_Printf("%s: %i %3.2f%%\n", bitprofilenames[i], bitprofile[i], bitprofile[i] * 100.0 / bitprofilecount);
711 for (i = 0;i < 32;i++)
716 void CL_EntityUpdateSetup(void)
720 void CL_EntityUpdateEnd(void)
723 // disable entities that disappeared this frame
724 for (i = 1;i < MAX_EDICTS;i++)
726 // clear only the entities that were active last frame but not this
727 // frame, don't waste time clearing all entities (which would cause
733 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
743 void CL_ParseBaseline (entity_t *ent, int large)
747 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
748 ent->state_baseline.active = true;
751 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
752 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
756 ent->state_baseline.modelindex = MSG_ReadByte ();
757 ent->state_baseline.frame = MSG_ReadByte ();
759 ent->state_baseline.colormap = MSG_ReadByte();
760 ent->state_baseline.skin = MSG_ReadByte();
761 for (i = 0;i < 3;i++)
763 ent->state_baseline.origin[i] = MSG_ReadCoord ();
764 ent->state_baseline.angles[i] = MSG_ReadAngle ();
766 ent->state_baseline.alpha = 255;
767 ent->state_baseline.scale = 16;
768 ent->state_baseline.glowsize = 0;
769 ent->state_baseline.glowcolor = 254;
770 ent->state_previous = ent->state_current = ent->state_baseline;
772 CL_ValidateState(&ent->state_baseline);
780 Server information pertaining to this client only
783 void CL_ParseClientdata (int bits)
788 if (bits & SU_EXTEND1)
789 bits |= (MSG_ReadByte() << 16);
790 if (bits & SU_EXTEND2)
791 bits |= (MSG_ReadByte() << 24);
793 if (bits & SU_VIEWHEIGHT)
794 cl.viewheight = MSG_ReadChar ();
796 cl.viewheight = DEFAULT_VIEWHEIGHT;
798 if (bits & SU_IDEALPITCH)
799 cl.idealpitch = MSG_ReadChar ();
803 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
804 for (i=0 ; i<3 ; i++)
806 if (bits & (SU_PUNCH1<<i) )
809 cl.punchangle[i] = MSG_ReadPreciseAngle();
811 cl.punchangle[i] = MSG_ReadChar();
814 cl.punchangle[i] = 0;
815 if (bits & (SU_PUNCHVEC1<<i))
816 cl.punchvector[i] = MSG_ReadCoord();
818 cl.punchvector[i] = 0;
819 if (bits & (SU_VELOCITY1<<i) )
820 cl.mvelocity[0][i] = MSG_ReadChar()*16;
822 cl.mvelocity[0][i] = 0;
828 for (j=0 ; j<32 ; j++)
829 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
830 cl.item_gettime[j] = cl.time;
834 cl.onground = (bits & SU_ONGROUND) != 0;
835 cl.inwater = (bits & SU_INWATER) != 0;
837 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
838 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
839 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
840 cl.stats[STAT_HEALTH] = MSG_ReadShort();
841 cl.stats[STAT_AMMO] = MSG_ReadByte();
843 cl.stats[STAT_SHELLS] = MSG_ReadByte();
844 cl.stats[STAT_NAILS] = MSG_ReadByte();
845 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
846 cl.stats[STAT_CELLS] = MSG_ReadByte();
850 if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
851 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
853 cl.stats[STAT_ACTIVEWEAPON] = i;
855 cl.viewzoomold = cl.viewzoomnew; // for interpolation
856 if (bits & SU_VIEWZOOM)
861 cl.viewzoomnew = (float) i * (1.0f / 255.0f);
869 =====================
871 =====================
873 void CL_ParseStatic (int large)
877 if (cl_num_static_entities >= cl_max_static_entities)
878 Host_Error ("Too many static entities");
879 ent = &cl_static_entities[cl_num_static_entities++];
880 CL_ParseBaseline (ent, large);
882 // copy it to the current state
883 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
884 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
885 ent->render.framelerp = 0;
886 // make torchs play out of sync
887 ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1);
888 ent->render.colormap = -1; // no special coloring
889 ent->render.skinnum = ent->state_baseline.skin;
890 ent->render.effects = ent->state_baseline.effects;
891 ent->render.alpha = 1;
892 ent->render.scale = 1;
893 ent->render.alpha = 1;
895 VectorCopy (ent->state_baseline.origin, ent->render.origin);
896 VectorCopy (ent->state_baseline.angles, ent->render.angles);
898 if (ent->render.angles[0] || ent->render.angles[2])
901 VectorAdd(ent->render.origin, ent->render.model->rotatedmins, ent->render.mins);
902 VectorAdd(ent->render.origin, ent->render.model->rotatedmaxs, ent->render.maxs);
904 else if (ent->render.angles[1])
907 VectorAdd(ent->render.origin, ent->render.model->yawmins, ent->render.mins);
908 VectorAdd(ent->render.origin, ent->render.model->yawmaxs, ent->render.maxs);
912 VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins);
913 VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs);
916 // This is definitely cheating...
917 if (ent->render.model == NULL)
918 cl_num_static_entities--;
926 void CL_ParseStaticSound (int large)
929 int sound_num, vol, atten;
933 sound_num = (unsigned short) MSG_ReadShort ();
935 sound_num = MSG_ReadByte ();
936 vol = MSG_ReadByte ();
937 atten = MSG_ReadByte ();
939 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
942 void CL_ParseEffect (void)
945 int modelindex, startframe, framecount, framerate;
948 modelindex = MSG_ReadByte ();
949 startframe = MSG_ReadByte ();
950 framecount = MSG_ReadByte ();
951 framerate = MSG_ReadByte ();
953 CL_Effect(org, modelindex, startframe, framecount, framerate);
956 void CL_ParseEffect2 (void)
959 int modelindex, startframe, framecount, framerate;
962 modelindex = MSG_ReadShort ();
963 startframe = MSG_ReadShort ();
964 framecount = MSG_ReadByte ();
965 framerate = MSG_ReadByte ();
967 CL_Effect(org, modelindex, startframe, framecount, framerate);
971 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
973 static qbyte cgamenetbuffer[65536];
976 =====================
977 CL_ParseServerMessage
978 =====================
980 void CL_ParseServerMessage (void)
983 int i, entitiesupdated;
985 char *cmdlogname[32], *temp;
986 int cmdindex, cmdcount = 0;
989 // if recording demos, copy the message out
991 if (cl_shownet.integer == 1)
992 Con_Printf ("%i ",net_message.cursize);
993 else if (cl_shownet.integer == 2)
994 Con_Printf ("------------------\n");
996 cl.onground = false; // unless the server says otherwise
1000 MSG_BeginReading ();
1002 entitiesupdated = false;
1007 Host_Error ("CL_ParseServerMessage: Bad server message");
1009 cmd = MSG_ReadByte ();
1013 SHOWNET("END OF MESSAGE");
1014 break; // end of message
1017 cmdindex = cmdcount & 31;
1019 cmdlog[cmdindex] = cmd;
1021 // if the high bit of the command byte is set, it is a fast update
1024 // 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)
1026 cmdlogname[cmdindex] = temp;
1027 SHOWNET("fast update");
1028 if (cls.signon == SIGNONS - 1)
1030 // first update is the final signon stage
1031 cls.signon = SIGNONS;
1034 CL_ParseUpdate (cmd&127);
1038 SHOWNET(svc_strings[cmd]);
1039 cmdlogname[cmdindex] = svc_strings[cmd];
1040 if (!cmdlogname[cmdindex])
1042 // 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)
1044 cmdlogname[cmdindex] = temp;
1052 char description[32*64], temp[64];
1054 strcpy(description, "packet dump: ");
1058 count = cmdcount - i;
1062 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
1063 strcat(description, temp);
1068 description[strlen(description)-1] = '\n'; // replace the last space with a newline
1069 Con_Printf("%s", description);
1070 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
1078 if (!entitiesupdated)
1080 // this is a new frame, we'll be seeing entities,
1081 // so prepare for entity updates
1082 CL_EntityUpdateSetup();
1083 entitiesupdated = true;
1085 cl.mtime[1] = cl.mtime[0];
1086 cl.mtime[0] = MSG_ReadFloat ();
1089 case svc_clientdata:
1090 i = MSG_ReadShort ();
1091 CL_ParseClientdata (i);
1095 i = MSG_ReadLong ();
1096 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
1097 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
1098 Nehahrademcompatibility = false;
1100 Nehahrademcompatibility = true;
1101 if (cls.demoplayback && demo_nehahra.integer)
1102 Nehahrademcompatibility = true;
1104 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
1108 case svc_disconnect:
1109 Host_EndGame ("Server disconnected\n");
1112 Con_Printf ("%s", MSG_ReadString ());
1115 case svc_centerprint:
1116 SCR_CenterPrint (MSG_ReadString ());
1120 Cbuf_AddText (MSG_ReadString ());
1127 case svc_serverinfo:
1128 CL_ParseServerInfo ();
1132 for (i=0 ; i<3 ; i++)
1133 cl.viewangles[i] = MSG_ReadAngle ();
1137 cl.viewentity = MSG_ReadShort ();
1140 case svc_lightstyle:
1141 i = MSG_ReadByte ();
1142 if (i >= MAX_LIGHTSTYLES)
1143 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1144 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1145 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1146 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1150 CL_ParseStartSoundPacket(false);
1154 CL_ParseStartSoundPacket(true);
1158 i = MSG_ReadShort();
1159 S_StopSound(i>>3, i&7);
1162 case svc_updatename:
1163 i = MSG_ReadByte ();
1164 if (i >= cl.maxclients)
1165 Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
1166 strcpy (cl.scores[i].name, MSG_ReadString ());
1169 case svc_updatefrags:
1170 i = MSG_ReadByte ();
1171 if (i >= cl.maxclients)
1172 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
1173 cl.scores[i].frags = MSG_ReadShort ();
1176 case svc_updatecolors:
1177 i = MSG_ReadByte ();
1178 if (i >= cl.maxclients)
1179 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
1180 cl.scores[i].colors = MSG_ReadByte ();
1184 CL_ParseParticleEffect ();
1195 case svc_spawnbaseline:
1196 i = MSG_ReadShort ();
1197 // must use CL_EntityNum() to force cl.num_entities up
1198 CL_ParseBaseline (CL_EntityNum(i), false);
1200 case svc_spawnbaseline2:
1201 i = MSG_ReadShort ();
1202 // must use CL_EntityNum() to force cl.num_entities up
1203 CL_ParseBaseline (CL_EntityNum(i), true);
1205 case svc_spawnstatic:
1206 CL_ParseStatic (false);
1208 case svc_spawnstatic2:
1209 CL_ParseStatic (true);
1211 case svc_temp_entity:
1216 cl.paused = MSG_ReadByte ();
1224 i = MSG_ReadByte ();
1225 if (i <= cls.signon)
1226 Host_Error ("Received signon %i when at %i", i, cls.signon);
1231 case svc_killedmonster:
1232 cl.stats[STAT_MONSTERS]++;
1235 case svc_foundsecret:
1236 cl.stats[STAT_SECRETS]++;
1239 case svc_updatestat:
1240 i = MSG_ReadByte ();
1241 if (i < 0 || i >= MAX_CL_STATS)
1242 Host_Error ("svc_updatestat: %i is invalid", i);
1243 cl.stats[i] = MSG_ReadLong ();
1246 case svc_spawnstaticsound:
1247 CL_ParseStaticSound (false);
1250 case svc_spawnstaticsound2:
1251 CL_ParseStaticSound (true);
1255 cl.cdtrack = MSG_ReadByte ();
1256 cl.looptrack = MSG_ReadByte ();
1257 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1258 CDAudio_Play ((qbyte)cls.forcetrack, true);
1260 CDAudio_Play ((qbyte)cl.cdtrack, true);
1263 case svc_intermission:
1264 cl.intermission = 1;
1265 cl.completed_time = cl.time;
1269 cl.intermission = 2;
1270 cl.completed_time = cl.time;
1271 SCR_CenterPrint (MSG_ReadString ());
1275 cl.intermission = 3;
1276 cl.completed_time = cl.time;
1277 SCR_CenterPrint (MSG_ReadString ());
1280 case svc_sellscreen:
1281 Cmd_ExecuteString ("help", src_command);
1284 SHOWLMP_decodehide();
1287 SHOWLMP_decodeshow();
1290 R_SetSkyBox(MSG_ReadString());
1295 length = (int) ((unsigned short) MSG_ReadShort());
1296 for (i = 0;i < length;i++)
1297 cgamenetbuffer[i] = MSG_ReadByte();
1299 CL_CGVM_ParseNetwork(cgamenetbuffer, length);
1303 if (cls.signon == SIGNONS - 1)
1305 // first update is the final signon stage
1306 cls.signon = SIGNONS;
1309 CL_ReadEntityFrame();
1314 if (entitiesupdated)
1315 CL_EntityUpdateEnd();