1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3 
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.
8 
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.
12 
13 See the GNU General Public License for more details.
14 
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.
18 
19 */
20 // cl_parse.c  -- parse a message received from the server
21 
22 #include <stdio.h>
23 
24 #include "cdaudio.h"
25 #include "client.h"
26 #include "cmd.h"
27 #include "console.h"
28 #include "host.h"
29 #include "model.h"
30 #include "net.h"
31 #include "protocol.h"
32 #include "quakedef.h"
33 #include "sbar.h"
34 #include "screen.h"
35 #include "server.h"
36 #include "sound.h"
37 #include "bgmusic.h"
38 #include "sys.h"
39 
40 static const char *svc_strings[] = {
41     "svc_bad",
42     "svc_nop",
43     "svc_disconnect",
44     "svc_updatestat",
45     "svc_version",		// [long] server version
46     "svc_setview",		// [short] entity number
47     "svc_sound",		// <see code>
48     "svc_time",			// [float] server time
49     "svc_print",		// [string] null terminated string
50     "svc_stufftext",		// [string] stuffed into client's console buffer
51     // the string should be \n terminated
52     "svc_setangle",		// [vec3] set the view angle to this absolute value
53 
54     "svc_serverinfo",		// [long] version
55     // [string] signon string
56     // [string]..[0]model cache [string]...[0]sounds cache
57     // [string]..[0]item cache
58     "svc_lightstyle",		// [byte] [string]
59     "svc_updatename",		// [byte] [string]
60     "svc_updatefrags",		// [byte] [short]
61     "svc_clientdata",		// <shortbits + data>
62     "svc_stopsound",		// <see code>
63     "svc_updatecolors",		// [byte] [byte]
64     "svc_particle",		// [vec3] <variable>
65     "svc_damage",		// [byte] impact [byte] blood [vec3] from
66 
67     "svc_spawnstatic",
68     "OBSOLETE svc_spawnbinary",
69     "svc_spawnbaseline",
70 
71     "svc_temp_entity",		// <variable>
72     "svc_setpause",
73     "svc_signonnum",
74     "svc_centerprint",
75     "svc_killedmonster",
76     "svc_foundsecret",
77     "svc_spawnstaticsound",
78     "svc_intermission",
79     "svc_finale",		// [string] music [string] text
80     "svc_cdtrack",		// [byte] track [byte] looptrack
81     "svc_sellscreen",
82     "svc_cutscene",
83     "",				// 35
84     "",				// 36
85     "svc_fitz_skybox",
86     "",				// 38
87     "",				// 39
88     "svc_fitz_bf",
89     "svc_fitz_fog",
90     "svc_fitz_spawnbaseline2",
91     "svc_fitz_spawnstatic2",
92     "svc_fitz_spawnstaticsound2",
93     "",				// 45
94     "",				// 46
95     "",				// 47
96     "",				// 48
97     "",				// 49
98 };
99 
100 //=============================================================================
101 
102 /*
103 ===============
104 CL_EntityNum
105 
106 This error checks and tracks the total number of entities
107 ===============
108 */
109 entity_t *
CL_EntityNum(int num)110 CL_EntityNum(int num)
111 {
112     if (num >= cl.num_entities) {
113 	if (num >= MAX_EDICTS)
114 	    Host_Error("CL_EntityNum: %i is an invalid number", num);
115 	while (cl.num_entities <= num) {
116 	    cl_entities[cl.num_entities].colormap = vid.colormap;
117 	    cl.num_entities++;
118 	}
119     }
120 
121     return &cl_entities[num];
122 }
123 
124 
CL_ReadSoundNum(int field_mask)125 static int CL_ReadSoundNum(int field_mask)
126 {
127    switch (cl.protocol)
128    {
129       case PROTOCOL_VERSION_NQ:
130       case PROTOCOL_VERSION_BJP:
131          return MSG_ReadByte();
132       case PROTOCOL_VERSION_BJP2:
133       case PROTOCOL_VERSION_BJP3:
134          return (unsigned short)MSG_ReadShort();
135       case PROTOCOL_VERSION_FITZ:
136          if (field_mask & SND_FITZ_LARGESOUND)
137             return (unsigned short)MSG_ReadShort();
138          else
139             return MSG_ReadByte();
140       default:
141          Host_Error("%s: Unknown protocol version (%d)\n", __func__,
142                cl.protocol);
143    }
144 
145    return 0;
146 }
147 
148 /*
149 ==================
150 CL_ParseStartSoundPacket
151 ==================
152 */
153 void
CL_ParseStartSoundPacket(void)154 CL_ParseStartSoundPacket(void)
155 {
156    vec3_t pos;
157    int channel, ent;
158    int sound_num;
159    int volume;
160    float attenuation;
161    int i;
162    int field_mask = MSG_ReadByte();
163 
164    if (field_mask & SND_VOLUME)
165       volume = MSG_ReadByte();
166    else
167       volume = DEFAULT_SOUND_PACKET_VOLUME;
168 
169    if (field_mask & SND_ATTENUATION)
170       attenuation = MSG_ReadByte() / 64.0;
171    else
172       attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
173 
174    if (cl.protocol == PROTOCOL_VERSION_FITZ && (field_mask & SND_FITZ_LARGEENTITY))
175    {
176       ent = (unsigned short)MSG_ReadShort();
177       channel = MSG_ReadByte();
178    }
179    else
180    {
181       channel = MSG_ReadShort();
182       ent = channel >> 3;
183       channel &= 7;
184    }
185    sound_num = CL_ReadSoundNum(field_mask);
186 
187    if (ent > MAX_EDICTS)
188       Host_Error("CL_ParseStartSoundPacket: ent = %i", ent);
189 
190    for (i = 0; i < 3; i++)
191       pos[i] = MSG_ReadCoord();
192 
193    S_StartSound(ent, channel, cl.sound_precache[sound_num], pos,
194          volume / 255.0, attenuation);
195 }
196 
197 /*
198 ==================
199 CL_KeepaliveMessage
200 
201 When the client is taking a long time to load stuff, send keepalive messages
202 so the server doesn't disconnect.
203 ==================
204 */
205 void
CL_KeepaliveMessage(void)206 CL_KeepaliveMessage(void)
207 {
208     float time;
209     static float lastmsg;
210     int ret;
211     sizebuf_t old;
212     byte olddata[8192];
213 
214     if (sv.active)
215 	return;			// no need if server is local
216     if (cls.demoplayback)
217 	return;
218 
219 // read messages from server, should just be nops
220     old = net_message;
221     memcpy(olddata, net_message.data, net_message.cursize);
222 
223     do {
224 	ret = CL_GetMessage();
225 	switch (ret) {
226 	case 0:
227 	    break;		// nothing waiting
228 	case 1:
229 	    Host_Error("%s: received a message", __func__);
230 	case 2:
231 	    if (MSG_ReadByte() != svc_nop)
232 		Host_Error("%s: datagram wasn't a nop", __func__);
233 	    break;
234 	default:
235 	    Host_Error("%s: CL_GetMessage failed", __func__);
236 	}
237     } while (ret);
238 
239     net_message = old;
240     memcpy(net_message.data, olddata, net_message.cursize);
241 
242 // check time
243     time = Sys_DoubleTime();
244     if (time - lastmsg < 5)
245 	return;
246     lastmsg = time;
247 
248 // write out a nop
249     Con_Printf("--> client to server keepalive\n");
250 
251     MSG_WriteByte(&cls.message, clc_nop);
252     NET_SendMessage(cls.netcon, &cls.message);
253     SZ_Clear(&cls.message);
254 }
255 
256 /*
257 ==================
258 CL_ParseServerInfo
259 ==================
260 */
261 void
CL_ParseServerInfo(void)262 CL_ParseServerInfo(void)
263 {
264     char *level;
265     const char *mapname;
266     int i, maxlen;
267     int nummodels, numsounds;
268     char **model_precache = malloc(sizeof(char*) * MAX_MODELS);
269     char **sound_precache = malloc(sizeof(char*) * MAX_SOUNDS);
270     for (i = 0; i < MAX_MODELS; i++)
271        model_precache[i] = malloc(sizeof(char*) * MAX_QPATH);
272     for (i = 0; i < MAX_SOUNDS; i++)
273        sound_precache[i] = malloc(sizeof(char*) * MAX_QPATH);
274 
275     Con_DPrintf("Serverinfo packet received.\n");
276 
277     /* wipe the client_state_t struct */
278     CL_ClearState();
279 
280     /* parse protocol version number */
281     i = MSG_ReadLong();
282     if (!Protocol_Known(i))
283     {
284        Con_Printf("Server returned unknown protocol version %i\n", i);
285        return;
286     }
287     cl.protocol = i;
288 
289     /* parse maxclients */
290     cl.maxclients = MSG_ReadByte();
291     if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
292     {
293        Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
294        return;
295     }
296     cl.players = (player_info_t*)Hunk_AllocName(cl.maxclients * sizeof(*cl.players), "players");
297 
298     /* parse gametype */
299     cl.gametype = MSG_ReadByte();
300 
301     /* parse signon message */
302     level = cl.levelname;
303     maxlen = sizeof(cl.levelname);
304     snprintf(level, maxlen, "%s", MSG_ReadString());
305 
306     /* seperate the printfs so the server message can have a color */
307     Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
308 	       "\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
309     Con_Printf("%c%s\n", 2, level);
310     Con_Printf("Using protocol %i\n", cl.protocol);
311 
312     // first we go through and touch all of the precache data that still
313     // happens to be in the cache, so precaching something else doesn't
314     // needlessly purge it
315 
316     /* precache models */
317     memset(cl.model_precache, 0, sizeof(cl.model_precache));
318     for (nummodels = 1;; nummodels++)
319     {
320        char *in = MSG_ReadString();
321        if (!in[0])
322           break;
323        if (nummodels == max_models(cl.protocol))
324        {
325           Host_Error("Server sent too many model precaches (max = %d)",
326                 max_models(cl.protocol));
327           return;
328        }
329        strcpy(model_precache[nummodels], in);
330        Mod_TouchModel(in);
331     }
332 
333     /* precache sounds */
334     memset(cl.sound_precache, 0, sizeof(cl.sound_precache));
335     for (numsounds = 1;; numsounds++)
336     {
337        char *in = MSG_ReadString();
338        if (!in[0])
339           break;
340        if (numsounds == max_sounds(cl.protocol))
341        {
342           Host_Error("Server sent too many sound precaches (max = %d)",
343                 max_sounds(cl.protocol));
344           return;
345        }
346 
347        strcpy(sound_precache[numsounds], in);
348        S_TouchSound(in);
349     }
350 
351     /* copy the naked name of the map file to the cl structure */
352     mapname = COM_SkipPath(model_precache[1]);
353     snprintf(cl.mapname, sizeof(cl.mapname), "%s", mapname);
354     COM_StripExtension(cl.mapname);
355 
356     /* now we try to load everything else until a cache allocation fails */
357 
358     for (i = 1; i < nummodels; i++)
359     {
360        cl.model_precache[i] = Mod_ForName(model_precache[i], false);
361        if (cl.model_precache[i] == NULL)
362        {
363           Con_Printf("Model %s not found\n", model_precache[i]);
364           return;
365        }
366        CL_KeepaliveMessage();
367     }
368 
369     S_BeginPrecaching();
370     for (i = 1; i < numsounds; i++)
371     {
372        cl.sound_precache[i] = S_PrecacheSound(sound_precache[i]);
373        CL_KeepaliveMessage();
374     }
375     S_EndPrecaching();
376 
377 
378     /* local state */
379     cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
380 
381     R_NewMap();
382 
383     /* make sure nothing is hurt */
384     Hunk_Check();
385 
386     /* noclip is turned off at start */
387     noclip_anglehack = false;
388 
389     for (i = 0; i < MAX_MODELS; i++)
390        free(model_precache[i]);
391     free(model_precache);
392     for (i = 0; i < MAX_SOUNDS; i++)
393        free(sound_precache[i]);
394     free(sound_precache);
395 }
396 
397 
CL_ReadModelIndex(unsigned int bits)398 static int CL_ReadModelIndex(unsigned int bits)
399 {
400    switch (cl.protocol)
401    {
402       case PROTOCOL_VERSION_NQ:
403          return MSG_ReadByte();
404       case PROTOCOL_VERSION_BJP:
405       case PROTOCOL_VERSION_BJP2:
406       case PROTOCOL_VERSION_BJP3:
407          return MSG_ReadShort();
408       case PROTOCOL_VERSION_FITZ:
409          if (bits & B_FITZ_LARGEMODEL)
410             return MSG_ReadShort();
411          return MSG_ReadByte();
412       default:
413          break;
414    }
415 
416    Host_Error("%s: Unknown protocol version (%d)\n", __func__,
417          cl.protocol);
418    return 0; /* should never happen */
419 }
420 
CL_ReadModelFrame(unsigned int bits)421 static int CL_ReadModelFrame(unsigned int bits)
422 {
423    switch (cl.protocol)
424    {
425       case PROTOCOL_VERSION_NQ:
426       case PROTOCOL_VERSION_BJP:
427       case PROTOCOL_VERSION_BJP2:
428       case PROTOCOL_VERSION_BJP3:
429          return MSG_ReadByte();
430       case PROTOCOL_VERSION_FITZ:
431          if (bits & B_FITZ_LARGEFRAME)
432             return MSG_ReadShort();
433          return MSG_ReadByte();
434       default:
435          break;
436    }
437 
438    Host_Error("%s: Unknown protocol version (%d)\n", __func__,
439          cl.protocol);
440    return 0; /* should never happen */
441 }
442 
443 /*
444 ==================
445 CL_ParseUpdate
446 
447 Parse an entity update message from the server
448 If an entities model or origin changes from frame to frame, it must be
449 relinked.  Other attributes can change without relinking.
450 ==================
451 */
452 
453 void
CL_ParseUpdate(unsigned int bits)454 CL_ParseUpdate(unsigned int bits)
455 {
456    int i;
457    model_t *model;
458    int modnum;
459    qboolean forcelink;
460    entity_t *ent;
461    int num;
462 
463    if (cls.state == ca_firstupdate) {
464       // first update is the final signon stage
465       cls.signon = SIGNONS;
466       CL_SignonReply();
467    }
468 
469    if (bits & U_MOREBITS) {
470       i = MSG_ReadByte();
471       bits |= (i << 8);
472    }
473 
474    if (cl.protocol == PROTOCOL_VERSION_FITZ) {
475       if (bits & U_FITZ_EXTEND1)
476          bits |= MSG_ReadByte() << 16;
477       if (bits & U_FITZ_EXTEND2)
478          bits |= MSG_ReadByte() << 24;
479    }
480 
481    if (bits & U_LONGENTITY)
482       num = MSG_ReadShort();
483    else
484       num = MSG_ReadByte();
485 
486    ent = CL_EntityNum(num);
487 
488    if (ent->msgtime != cl.mtime[1])
489       forcelink = true;	// no previous frame to lerp from
490    else
491       forcelink = false;
492 
493    ent->msgtime = cl.mtime[0];
494 
495    if (bits & U_MODEL) {
496       modnum = CL_ReadModelIndex(0);
497       if (modnum >= max_models(cl.protocol))
498          Host_Error("CL_ParseModel: bad modnum");
499    } else
500       modnum = ent->baseline.modelindex;
501 
502    if (bits & U_FRAME)
503       ent->frame = MSG_ReadByte();
504    else
505       ent->frame = ent->baseline.frame;
506 
507    /* ANIMATION LERPING INFO */
508    if (ent->currentframe != ent->frame) {
509       /* TODO: invalidate things when they fall off the
510          currententities list or haven't been updated for a while */
511       ent->previousframe = ent->currentframe;
512       ent->previousframetime = ent->currentframetime;
513       ent->currentframe = ent->frame;
514       ent->currentframetime = cl.time;
515    }
516 
517    if (bits & U_COLORMAP)
518       i = MSG_ReadByte();
519    else
520       i = ent->baseline.colormap;
521    if (!i)
522       ent->colormap = vid.colormap;
523    else {
524       if (i > cl.maxclients)
525          Sys_Error("i >= cl.maxclients");
526       ent->colormap = cl.players[i - 1].translations;
527    }
528 
529    if (bits & U_SKIN)
530       ent->skinnum = MSG_ReadByte();
531    else
532       ent->skinnum = ent->baseline.skinnum;
533 
534    if (bits & U_EFFECTS)
535       ent->effects = MSG_ReadByte();
536    else
537       ent->effects = ent->baseline.effects;
538 
539    // shift the known values for interpolation
540    VectorCopy(ent->msg_origins[0], ent->msg_origins[1]);
541    VectorCopy(ent->msg_angles[0], ent->msg_angles[1]);
542 
543    if (bits & U_ORIGIN1)
544       ent->msg_origins[0][0] = MSG_ReadCoord();
545    else
546       ent->msg_origins[0][0] = ent->baseline.origin[0];
547    if (bits & U_ANGLE1)
548       ent->msg_angles[0][0] = MSG_ReadAngle();
549    else
550       ent->msg_angles[0][0] = ent->baseline.angles[0];
551 
552    if (bits & U_ORIGIN2)
553       ent->msg_origins[0][1] = MSG_ReadCoord();
554    else
555       ent->msg_origins[0][1] = ent->baseline.origin[1];
556    if (bits & U_ANGLE2)
557       ent->msg_angles[0][1] = MSG_ReadAngle();
558    else
559       ent->msg_angles[0][1] = ent->baseline.angles[1];
560 
561    if (bits & U_ORIGIN3)
562       ent->msg_origins[0][2] = MSG_ReadCoord();
563    else
564       ent->msg_origins[0][2] = ent->baseline.origin[2];
565    if (bits & U_ANGLE3)
566       ent->msg_angles[0][2] = MSG_ReadAngle();
567    else
568       ent->msg_angles[0][2] = ent->baseline.angles[2];
569 
570    if (cl.protocol == PROTOCOL_VERSION_FITZ) {
571       if (bits & U_NOLERP) {
572          // FIXME - TODO (called U_STEP in FQ)
573       }
574       if (bits & U_FITZ_ALPHA) {
575          MSG_ReadByte(); // FIXME - TODO
576       }
577       if (bits & U_FITZ_FRAME2)
578          ent->frame = (ent->frame & 0xFF) | (MSG_ReadByte() << 8);
579       if (bits & U_FITZ_MODEL2)
580          modnum = (modnum & 0xFF)| (MSG_ReadByte() << 8);
581       if (bits & U_FITZ_LERPFINISH) {
582          MSG_ReadByte(); // FIXME - TODO
583       }
584    }
585 
586    model = cl.model_precache[modnum];
587    if (model != ent->model) {
588       ent->model = model;
589       // automatic animation (torches, etc) can be either all together
590       // or randomized
591       if (model) {
592          if (model->synctype == ST_RAND)
593             ent->syncbase = (float)(rand() & 0x7fff) / 0x7fff;
594          else
595             ent->syncbase = 0.0;
596       } else
597          forcelink = true;	// hack to make null model players work
598    }
599 
600    /* MOVEMENT LERP INFO - could I just extend baseline instead? */
601    if (!VectorCompare(ent->msg_origins[0], ent->currentorigin)) {
602       if (ent->currentorigintime) {
603          VectorCopy(ent->currentorigin, ent->previousorigin);
604          ent->previousorigintime = ent->currentorigintime;
605       } else {
606          VectorCopy(ent->msg_origins[0], ent->previousorigin);
607          ent->previousorigintime = cl.mtime[0];
608       }
609       VectorCopy(ent->msg_origins[0], ent->currentorigin);
610       ent->currentorigintime = cl.mtime[0];
611    }
612    if (!VectorCompare(ent->msg_angles[0], ent->currentangles)) {
613       if (ent->currentanglestime) {
614          VectorCopy(ent->currentangles, ent->previousangles);
615          ent->previousanglestime = ent->currentanglestime;
616       } else {
617          VectorCopy(ent->msg_angles[0], ent->previousangles);
618          ent->previousanglestime = cl.mtime[0];
619       }
620       VectorCopy(ent->msg_angles[0], ent->currentangles);
621       ent->currentanglestime = cl.mtime[0];
622    }
623 
624    if (bits & U_NOLERP)
625       ent->forcelink = true;
626 
627    if (forcelink) {		// didn't have an update last message
628       VectorCopy(ent->msg_origins[0], ent->msg_origins[1]);
629       VectorCopy(ent->msg_origins[0], ent->origin);
630       VectorCopy(ent->msg_angles[0], ent->msg_angles[1]);
631       VectorCopy(ent->msg_angles[0], ent->angles);
632       ent->forcelink = true;
633    }
634 }
635 
636 /*
637 ==================
638 CL_ParseBaseline
639 ==================
640 */
641 static void
CL_ParseBaseline(entity_t * ent,unsigned int bits)642 CL_ParseBaseline(entity_t *ent, unsigned int bits)
643 {
644    int i;
645 
646    ent->baseline.modelindex = CL_ReadModelIndex(bits);
647    ent->baseline.frame      = CL_ReadModelFrame(bits);
648    ent->baseline.colormap   = MSG_ReadByte();
649    ent->baseline.skinnum    = MSG_ReadByte();
650    for (i = 0; i < 3; i++)
651    {
652       ent->baseline.origin[i] = MSG_ReadCoord();
653       ent->baseline.angles[i] = MSG_ReadAngle();
654    }
655 
656    if (cl.protocol == PROTOCOL_VERSION_FITZ && (bits & B_FITZ_ALPHA))
657       MSG_ReadByte(); // FIXME - TODO
658 }
659 
660 
661 /*
662 ==================
663 CL_ParseClientdata
664 
665 Server information pertaining to this client only
666 ==================
667 */
668 void
CL_ParseClientdata(void)669 CL_ParseClientdata(void)
670 {
671     int i, j;
672     unsigned int bits;
673 
674     bits = (unsigned short)MSG_ReadShort();
675     if (bits & SU_FITZ_EXTEND1)
676 	bits |= MSG_ReadByte() << 16;
677     if (bits & SU_FITZ_EXTEND2)
678 	bits |= MSG_ReadByte() << 24;
679 
680     if (bits & SU_VIEWHEIGHT)
681 	cl.viewheight = MSG_ReadChar();
682     else
683 	cl.viewheight = DEFAULT_VIEWHEIGHT;
684 
685     if (bits & SU_IDEALPITCH)
686 	cl.idealpitch = MSG_ReadChar();
687     else
688 	cl.idealpitch = 0;
689 
690     VectorCopy(cl.mvelocity[0], cl.mvelocity[1]);
691     for (i = 0; i < 3; i++) {
692 	if (bits & (SU_PUNCH1 << i))
693 	    cl.punchangle[i] = MSG_ReadChar();
694 	else
695 	    cl.punchangle[i] = 0;
696 	if (bits & (SU_VELOCITY1 << i))
697 	    cl.mvelocity[0][i] = MSG_ReadChar() * 16;
698 	else
699 	    cl.mvelocity[0][i] = 0;
700     }
701 
702 // [always sent]        if (bits & SU_ITEMS)
703     i = MSG_ReadLong();
704 
705     if (cl.stats[STAT_ITEMS] != i) {	// set flash times
706 	Sbar_Changed();
707 	for (j = 0; j < 32; j++)
708 	    if ((i & (1 << j)) && !(cl.stats[STAT_ITEMS] & (1 << j)))
709 		cl.item_gettime[j] = cl.time;
710 	cl.stats[STAT_ITEMS] = i;
711     }
712 
713     cl.onground = (bits & SU_ONGROUND) != 0;
714     cl.inwater = (bits & SU_INWATER) != 0;
715 
716     if (bits & SU_WEAPONFRAME)
717 	cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte();
718     else
719 	cl.stats[STAT_WEAPONFRAME] = 0;
720 
721     if (bits & SU_ARMOR)
722 	i = MSG_ReadByte();
723     else
724 	i = 0;
725     if (cl.stats[STAT_ARMOR] != i) {
726 	cl.stats[STAT_ARMOR] = i;
727 	Sbar_Changed();
728     }
729 
730     if (bits & SU_WEAPON)
731 	i = CL_ReadModelIndex(0);
732     else
733 	i = 0;
734     if (cl.stats[STAT_WEAPON] != i) {
735 	cl.stats[STAT_WEAPON] = i;
736 	Sbar_Changed();
737     }
738 
739     i = MSG_ReadShort();
740     if (cl.stats[STAT_HEALTH] != i) {
741 	cl.stats[STAT_HEALTH] = i;
742 	Sbar_Changed();
743     }
744 
745     i = MSG_ReadByte();
746     if (cl.stats[STAT_AMMO] != i) {
747 	cl.stats[STAT_AMMO] = i;
748 	Sbar_Changed();
749     }
750 
751     for (i = 0; i < 4; i++) {
752 	j = MSG_ReadByte();
753 	if (cl.stats[STAT_SHELLS + i] != j) {
754 	    cl.stats[STAT_SHELLS + i] = j;
755 	    Sbar_Changed();
756 	}
757     }
758 
759     i = MSG_ReadByte();
760 
761     if (standard_quake) {
762 	if (cl.stats[STAT_ACTIVEWEAPON] != i) {
763 	    cl.stats[STAT_ACTIVEWEAPON] = i;
764 	    Sbar_Changed();
765 	}
766     } else {
767 	if (cl.stats[STAT_ACTIVEWEAPON] != (1 << i)) {
768 	    cl.stats[STAT_ACTIVEWEAPON] = (1 << i);
769 	    Sbar_Changed();
770 	}
771     }
772 
773     /* FITZ Protocol */
774     if (bits & SU_FITZ_WEAPON2)
775 	cl.stats[STAT_WEAPON] |= MSG_ReadByte() << 8;
776     if (bits & SU_FITZ_ARMOR2)
777 	cl.stats[STAT_ARMOR] |= MSG_ReadByte() << 8;
778     if (bits & SU_FITZ_AMMO2)
779 	cl.stats[STAT_AMMO] |= MSG_ReadByte() << 8;
780     if (bits & SU_FITZ_SHELLS2)
781 	cl.stats[STAT_SHELLS] |= MSG_ReadByte() << 8;
782     if (bits & SU_FITZ_NAILS2)
783 	cl.stats[STAT_NAILS] |= MSG_ReadByte() << 8;
784     if (bits & SU_FITZ_ROCKETS2)
785 	cl.stats[STAT_ROCKETS] |= MSG_ReadByte() << 8;
786     if (bits & SU_FITZ_CELLS2)
787 	cl.stats[STAT_CELLS] |= MSG_ReadByte() << 8;
788     if (bits & SU_FITZ_WEAPONFRAME2)
789 	cl.stats[STAT_WEAPONFRAME] |= MSG_ReadByte() << 8;
790     if (bits & SU_FITZ_WEAPONALPHA)
791 	MSG_ReadByte(); // FIXME - TODO
792 }
793 
794 /*
795 =====================
796 CL_NewTranslation
797 =====================
798 */
799 void
CL_NewTranslation(int slot)800 CL_NewTranslation(int slot)
801 {
802    int i, j;
803    int top, bottom;
804    byte *dest, *source;
805 
806    if (slot > cl.maxclients)
807       Sys_Error("%s: slot > cl.maxclients", __func__);
808    dest = cl.players[slot].translations;
809    source = vid.colormap;
810    memcpy(dest, vid.colormap, sizeof(cl.players[slot].translations));
811    top = cl.players[slot].topcolor;
812    bottom = cl.players[slot].bottomcolor;
813 
814    for (i = 0; i < VID_GRADES; i++, dest += 256, source += 256) {
815       if (top < 128)		// the artists made some backwards ranges.  sigh.
816          memcpy(dest + TOP_RANGE, source + top, 16);
817       else
818          for (j = 0; j < 16; j++)
819             dest[TOP_RANGE + j] = source[top + 15 - j];
820 
821       if (bottom < 128)
822          memcpy(dest + BOTTOM_RANGE, source + bottom, 16);
823       else
824          for (j = 0; j < 16; j++)
825             dest[BOTTOM_RANGE + j] = source[bottom + 15 - j];
826    }
827 }
828 
829 /*
830 =====================
831 CL_ParseStatic
832 =====================
833 */
834 void
CL_ParseStatic(unsigned int bits)835 CL_ParseStatic(unsigned int bits)
836 {
837     entity_t *ent;
838     int i;
839 
840     i = cl.num_statics;
841     if (i >= MAX_STATIC_ENTITIES)
842 	Host_Error("Too many static entities");
843     ent = &cl_static_entities[i];
844     cl.num_statics++;
845     CL_ParseBaseline(ent, bits);
846 
847 // copy it to the current state
848     ent->model = cl.model_precache[ent->baseline.modelindex];
849     ent->frame = ent->baseline.frame;
850     ent->colormap = vid.colormap;
851     ent->skinnum = ent->baseline.skinnum;
852     ent->effects = ent->baseline.effects;
853 
854     /* Initilise frames for model lerp */
855     ent->currentframe = ent->baseline.frame;
856     ent->previousframe = ent->baseline.frame;
857     ent->currentframetime = cl.time;
858     ent->previousframetime = cl.time;
859 
860     /* Initialise movelerp data */
861     ent->previousorigintime = cl.time;
862     ent->currentorigintime = cl.time;
863     VectorCopy(ent->baseline.origin, ent->previousorigin);
864     VectorCopy(ent->baseline.origin, ent->currentorigin);
865     VectorCopy(ent->baseline.angles, ent->previousangles);
866     VectorCopy(ent->baseline.angles, ent->currentangles);
867 
868     VectorCopy(ent->baseline.origin, ent->origin);
869     VectorCopy(ent->baseline.angles, ent->angles);
870     R_AddEfrags(ent);
871 }
872 
873 
CL_ReadSoundNum_Static(void)874 static int CL_ReadSoundNum_Static(void)
875 {
876    switch (cl.protocol)
877    {
878       case PROTOCOL_VERSION_NQ:
879       case PROTOCOL_VERSION_BJP:
880       case PROTOCOL_VERSION_BJP3:
881       case PROTOCOL_VERSION_FITZ:
882          return MSG_ReadByte();
883       case PROTOCOL_VERSION_BJP2:
884          return MSG_ReadShort();
885       default:
886          break;
887    }
888 
889    Host_Error("%s: Unknown protocol version (%d)\n", __func__,
890          cl.protocol);
891    return 0; /* should never happen */
892 }
893 
894 /*
895 ===================
896 CL_ParseStaticSound
897 ===================
898 */
899 static void
CL_ParseStaticSound(void)900 CL_ParseStaticSound(void)
901 {
902     vec3_t org;
903     int sound_num, vol, atten;
904     int i;
905 
906     for (i = 0; i < 3; i++)
907 	org[i] = MSG_ReadCoord();
908     sound_num = CL_ReadSoundNum_Static();
909     vol = MSG_ReadByte();
910     atten = MSG_ReadByte();
911 
912     S_StaticSound(cl.sound_precache[sound_num], org, vol, atten);
913 }
914 
915 /* FITZ protocol */
916 static void
CL_ParseFitzStaticSound2(void)917 CL_ParseFitzStaticSound2(void)
918 {
919     vec3_t org;
920     int sound_num, vol, atten;
921     int i;
922 
923     for (i = 0; i < 3; i++)
924 	org[i] = MSG_ReadCoord();
925     sound_num = MSG_ReadShort();
926     vol = MSG_ReadByte();
927     atten = MSG_ReadByte();
928 
929     S_StaticSound(cl.sound_precache[sound_num], org, vol, atten);
930 }
931 
932 /* helper function (was a macro, hence the CAPS) */
933 static void
SHOWNET(const char * msg)934 SHOWNET(const char *msg)
935 {
936     if (cl_shownet.value == 2)
937 	Con_Printf("%3i:%s\n", msg_readcount - 1, msg);
938 }
939 
940 
941 /*
942 =====================
943 CL_ParseServerMessage
944 =====================
945 */
946 void
CL_ParseServerMessage(void)947 CL_ParseServerMessage(void)
948 {
949    char *s;
950    int i;
951    unsigned int bits;
952    byte colors;
953 
954    //
955    // if recording demos, copy the message out
956    //
957    if (cl_shownet.value == 1)
958       Con_Printf("%i ", net_message.cursize);
959    else if (cl_shownet.value == 2)
960       Con_Printf("------------------\n");
961 
962    cl.onground = false;	// unless the server says otherwise
963    // parse the message
964    MSG_BeginReading();
965 
966    while (1)
967    {
968       int cmd;
969 
970       if (msg_badread)
971          Host_Error("%s: Bad server message", __func__);
972 
973       cmd = MSG_ReadByte();
974 
975       if (cmd == -1) {
976          SHOWNET("END OF MESSAGE");
977          return;		// end of message
978       }
979       // if the high bit of the command byte is set, it is a fast update
980       if (cmd & 128) {
981          SHOWNET("fast update");
982          CL_ParseUpdate(cmd & 127);
983          continue;
984       }
985 
986       SHOWNET(svc_strings[cmd]);
987 
988       // other commands
989       switch (cmd) {
990          case svc_nop:
991             break;
992 
993          case svc_time:
994             cl.mtime[1] = cl.mtime[0];
995             cl.mtime[0] = MSG_ReadFloat();
996             break;
997 
998          case svc_clientdata:
999             CL_ParseClientdata();
1000             break;
1001 
1002          case svc_version:
1003             i = MSG_ReadLong();
1004             if (!Protocol_Known(i))
1005                Host_Error("%s: Server returned unknown protocol version %i",
1006                      __func__, i);
1007             cl.protocol = i;
1008             break;
1009 
1010          case svc_disconnect:
1011             Host_EndGame("Server disconnected\n");
1012 
1013          case svc_print:
1014             Con_Printf("%s", MSG_ReadString());
1015             break;
1016 
1017          case svc_centerprint:
1018             SCR_CenterPrint(MSG_ReadString());
1019             break;
1020 
1021          case svc_stufftext:
1022             Cbuf_AddText("%s", MSG_ReadString());
1023             break;
1024 
1025          case svc_damage:
1026             V_ParseDamage();
1027             break;
1028 
1029          case svc_serverinfo:
1030             CL_ParseServerInfo();
1031             vid.recalc_refdef = true;	// leave intermission full screen
1032             break;
1033 
1034          case svc_setangle:
1035             for (i = 0; i < 3; i++)
1036                cl.viewangles[i] = MSG_ReadAngle();
1037             break;
1038 
1039          case svc_setview:
1040             cl.viewentity = MSG_ReadShort();
1041             break;
1042 
1043          case svc_lightstyle:
1044             i = MSG_ReadByte();
1045             if (i >= MAX_LIGHTSTYLES)
1046                Sys_Error("svc_lightstyle > MAX_LIGHTSTYLES");
1047             s = MSG_ReadString();
1048             snprintf(cl_lightstyle[i].map, MAX_STYLESTRING, "%s", s);
1049             cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1050             break;
1051 
1052          case svc_sound:
1053             CL_ParseStartSoundPacket();
1054             break;
1055 
1056          case svc_stopsound:
1057             i = MSG_ReadShort();
1058             S_StopSound(i >> 3, i & 7);
1059             break;
1060 
1061          case svc_updatename:
1062             Sbar_Changed();
1063             i = MSG_ReadByte();
1064             if (i >= cl.maxclients)
1065                Host_Error("%s: svc_updatename > MAX_SCOREBOARD", __func__);
1066             s = MSG_ReadString();
1067             snprintf(cl.players[i].name, MAX_SCOREBOARDNAME, "%s", s);
1068             break;
1069 
1070          case svc_updatefrags:
1071             Sbar_Changed();
1072             i = MSG_ReadByte();
1073             if (i >= cl.maxclients)
1074                Host_Error("%s: svc_updatefrags > MAX_SCOREBOARD", __func__);
1075             cl.players[i].frags = MSG_ReadShort();
1076             break;
1077 
1078          case svc_updatecolors:
1079             Sbar_Changed();
1080             i = MSG_ReadByte();
1081             if (i >= cl.maxclients)
1082                Host_Error("%s: svc_updatecolors > MAX_SCOREBOARD", __func__);
1083             colors = MSG_ReadByte();
1084             cl.players[i].topcolor = (colors & 0xf0) >> 4;
1085             cl.players[i].bottomcolor = colors & 0x0f;
1086             CL_NewTranslation(i);
1087             break;
1088 
1089          case svc_particle:
1090             R_ParseParticleEffect();
1091             break;
1092 
1093          case svc_spawnbaseline:
1094             i = MSG_ReadShort();
1095             // must use CL_EntityNum() to force cl.num_entities up
1096             CL_ParseBaseline(CL_EntityNum(i), 0);
1097             break;
1098 
1099          case svc_fitz_spawnbaseline2:
1100             /* FIXME - check here that protocol is FITZ? => Host_Error() */
1101             i = MSG_ReadShort();
1102             bits = MSG_ReadByte();
1103             // must use CL_EntityNum() to force cl.num_entities up
1104             CL_ParseBaseline(CL_EntityNum(i), bits);
1105             break;
1106 
1107          case svc_spawnstatic:
1108             CL_ParseStatic(0);
1109             break;
1110 
1111          case svc_fitz_spawnstatic2:
1112             /* FIXME - check here that protocol is FITZ? => Host_Error() */
1113             bits = MSG_ReadByte();
1114             CL_ParseStatic(bits);
1115             break;
1116 
1117          case svc_temp_entity:
1118             CL_ParseTEnt();
1119             break;
1120 
1121          case svc_setpause:
1122             cl.paused = MSG_ReadByte();
1123             if (cl.paused)
1124             {
1125                CDAudio_Pause();
1126                BGM_Pause();
1127             }
1128             else
1129             {
1130                CDAudio_Resume();
1131                BGM_Resume();
1132             }
1133             break;
1134 
1135          case svc_signonnum:
1136             i = MSG_ReadByte();
1137             if (i <= cls.signon)
1138                Host_Error("Received signon %i when at %i", i, cls.signon);
1139             cls.signon = i;
1140             CL_SignonReply();
1141             break;
1142 
1143          case svc_killedmonster:
1144             cl.stats[STAT_MONSTERS]++;
1145             break;
1146 
1147          case svc_foundsecret:
1148             cl.stats[STAT_SECRETS]++;
1149             break;
1150 
1151          case svc_updatestat:
1152             i = MSG_ReadByte();
1153             if (i < 0 || i >= MAX_CL_STATS)
1154                Sys_Error("svc_updatestat: %i is invalid", i);
1155             cl.stats[i] = MSG_ReadLong();
1156             break;
1157 
1158          case svc_spawnstaticsound:
1159             CL_ParseStaticSound();
1160             break;
1161 
1162          case svc_fitz_spawnstaticsound2:
1163             /* FIXME - check here that protocol is FITZ? => Host_Error() */
1164             CL_ParseFitzStaticSound2();
1165             break;
1166 
1167          case svc_cdtrack:
1168             cl.cdtrack = MSG_ReadByte();
1169             cl.looptrack = MSG_ReadByte();
1170             if ((cls.demoplayback || cls.demorecording)
1171                   && (cls.forcetrack != -1))
1172                BGM_PlayCDtrack ((byte)cls.forcetrack, true);
1173 			else
1174                BGM_PlayCDtrack ((byte)cl.cdtrack, true);
1175             break;
1176 
1177          case svc_intermission:
1178             cl.intermission = 1;
1179             cl.completed_time = cl.time;
1180             vid.recalc_refdef = true;	// go to full screen
1181             break;
1182 
1183          case svc_finale:
1184             cl.intermission = 2;
1185             cl.completed_time = cl.time;
1186             vid.recalc_refdef = true;	// go to full screen
1187             SCR_CenterPrint(MSG_ReadString());
1188             break;
1189 
1190          case svc_cutscene:
1191             cl.intermission = 3;
1192             cl.completed_time = cl.time;
1193             vid.recalc_refdef = true;	// go to full screen
1194             SCR_CenterPrint(MSG_ReadString());
1195             break;
1196 
1197          case svc_sellscreen:
1198             Cmd_ExecuteString("help", src_command);
1199             break;
1200 
1201             /* Various FITZ protocol messages - FIXME - !protocol => Host_Error */
1202          case svc_fitz_skybox:
1203             MSG_ReadString(); // FIXME - TODO
1204             break;
1205 
1206          case svc_fitz_bf:
1207             Cmd_ExecuteString("bf", src_command);
1208             break;
1209 
1210          case svc_fitz_fog:
1211             /* FIXME - TODO */
1212             MSG_ReadByte(); // density
1213             MSG_ReadByte(); // red
1214             MSG_ReadByte(); // green
1215             MSG_ReadByte(); // blue
1216             MSG_ReadShort(); // time
1217             break;
1218 
1219          default:
1220             Host_Error("%s: Illegible server message", __func__);
1221       }
1222    }
1223 }
1224