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