64-bit fixes.
[AROS-Contrib.git] / Games / Quake / cl_parse.c
blob92d411ba98a61455be866ba388c5037c0cc6cf16
1 /*
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
22 #include "quakedef.h"
24 char *svc_strings[] =
26 "svc_bad",
27 "svc_nop",
28 "svc_disconnect",
29 "svc_updatestat",
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
52 "svc_spawnstatic",
53 "OBSOLETE svc_spawnbinary",
54 "svc_spawnbaseline",
56 "svc_temp_entity", // <variable>
57 "svc_setpause",
58 "svc_signonnum",
59 "svc_centerprint",
60 "svc_killedmonster",
61 "svc_foundsecret",
62 "svc_spawnstaticsound",
63 "svc_intermission",
64 "svc_finale", // [string] music [string] text
65 "svc_cdtrack", // [byte] track [byte] looptrack
66 "svc_sellscreen",
67 "svc_cutscene"
70 //=============================================================================
73 ===============
74 CL_EntityNum
76 This error checks and tracks the total number of entities
77 ===============
79 entity_t *CL_EntityNum (int num)
81 if (num >= cl.num_entities)
83 if (num >= MAX_EDICTS)
84 Host_Error ("CL_EntityNum: %i is an invalid number",num);
85 while (cl.num_entities<=num)
87 cl_entities[cl.num_entities].colormap = vid.colormap;
88 cl.num_entities++;
92 return &cl_entities[num];
97 ==================
98 CL_ParseStartSoundPacket
99 ==================
101 void CL_ParseStartSoundPacket(void)
103 vec3_t pos;
104 int channel, ent;
105 int sound_num;
106 int volume;
107 int field_mask;
108 float attenuation;
109 int i;
111 field_mask = MSG_ReadByte();
113 if (field_mask & SND_VOLUME)
114 volume = MSG_ReadByte ();
115 else
116 volume = DEFAULT_SOUND_PACKET_VOLUME;
118 if (field_mask & SND_ATTENUATION)
119 attenuation = MSG_ReadByte () / 64.0;
120 else
121 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
123 channel = MSG_ReadShort ();
124 sound_num = MSG_ReadByte ();
126 ent = channel >> 3;
127 channel &= 7;
129 if (ent > MAX_EDICTS)
130 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
132 for (i=0 ; i<3 ; i++)
133 pos[i] = MSG_ReadCoord ();
135 S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
139 ==================
140 CL_KeepaliveMessage
142 When the client is taking a long time to load stuff, send keepalive messages
143 so the server doesn't disconnect.
144 ==================
146 void CL_KeepaliveMessage (void)
148 float time;
149 static float lastmsg;
150 int ret;
151 sizebuf_t old;
152 byte olddata[8192];
154 if (sv.active)
155 return; // no need if server is local
156 if (cls.demoplayback)
157 return;
159 // read messages from server, should just be nops
160 old = net_message;
161 memcpy (olddata, net_message.data, net_message.cursize);
165 ret = CL_GetMessage ();
166 switch (ret)
168 default:
169 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
170 case 0:
171 break; // nothing waiting
172 case 1:
173 Host_Error ("CL_KeepaliveMessage: received a message");
174 break;
175 case 2:
176 if (MSG_ReadByte() != svc_nop)
177 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
178 break;
180 } while (ret);
182 net_message = old;
183 memcpy (net_message.data, olddata, net_message.cursize);
185 // check time
186 time = Sys_FloatTime ();
187 if (time - lastmsg < 5)
188 return;
189 lastmsg = time;
191 // write out a nop
192 Con_Printf ("--> client to server keepalive\n");
194 MSG_WriteByte (&cls.message, clc_nop);
195 NET_SendMessage (cls.netcon, &cls.message);
196 SZ_Clear (&cls.message);
200 ==================
201 CL_ParseServerInfo
202 ==================
204 void CL_ParseServerInfo (void)
206 char *str;
207 int i;
208 int nummodels, numsounds;
209 char model_precache[MAX_MODELS][MAX_QPATH];
210 char sound_precache[MAX_SOUNDS][MAX_QPATH];
212 Con_DPrintf ("Serverinfo packet received.\n");
214 // wipe the client_state_t struct
216 CL_ClearState ();
218 // parse protocol version number
219 i = MSG_ReadLong ();
220 if (i != PROTOCOL_VERSION)
222 Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
223 return;
226 // parse maxclients
227 cl.maxclients = MSG_ReadByte ();
228 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
230 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
231 return;
233 cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
235 // parse gametype
236 cl.gametype = MSG_ReadByte ();
238 // parse signon message
239 str = MSG_ReadString ();
240 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
242 // seperate the printfs so the server message can have a color
243 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");
244 Con_Printf ("%c%s\n", 2, str);
247 // first we go through and touch all of the precache data that still
248 // happens to be in the cache, so precaching something else doesn't
249 // needlessly purge it
252 // precache models
253 memset (cl.model_precache, 0, sizeof(cl.model_precache));
254 for (nummodels=1 ; ; nummodels++)
256 str = MSG_ReadString ();
257 if (!str[0])
258 break;
259 if (nummodels==MAX_MODELS)
261 Con_Printf ("Server sent too many model precaches\n");
262 return;
264 strcpy (model_precache[nummodels], str);
265 Mod_TouchModel (str);
268 // precache sounds
269 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
270 for (numsounds=1 ; ; numsounds++)
272 str = MSG_ReadString ();
273 if (!str[0])
274 break;
275 if (numsounds==MAX_SOUNDS)
277 Con_Printf ("Server sent too many sound precaches\n");
278 return;
280 strcpy (sound_precache[numsounds], str);
281 S_TouchSound (str);
285 // now we try to load everything else until a cache allocation fails
288 for (i=1 ; i<nummodels ; i++)
290 cl.model_precache[i] = Mod_ForName (model_precache[i], false);
291 if (cl.model_precache[i] == NULL)
293 Con_Printf("Model %s not found\n", model_precache[i]);
294 return;
296 CL_KeepaliveMessage ();
299 S_BeginPrecaching ();
300 for (i=1 ; i<numsounds ; i++)
302 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
303 CL_KeepaliveMessage ();
305 S_EndPrecaching ();
308 // local state
309 cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
311 R_NewMap ();
313 Hunk_Check (); // make sure nothing is hurt
315 noclip_anglehack = false; // noclip is turned off at start
320 ==================
321 CL_ParseUpdate
323 Parse an entity update message from the server
324 If an entities model or origin changes from frame to frame, it must be
325 relinked. Other attributes can change without relinking.
326 ==================
328 int bitcounts[16];
330 void CL_ParseUpdate (int bits)
332 int i;
333 model_t *model;
334 int modnum;
335 qboolean forcelink;
336 entity_t *ent;
337 int num;
338 #ifdef GLQUAKE
339 int skin;
340 #endif
342 if (cls.signon == SIGNONS - 1)
343 { // first update is the final signon stage
344 cls.signon = SIGNONS;
345 CL_SignonReply ();
348 if (bits & U_MOREBITS)
350 i = MSG_ReadByte ();
351 bits |= (i<<8);
354 if (bits & U_LONGENTITY)
355 num = MSG_ReadShort ();
356 else
357 num = MSG_ReadByte ();
359 ent = CL_EntityNum (num);
361 for (i=0 ; i<16 ; i++)
362 if (bits&(1<<i))
363 bitcounts[i]++;
365 if (ent->msgtime != cl.mtime[1])
366 forcelink = true; // no previous frame to lerp from
367 else
368 forcelink = false;
370 ent->msgtime = cl.mtime[0];
372 if (bits & U_MODEL)
374 modnum = MSG_ReadByte ();
375 if (modnum >= MAX_MODELS)
376 Host_Error ("CL_ParseModel: bad modnum");
378 else
379 modnum = ent->baseline.modelindex;
381 model = cl.model_precache[modnum];
382 if (model != ent->model)
384 ent->model = model;
385 // automatic animation (torches, etc) can be either all together
386 // or randomized
387 if (model)
389 if (model->synctype == ST_RAND)
390 ent->syncbase = (float)(rand()&0x7fff) / 0x7fff;
391 else
392 ent->syncbase = 0.0;
394 else
395 forcelink = true; // hack to make null model players work
396 #ifdef GLQUAKE
397 if (num > 0 && num <= cl.maxclients)
398 R_TranslatePlayerSkin (num - 1);
399 #endif
402 if (bits & U_FRAME)
403 ent->frame = MSG_ReadByte ();
404 else
405 ent->frame = ent->baseline.frame;
407 if (bits & U_COLORMAP)
408 i = MSG_ReadByte();
409 else
410 i = ent->baseline.colormap;
411 if (!i)
412 ent->colormap = vid.colormap;
413 else
415 if (i > cl.maxclients)
416 Sys_Error ("i >= cl.maxclients");
417 ent->colormap = cl.scores[i-1].translations;
420 #ifdef GLQUAKE
421 if (bits & U_SKIN)
422 skin = MSG_ReadByte();
423 else
424 skin = ent->baseline.skin;
425 if (skin != ent->skinnum) {
426 ent->skinnum = skin;
427 if (num > 0 && num <= cl.maxclients)
428 R_TranslatePlayerSkin (num - 1);
431 #else
433 if (bits & U_SKIN)
434 ent->skinnum = MSG_ReadByte();
435 else
436 ent->skinnum = ent->baseline.skin;
437 #endif
439 if (bits & U_EFFECTS)
440 ent->effects = MSG_ReadByte();
441 else
442 ent->effects = ent->baseline.effects;
444 // shift the known values for interpolation
445 VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
446 VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
448 if (bits & U_ORIGIN1)
449 ent->msg_origins[0][0] = MSG_ReadCoord ();
450 else
451 ent->msg_origins[0][0] = ent->baseline.origin[0];
452 if (bits & U_ANGLE1)
453 ent->msg_angles[0][0] = MSG_ReadAngle();
454 else
455 ent->msg_angles[0][0] = ent->baseline.angles[0];
457 if (bits & U_ORIGIN2)
458 ent->msg_origins[0][1] = MSG_ReadCoord ();
459 else
460 ent->msg_origins[0][1] = ent->baseline.origin[1];
461 if (bits & U_ANGLE2)
462 ent->msg_angles[0][1] = MSG_ReadAngle();
463 else
464 ent->msg_angles[0][1] = ent->baseline.angles[1];
466 if (bits & U_ORIGIN3)
467 ent->msg_origins[0][2] = MSG_ReadCoord ();
468 else
469 ent->msg_origins[0][2] = ent->baseline.origin[2];
470 if (bits & U_ANGLE3)
471 ent->msg_angles[0][2] = MSG_ReadAngle();
472 else
473 ent->msg_angles[0][2] = ent->baseline.angles[2];
475 if ( bits & U_NOLERP )
476 ent->forcelink = true;
478 if ( forcelink )
479 { // didn't have an update last message
480 VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
481 VectorCopy (ent->msg_origins[0], ent->origin);
482 VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
483 VectorCopy (ent->msg_angles[0], ent->angles);
484 ent->forcelink = true;
489 ==================
490 CL_ParseBaseline
491 ==================
493 void CL_ParseBaseline (entity_t *ent)
495 int i;
497 ent->baseline.modelindex = MSG_ReadByte ();
498 ent->baseline.frame = MSG_ReadByte ();
499 ent->baseline.colormap = MSG_ReadByte();
500 ent->baseline.skin = MSG_ReadByte();
501 for (i=0 ; i<3 ; i++)
503 ent->baseline.origin[i] = MSG_ReadCoord ();
504 ent->baseline.angles[i] = MSG_ReadAngle ();
510 ==================
511 CL_ParseClientdata
513 Server information pertaining to this client only
514 ==================
516 void CL_ParseClientdata (int bits)
518 int i, j;
520 if (bits & SU_VIEWHEIGHT)
521 cl.viewheight = MSG_ReadChar ();
522 else
523 cl.viewheight = DEFAULT_VIEWHEIGHT;
525 if (bits & SU_IDEALPITCH)
526 cl.idealpitch = MSG_ReadChar ();
527 else
528 cl.idealpitch = 0;
530 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
531 for (i=0 ; i<3 ; i++)
533 if (bits & (SU_PUNCH1<<i) )
534 cl.punchangle[i] = MSG_ReadChar();
535 else
536 cl.punchangle[i] = 0;
537 if (bits & (SU_VELOCITY1<<i) )
538 cl.mvelocity[0][i] = MSG_ReadChar()*16;
539 else
540 cl.mvelocity[0][i] = 0;
543 // [always sent] if (bits & SU_ITEMS)
544 i = MSG_ReadLong ();
546 if (cl.items != i)
547 { // set flash times
548 Sbar_Changed ();
549 for (j=0 ; j<32 ; j++)
550 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
551 cl.item_gettime[j] = cl.time;
552 cl.items = i;
555 cl.onground = (bits & SU_ONGROUND) != 0;
556 cl.inwater = (bits & SU_INWATER) != 0;
558 if (bits & SU_WEAPONFRAME)
559 cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
560 else
561 cl.stats[STAT_WEAPONFRAME] = 0;
563 if (bits & SU_ARMOR)
564 i = MSG_ReadByte ();
565 else
566 i = 0;
567 if (cl.stats[STAT_ARMOR] != i)
569 cl.stats[STAT_ARMOR] = i;
570 Sbar_Changed ();
573 if (bits & SU_WEAPON)
574 i = MSG_ReadByte ();
575 else
576 i = 0;
577 if (cl.stats[STAT_WEAPON] != i)
579 cl.stats[STAT_WEAPON] = i;
580 Sbar_Changed ();
583 i = MSG_ReadShort ();
584 if (cl.stats[STAT_HEALTH] != i)
586 cl.stats[STAT_HEALTH] = i;
587 Sbar_Changed ();
590 i = MSG_ReadByte ();
591 if (cl.stats[STAT_AMMO] != i)
593 cl.stats[STAT_AMMO] = i;
594 Sbar_Changed ();
597 for (i=0 ; i<4 ; i++)
599 j = MSG_ReadByte ();
600 if (cl.stats[STAT_SHELLS+i] != j)
602 cl.stats[STAT_SHELLS+i] = j;
603 Sbar_Changed ();
607 i = MSG_ReadByte ();
609 if (standard_quake)
611 if (cl.stats[STAT_ACTIVEWEAPON] != i)
613 cl.stats[STAT_ACTIVEWEAPON] = i;
614 Sbar_Changed ();
617 else
619 if (cl.stats[STAT_ACTIVEWEAPON] != (1<<i))
621 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
622 Sbar_Changed ();
628 =====================
629 CL_NewTranslation
630 =====================
632 void CL_NewTranslation (int slot)
634 int i, j;
635 int top, bottom;
636 byte *dest, *source;
638 if (slot > cl.maxclients)
639 Sys_Error ("CL_NewTranslation: slot > cl.maxclients");
640 dest = cl.scores[slot].translations;
641 source = vid.colormap;
642 memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations));
643 top = cl.scores[slot].colors & 0xf0;
644 bottom = (cl.scores[slot].colors &15)<<4;
645 #ifdef GLQUAKE
646 R_TranslatePlayerSkin (slot);
647 #endif
649 for (i=0 ; i<VID_GRADES ; i++, dest += 256, source+=256)
651 if (top < 128) // the artists made some backwards ranges. sigh.
652 memcpy (dest + TOP_RANGE, source + top, 16);
653 else
654 for (j=0 ; j<16 ; j++)
655 dest[TOP_RANGE+j] = source[top+15-j];
657 if (bottom < 128)
658 memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
659 else
660 for (j=0 ; j<16 ; j++)
661 dest[BOTTOM_RANGE+j] = source[bottom+15-j];
666 =====================
667 CL_ParseStatic
668 =====================
670 void CL_ParseStatic (void)
672 entity_t *ent;
673 int i;
675 i = cl.num_statics;
676 if (i >= MAX_STATIC_ENTITIES)
677 Host_Error ("Too many static entities");
678 ent = &cl_static_entities[i];
679 cl.num_statics++;
680 CL_ParseBaseline (ent);
682 // copy it to the current state
683 ent->model = cl.model_precache[ent->baseline.modelindex];
684 ent->frame = ent->baseline.frame;
685 ent->colormap = vid.colormap;
686 ent->skinnum = ent->baseline.skin;
687 ent->effects = ent->baseline.effects;
689 VectorCopy (ent->baseline.origin, ent->origin);
690 VectorCopy (ent->baseline.angles, ent->angles);
691 R_AddEfrags (ent);
695 ===================
696 CL_ParseStaticSound
697 ===================
699 void CL_ParseStaticSound (void)
701 vec3_t org;
702 int sound_num, vol, atten;
703 int i;
705 for (i=0 ; i<3 ; i++)
706 org[i] = MSG_ReadCoord ();
707 sound_num = MSG_ReadByte ();
708 vol = MSG_ReadByte ();
709 atten = MSG_ReadByte ();
711 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
715 #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
718 =====================
719 CL_ParseServerMessage
720 =====================
722 void CL_ParseServerMessage (void)
724 int cmd;
725 int i;
728 // if recording demos, copy the message out
730 if (cl_shownet.value == 1)
731 Con_Printf ("%i ",net_message.cursize);
732 else if (cl_shownet.value == 2)
733 Con_Printf ("------------------\n");
735 cl.onground = false; // unless the server says otherwise
737 // parse the message
739 MSG_BeginReading ();
741 while (1)
743 if (msg_badread)
744 Host_Error ("CL_ParseServerMessage: Bad server message");
746 cmd = MSG_ReadByte ();
748 if (cmd == -1)
750 SHOWNET("END OF MESSAGE");
751 return; // end of message
754 // if the high bit of the command byte is set, it is a fast update
755 if (cmd & 128)
757 SHOWNET("fast update");
758 CL_ParseUpdate (cmd&127);
759 continue;
762 SHOWNET(svc_strings[cmd]);
764 // other commands
765 switch (cmd)
767 default:
768 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
769 break;
771 case svc_nop:
772 // Con_Printf ("svc_nop\n");
773 break;
775 case svc_time:
776 cl.mtime[1] = cl.mtime[0];
777 cl.mtime[0] = MSG_ReadFloat ();
778 break;
780 case svc_clientdata:
781 i = MSG_ReadShort ();
782 CL_ParseClientdata (i);
783 break;
785 case svc_version:
786 i = MSG_ReadLong ();
787 if (i != PROTOCOL_VERSION)
788 Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
789 break;
791 case svc_disconnect:
792 Host_EndGame ("Server disconnected\n");
794 case svc_print:
795 Con_Printf ("%s", MSG_ReadString ());
796 break;
798 case svc_centerprint:
799 SCR_CenterPrint (MSG_ReadString ());
800 break;
802 case svc_stufftext:
803 Cbuf_AddText (MSG_ReadString ());
804 break;
806 case svc_damage:
807 V_ParseDamage ();
808 break;
810 case svc_serverinfo:
811 CL_ParseServerInfo ();
812 vid.recalc_refdef = true; // leave intermission full screen
813 break;
815 case svc_setangle:
816 for (i=0 ; i<3 ; i++)
817 cl.viewangles[i] = MSG_ReadAngle ();
818 break;
820 case svc_setview:
821 cl.viewentity = MSG_ReadShort ();
822 break;
824 case svc_lightstyle:
825 i = MSG_ReadByte ();
826 if (i >= MAX_LIGHTSTYLES)
827 Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
828 Q_strcpy (cl_lightstyle[i].map, MSG_ReadString());
829 cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
830 break;
832 case svc_sound:
833 CL_ParseStartSoundPacket();
834 break;
836 case svc_stopsound:
837 i = MSG_ReadShort();
838 S_StopSound(i>>3, i&7);
839 break;
841 case svc_updatename:
842 Sbar_Changed ();
843 i = MSG_ReadByte ();
844 if (i >= cl.maxclients)
845 Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
846 strcpy (cl.scores[i].name, MSG_ReadString ());
847 break;
849 case svc_updatefrags:
850 Sbar_Changed ();
851 i = MSG_ReadByte ();
852 if (i >= cl.maxclients)
853 Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
854 cl.scores[i].frags = MSG_ReadShort ();
855 break;
857 case svc_updatecolors:
858 Sbar_Changed ();
859 i = MSG_ReadByte ();
860 if (i >= cl.maxclients)
861 Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
862 cl.scores[i].colors = MSG_ReadByte ();
863 CL_NewTranslation (i);
864 break;
866 case svc_particle:
867 R_ParseParticleEffect ();
868 break;
870 case svc_spawnbaseline:
871 i = MSG_ReadShort ();
872 // must use CL_EntityNum() to force cl.num_entities up
873 CL_ParseBaseline (CL_EntityNum(i));
874 break;
875 case svc_spawnstatic:
876 CL_ParseStatic ();
877 break;
878 case svc_temp_entity:
879 CL_ParseTEnt ();
880 break;
882 case svc_setpause:
884 cl.paused = MSG_ReadByte ();
886 if (cl.paused)
888 CDAudio_Pause ();
889 #ifdef _WIN32
890 VID_HandlePause (true);
891 #endif
893 else
895 CDAudio_Resume ();
896 #ifdef _WIN32
897 VID_HandlePause (false);
898 #endif
901 break;
903 case svc_signonnum:
904 i = MSG_ReadByte ();
905 if (i <= cls.signon)
906 Host_Error ("Received signon %i when at %i", i, cls.signon);
907 cls.signon = i;
908 CL_SignonReply ();
909 break;
911 case svc_killedmonster:
912 cl.stats[STAT_MONSTERS]++;
913 break;
915 case svc_foundsecret:
916 cl.stats[STAT_SECRETS]++;
917 break;
919 case svc_updatestat:
920 i = MSG_ReadByte ();
921 if (i < 0 || i >= MAX_CL_STATS)
922 Sys_Error ("svc_updatestat: %i is invalid", i);
923 cl.stats[i] = MSG_ReadLong ();;
924 break;
926 case svc_spawnstaticsound:
927 CL_ParseStaticSound ();
928 break;
930 case svc_cdtrack:
931 cl.cdtrack = MSG_ReadByte ();
932 cl.looptrack = MSG_ReadByte ();
933 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
934 CDAudio_Play ((byte)cls.forcetrack, true);
935 else
936 CDAudio_Play ((byte)cl.cdtrack, true);
937 break;
939 case svc_intermission:
940 cl.intermission = 1;
941 cl.completed_time = cl.time;
942 vid.recalc_refdef = true; // go to full screen
943 break;
945 case svc_finale:
946 cl.intermission = 2;
947 cl.completed_time = cl.time;
948 vid.recalc_refdef = true; // go to full screen
949 SCR_CenterPrint (MSG_ReadString ());
950 break;
952 case svc_cutscene:
953 cl.intermission = 3;
954 cl.completed_time = cl.time;
955 vid.recalc_refdef = true; // go to full screen
956 SCR_CenterPrint (MSG_ReadString ());
957 break;
959 case svc_sellscreen:
960 Cmd_ExecuteString ("help", src_command);
961 break;