|
|
1.1 root 1: // cl_parse.c -- parse a message received from the server
2:
3: #include "quakedef.h"
4:
5: char *svc_strings[] =
6: {
7: "svc_bad",
8: "svc_nop",
9: "svc_disconnect",
10: "svc_updatestat",
11: "svc_version", // [long] server version
12: "svc_setview", // [short] entity number
13: "svc_sound", // <see code>
14: "svc_time", // [float] server time
15: "svc_print", // [string] null terminated string
16: "svc_stufftext", // [string] stuffed into client's console buffer
17: // the string should be \n terminated
18: "svc_setangle", // [vec3] set the view angle to this absolute value
19:
20: "svc_serverinfo", // [long] version
21: // [string] signon string
22: // [string]..[0]model cache [string]...[0]sounds cache
23: // [string]..[0]item cache
24: "svc_lightstyle", // [byte] [string]
25: "svc_updatename", // [byte] [string]
26: "svc_updatefrags", // [byte] [short]
27: "svc_clientdata", // <shortbits + data>
28: "svc_stopsound", // <see code>
29: "svc_updatecolors", // [byte] [byte]
30: "svc_particle", // [vec3] <variable>
31: "svc_damage", // [byte] impact [byte] blood [vec3] from
32:
33: "svc_spawnstatic",
34: "OBSOLETE svc_spawnbinary",
35: "svc_spawnbaseline",
36:
37: "svc_temp_entity", // <variable>
38: "svc_setpause",
39: "svc_signonnum",
40: "svc_centerprint",
41: "svc_killedmonster",
42: "svc_foundsecret",
43: "svc_spawnstaticsound",
1.1.1.3 ! root 44: "svc_intermission",
! 45: "svc_finale", // [string] music [string] text
! 46: "svc_cdtrack", // [byte] track [byte] looptrack
! 47: "svc_sellscreen",
! 48: "svc_cutscene"
1.1 root 49: };
50:
51: //=============================================================================
52:
53: /*
54: ===============
55: CL_EntityNum
56:
57: This error checks and tracks the total number of entities
58: ===============
59: */
60: entity_t *CL_EntityNum (int num)
61: {
62: if (num >= cl.num_entities)
63: {
64: if (num >= MAX_EDICTS)
65: Host_Error ("CL_EntityNum: %i is an invalid number",num);
66: while (cl.num_entities<=num)
67: {
68: cl_entities[cl.num_entities].colormap = vid.colormap;
69: cl.num_entities++;
70: }
71: }
72:
73: return &cl_entities[num];
74: }
75:
76:
77: /*
78: ==================
79: CL_ParseStartSoundPacket
80: ==================
81: */
82: void CL_ParseStartSoundPacket(void)
83: {
84: vec3_t pos;
85: int channel, ent;
86: int sound_num;
87: int volume;
88: int field_mask;
89: float attenuation;
90: int i;
91:
92: field_mask = MSG_ReadByte();
93:
94: if (field_mask & SND_VOLUME)
95: volume = MSG_ReadByte ();
96: else
97: volume = DEFAULT_SOUND_PACKET_VOLUME;
98:
99: if (field_mask & SND_ATTENUATION)
100: attenuation = MSG_ReadByte () / 64.0;
101: else
102: attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
103:
104: channel = MSG_ReadShort ();
105: sound_num = MSG_ReadByte ();
106:
107: ent = channel >> 3;
108: channel &= 7;
109:
110: if (ent > MAX_EDICTS)
111: Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
112:
113: for (i=0 ; i<3 ; i++)
114: pos[i] = MSG_ReadCoord ();
115:
116: S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
117: }
118:
119: /*
120: ==================
121: CL_KeepaliveMessage
122:
123: When the client is taking a long time to load stuff, send keepalive messages
124: so the server doesn't disconnect.
125: ==================
126: */
127: void CL_KeepaliveMessage (void)
128: {
129: float time;
130: static float lastmsg;
131: int ret;
132: sizebuf_t old;
133: byte olddata[8192];
134:
135: if (sv.active)
136: return; // no need if server is local
137: if (cls.demoplayback)
138: return;
139:
140: // read messages from server, should just be nops
141: old = net_message;
142: memcpy (olddata, net_message.data, net_message.cursize);
143:
144: do
145: {
146: ret = CL_GetMessage ();
147: switch (ret)
148: {
149: default:
150: Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
151: case 0:
152: break; // nothing waiting
153: case 1:
154: Host_Error ("CL_KeepaliveMessage: received a message");
155: break;
156: case 2:
157: if (MSG_ReadByte() != svc_nop)
158: Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
159: break;
160: }
161: } while (ret);
162:
163: net_message = old;
164: memcpy (net_message.data, olddata, net_message.cursize);
165:
166: // check time
167: time = Sys_FloatTime ();
168: if (time - lastmsg < 5)
169: return;
170: lastmsg = time;
171:
172: // write out a nop
173: Con_Printf ("--> client to server keepalive\n");
174:
175: MSG_WriteByte (&cls.message, clc_nop);
176: NET_SendMessage (cls.netcon, &cls.message);
177: SZ_Clear (&cls.message);
178: }
179:
180: /*
181: ==================
182: CL_ParseServerInfo
183: ==================
184: */
185: void CL_ParseServerInfo (void)
186: {
187: char *str;
188: int i;
189: int nummodels, numsounds;
190: char model_precache[MAX_MODELS][MAX_QPATH];
191: char sound_precache[MAX_SOUNDS][MAX_QPATH];
192:
193: Con_DPrintf ("Serverinfo packet received.\n");
194: //
195: // wipe the client_state_t struct
196: //
197: CL_ClearState ();
198:
199: // parse protocol version number
200: i = MSG_ReadLong ();
201: if (i != PROTOCOL_VERSION)
1.1.1.3 ! root 202: {
! 203: Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
! 204: return;
! 205: }
1.1 root 206:
207: // parse maxclients
208: cl.maxclients = MSG_ReadByte ();
1.1.1.3 ! root 209: if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
! 210: {
! 211: Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
! 212: return;
! 213: }
1.1 root 214: cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
215:
216: // parse gametype
217: cl.gametype = MSG_ReadByte ();
218:
219: // parse signon message
220: str = MSG_ReadString ();
221: strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
222:
223: // seperate the printfs so the server message can have a color
224: 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");
225: Con_Printf ("%c%s\n", 2, str);
226:
227: //
228: // first we go through and touch all of the precache data that still
229: // happens to be in the cache, so precaching something else doesn't
230: // needlessly purge it
231: //
232:
233: // precache models
234: memset (cl.model_precache, 0, sizeof(cl.model_precache));
235: for (nummodels=1 ; ; nummodels++)
236: {
237: str = MSG_ReadString ();
238: if (!str[0])
239: break;
240: if (nummodels==MAX_MODELS)
1.1.1.3 ! root 241: {
! 242: Con_Printf ("Server sent too many model precaches\n");
! 243: return;
! 244: }
1.1 root 245: strcpy (model_precache[nummodels], str);
246: Mod_TouchModel (str);
247: }
248:
249: // precache sounds
250: memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
251: for (numsounds=1 ; ; numsounds++)
252: {
253: str = MSG_ReadString ();
254: if (!str[0])
255: break;
256: if (numsounds==MAX_SOUNDS)
1.1.1.3 ! root 257: {
! 258: Con_Printf ("Server sent too many sound precaches\n");
! 259: return;
! 260: }
1.1 root 261: strcpy (sound_precache[numsounds], str);
262: S_TouchSound (str);
263: }
264:
265: //
266: // now we try to load everything else until a cache allocation fails
267: //
268: for (i=1 ; i<nummodels ; i++)
269: {
1.1.1.3 ! root 270: cl.model_precache[i] = Mod_ForName (model_precache[i], false);
! 271: if (cl.model_precache[i] == NULL)
! 272: {
! 273: Con_Printf("Model %s not found\n", model_precache[i]);
! 274: return;
! 275: }
1.1 root 276: CL_KeepaliveMessage ();
277: }
278:
1.1.1.3 ! root 279: S_BeginPrecaching ();
1.1 root 280: for (i=1 ; i<numsounds ; i++)
281: {
282: cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
283: CL_KeepaliveMessage ();
284: }
1.1.1.3 ! root 285: S_EndPrecaching ();
1.1 root 286:
287:
288: // local state
289: cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
290:
291: R_NewMap ();
292:
293: Hunk_Check (); // make sure nothing is hurt
294:
295: noclip_anglehack = false; // noclip is turned off at start
296: }
297:
298:
299: /*
300: ==================
301: CL_ParseUpdate
302:
303: Parse an entity update message from the server
304: If an entities model or origin changes from frame to frame, it must be
305: relinked. Other attributes can change without relinking.
306: ==================
307: */
308: int bitcounts[16];
309:
310: void CL_ParseUpdate (int bits)
311: {
312: int i;
313: model_t *model;
314: int modnum;
315: qboolean forcelink;
316: entity_t *ent;
317: int num;
318:
319: if (cls.signon == SIGNONS - 1)
320: { // first update is the final signon stage
321: cls.signon = SIGNONS;
322: CL_SignonReply ();
323: }
324:
325: if (bits & U_MOREBITS)
326: {
327: i = MSG_ReadByte ();
328: bits |= (i<<8);
329: }
330:
331: if (bits & U_LONGENTITY)
332: num = MSG_ReadShort ();
333: else
334: num = MSG_ReadByte ();
335:
336: ent = CL_EntityNum (num);
337:
338: for (i=0 ; i<16 ; i++)
339: if (bits&(1<<i))
340: bitcounts[i]++;
341:
342: if (ent->msgtime != cl.mtime[1])
343: forcelink = true; // no previous frame to lerp from
344: else
345: forcelink = false;
346:
347: ent->msgtime = cl.mtime[0];
348:
349: if (bits & U_MODEL)
350: {
351: modnum = MSG_ReadByte ();
352: if (modnum >= MAX_MODELS)
353: Host_Error ("CL_ParseModel: bad modnum");
354: }
355: else
356: modnum = ent->baseline.modelindex;
357:
358: model = cl.model_precache[modnum];
359: if (model != ent->model)
360: {
361: ent->model = model;
362: // automatic animation (torches, etc) can be either all together
363: // or randomized
364: if (model)
365: {
366: if (model->synctype == ST_RAND)
367: ent->syncbase = (float)(rand()&0x7fff) / 0x7fff;
368: else
369: ent->syncbase = 0.0;
370: }
371: else
372: forcelink = true; // hack to make null model players work
1.1.1.3 ! root 373: #ifdef GLQUAKE
! 374: if (num > 0 && num <= cl.maxclients)
! 375: R_TranslatePlayerSkin (num - 1);
! 376: #endif
1.1 root 377: }
378:
379: if (bits & U_FRAME)
380: ent->frame = MSG_ReadByte ();
381: else
382: ent->frame = ent->baseline.frame;
383:
384: if (bits & U_COLORMAP)
385: i = MSG_ReadByte();
386: else
387: i = ent->baseline.colormap;
388: if (!i)
389: ent->colormap = vid.colormap;
390: else
391: {
392: if (i > cl.maxclients)
393: Sys_Error ("i >= cl.maxclients");
394: ent->colormap = cl.scores[i-1].translations;
395: }
396:
397: if (bits & U_SKIN)
398: ent->skinnum = MSG_ReadByte();
399: else
400: ent->skinnum = ent->baseline.skin;
401:
402: if (bits & U_EFFECTS)
403: ent->effects = MSG_ReadByte();
404: else
405: ent->effects = ent->baseline.effects;
406:
407: // shift the known values for interpolation
408: VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
409: VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
410:
411: if (bits & U_ORIGIN1)
412: ent->msg_origins[0][0] = MSG_ReadCoord ();
413: else
414: ent->msg_origins[0][0] = ent->baseline.origin[0];
415: if (bits & U_ANGLE1)
416: ent->msg_angles[0][0] = MSG_ReadAngle();
417: else
418: ent->msg_angles[0][0] = ent->baseline.angles[0];
419:
420: if (bits & U_ORIGIN2)
421: ent->msg_origins[0][1] = MSG_ReadCoord ();
422: else
423: ent->msg_origins[0][1] = ent->baseline.origin[1];
424: if (bits & U_ANGLE2)
425: ent->msg_angles[0][1] = MSG_ReadAngle();
426: else
427: ent->msg_angles[0][1] = ent->baseline.angles[1];
428:
429: if (bits & U_ORIGIN3)
430: ent->msg_origins[0][2] = MSG_ReadCoord ();
431: else
432: ent->msg_origins[0][2] = ent->baseline.origin[2];
433: if (bits & U_ANGLE3)
434: ent->msg_angles[0][2] = MSG_ReadAngle();
435: else
436: ent->msg_angles[0][2] = ent->baseline.angles[2];
437:
438: if ( bits & U_NOLERP )
439: ent->forcelink = true;
440:
441: if ( forcelink )
442: { // didn't have an update last message
443: VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
444: VectorCopy (ent->msg_origins[0], ent->origin);
445: VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
446: VectorCopy (ent->msg_angles[0], ent->angles);
447: ent->forcelink = true;
448: }
449: }
450:
451: /*
452: ==================
453: CL_ParseBaseline
454: ==================
455: */
456: void CL_ParseBaseline (entity_t *ent)
457: {
458: int i;
459:
460: ent->baseline.modelindex = MSG_ReadByte ();
461: ent->baseline.frame = MSG_ReadByte ();
462: ent->baseline.colormap = MSG_ReadByte();
463: ent->baseline.skin = MSG_ReadByte();
464: for (i=0 ; i<3 ; i++)
465: {
466: ent->baseline.origin[i] = MSG_ReadCoord ();
467: ent->baseline.angles[i] = MSG_ReadAngle ();
468: }
469: }
470:
471:
472: /*
473: ==================
474: CL_ParseClientdata
475:
476: Server information pertaining to this client only
477: ==================
478: */
479: void CL_ParseClientdata (int bits)
480: {
481: int i, j;
482:
483: if (bits & SU_VIEWHEIGHT)
484: cl.viewheight = MSG_ReadChar ();
485: else
486: cl.viewheight = DEFAULT_VIEWHEIGHT;
487:
488: if (bits & SU_IDEALPITCH)
489: cl.idealpitch = MSG_ReadChar ();
490: else
491: cl.idealpitch = 0;
492:
493: VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
494: for (i=0 ; i<3 ; i++)
495: {
496: if (bits & (SU_PUNCH1<<i) )
497: cl.punchangle[i] = MSG_ReadChar();
498: else
499: cl.punchangle[i] = 0;
500: if (bits & (SU_VELOCITY1<<i) )
501: cl.mvelocity[0][i] = MSG_ReadChar()*16;
502: else
503: cl.mvelocity[0][i] = 0;
504: }
505:
1.1.1.3 ! root 506: // [always sent] if (bits & SU_ITEMS)
1.1 root 507: i = MSG_ReadLong ();
1.1.1.3 ! root 508:
1.1 root 509: if (cl.items != i)
510: { // set flash times
511: Sbar_Changed ();
512: for (j=0 ; j<32 ; j++)
513: if ( (i & (1<<j)) && !(cl.items & (1<<j)))
514: cl.item_gettime[j] = cl.time;
515: cl.items = i;
516: }
517:
518: cl.onground = (bits & SU_ONGROUND) != 0;
519: cl.inwater = (bits & SU_INWATER) != 0;
520:
521: if (bits & SU_WEAPONFRAME)
522: cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
523: else
524: cl.stats[STAT_WEAPONFRAME] = 0;
525:
526: if (bits & SU_ARMOR)
527: i = MSG_ReadByte ();
528: else
529: i = 0;
530: if (cl.stats[STAT_ARMOR] != i)
531: {
532: cl.stats[STAT_ARMOR] = i;
533: Sbar_Changed ();
534: }
535:
536: if (bits & SU_WEAPON)
537: i = MSG_ReadByte ();
538: else
539: i = 0;
540: if (cl.stats[STAT_WEAPON] != i)
541: {
542: cl.stats[STAT_WEAPON] = i;
543: Sbar_Changed ();
544: }
545:
546: i = MSG_ReadShort ();
547: if (cl.stats[STAT_HEALTH] != i)
548: {
549: cl.stats[STAT_HEALTH] = i;
550: Sbar_Changed ();
551: }
552:
553: i = MSG_ReadByte ();
554: if (cl.stats[STAT_AMMO] != i)
555: {
556: cl.stats[STAT_AMMO] = i;
557: Sbar_Changed ();
558: }
559:
560: for (i=0 ; i<4 ; i++)
561: {
562: j = MSG_ReadByte ();
563: if (cl.stats[STAT_SHELLS+i] != j)
564: {
565: cl.stats[STAT_SHELLS+i] = j;
566: Sbar_Changed ();
567: }
568: }
569:
570: i = MSG_ReadByte ();
1.1.1.3 ! root 571:
! 572: if (standard_quake)
1.1 root 573: {
1.1.1.3 ! root 574: if (cl.stats[STAT_ACTIVEWEAPON] != i)
! 575: {
! 576: cl.stats[STAT_ACTIVEWEAPON] = i;
! 577: Sbar_Changed ();
! 578: }
! 579: }
! 580: else
! 581: {
! 582: if (cl.stats[STAT_ACTIVEWEAPON] != (1<<i))
! 583: {
! 584: cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
! 585: Sbar_Changed ();
! 586: }
1.1 root 587: }
588: }
589:
590: /*
591: =====================
592: CL_NewTranslation
593: =====================
594: */
595: void CL_NewTranslation (int slot)
596: {
597: int i, j;
598: int top, bottom;
599: byte *dest, *source;
600:
601: if (slot > cl.maxclients)
602: Sys_Error ("CL_NewTranslation: slot > cl.maxclients");
603: dest = cl.scores[slot].translations;
604: source = vid.colormap;
605: memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations));
606: top = cl.scores[slot].colors & 0xf0;
607: bottom = (cl.scores[slot].colors &15)<<4;
1.1.1.3 ! root 608: #ifdef GLQUAKE
! 609: R_TranslatePlayerSkin (slot);
! 610: #endif
1.1 root 611:
612: for (i=0 ; i<VID_GRADES ; i++, dest += 256, source+=256)
613: {
614: if (top < 128) // the artists made some backwards ranges. sigh.
615: memcpy (dest + TOP_RANGE, source + top, 16);
616: else
617: for (j=0 ; j<16 ; j++)
618: dest[TOP_RANGE+j] = source[top+15-j];
619:
620: if (bottom < 128)
621: memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
622: else
623: for (j=0 ; j<16 ; j++)
624: dest[BOTTOM_RANGE+j] = source[bottom+15-j];
625: }
626: }
627:
628: /*
629: =====================
630: CL_ParseStatic
631: =====================
632: */
633: void CL_ParseStatic (void)
634: {
635: entity_t *ent;
636: int i;
637:
638: i = cl.num_statics;
639: if (i >= MAX_STATIC_ENTITIES)
640: Host_Error ("Too many static entities");
641: ent = &cl_static_entities[i];
642: cl.num_statics++;
643: CL_ParseBaseline (ent);
644:
645: // copy it to the current state
646: ent->model = cl.model_precache[ent->baseline.modelindex];
647: ent->frame = ent->baseline.frame;
648: ent->colormap = vid.colormap;
649: ent->skinnum = ent->baseline.skin;
650: ent->effects = ent->baseline.effects;
651:
652: VectorCopy (ent->baseline.origin, ent->origin);
653: VectorCopy (ent->baseline.angles, ent->angles);
654: R_AddEfrags (ent);
655: }
656:
657: /*
658: ===================
659: CL_ParseStaticSound
660: ===================
661: */
662: void CL_ParseStaticSound (void)
663: {
664: vec3_t org;
665: int sound_num, vol, atten;
666: int i;
667:
668: for (i=0 ; i<3 ; i++)
669: org[i] = MSG_ReadCoord ();
670: sound_num = MSG_ReadByte ();
671: vol = MSG_ReadByte ();
672: atten = MSG_ReadByte ();
673:
674: S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
675: }
676:
677:
678: #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
679:
680: /*
681: =====================
682: CL_ParseServerMessage
683: =====================
684: */
685: void CL_ParseServerMessage (void)
686: {
687: int cmd;
688: int i;
689:
690: //
691: // if recording demos, copy the message out
692: //
693: if (cl_shownet.value == 1)
694: Con_Printf ("%i ",net_message.cursize);
695: else if (cl_shownet.value == 2)
696: Con_Printf ("------------------\n");
697:
698: cl.onground = false; // unless the server says otherwise
699: //
700: // parse the message
701: //
702: MSG_BeginReading ();
703:
704: while (1)
705: {
706: if (msg_badread)
707: Host_Error ("CL_ParseServerMessage: Bad server message");
708:
709: cmd = MSG_ReadByte ();
710:
711: if (cmd == -1)
712: {
713: SHOWNET("END OF MESSAGE");
714: return; // end of message
715: }
716:
717: // if the high bit of the command byte is set, it is a fast update
718: if (cmd & 128)
719: {
720: SHOWNET("fast update");
721: CL_ParseUpdate (cmd&127);
722: continue;
723: }
724:
725: SHOWNET(svc_strings[cmd]);
726:
727: // other commands
728: switch (cmd)
729: {
730: default:
731: Host_Error ("CL_ParseServerMessage: Illegible server message\n");
732: break;
733:
734: case svc_nop:
735: // Con_Printf ("svc_nop\n");
736: break;
737:
738: case svc_time:
739: cl.mtime[1] = cl.mtime[0];
740: cl.mtime[0] = MSG_ReadFloat ();
741: break;
742:
743: case svc_clientdata:
744: i = MSG_ReadShort ();
745: CL_ParseClientdata (i);
746: break;
747:
748: case svc_version:
749: i = MSG_ReadLong ();
750: if (i != PROTOCOL_VERSION)
751: Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
752: break;
753:
754: case svc_disconnect:
755: Host_EndGame ("Server disconnected\n");
756:
757: case svc_print:
1.1.1.3 ! root 758: Con_Printf ("%s", MSG_ReadString ());
1.1 root 759: break;
760:
761: case svc_centerprint:
762: SCR_CenterPrint (MSG_ReadString ());
763: break;
764:
765: case svc_stufftext:
766: Cbuf_AddText (MSG_ReadString ());
767: break;
768:
769: case svc_damage:
770: V_ParseDamage ();
771: break;
772:
773: case svc_serverinfo:
774: CL_ParseServerInfo ();
775: vid.recalc_refdef = true; // leave intermission full screen
776: break;
777:
778: case svc_setangle:
779: for (i=0 ; i<3 ; i++)
780: cl.viewangles[i] = MSG_ReadAngle ();
781: break;
782:
783: case svc_setview:
784: cl.viewentity = MSG_ReadShort ();
785: break;
786:
787: case svc_lightstyle:
788: i = MSG_ReadByte ();
789: if (i >= MAX_LIGHTSTYLES)
790: Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
791: Q_strcpy (cl_lightstyle[i].map, MSG_ReadString());
792: cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
793: break;
794:
795: case svc_sound:
796: CL_ParseStartSoundPacket();
797: break;
798:
799: case svc_stopsound:
800: i = MSG_ReadShort();
801: S_StopSound(i>>3, i&7);
802: break;
803:
804: case svc_updatename:
805: Sbar_Changed ();
806: i = MSG_ReadByte ();
807: if (i >= cl.maxclients)
808: Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
809: strcpy (cl.scores[i].name, MSG_ReadString ());
810: break;
811:
812: case svc_updatefrags:
813: Sbar_Changed ();
814: i = MSG_ReadByte ();
815: if (i >= cl.maxclients)
816: Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
817: cl.scores[i].frags = MSG_ReadShort ();
818: break;
819:
820: case svc_updatecolors:
821: Sbar_Changed ();
822: i = MSG_ReadByte ();
823: if (i >= cl.maxclients)
824: Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
825: cl.scores[i].colors = MSG_ReadByte ();
826: CL_NewTranslation (i);
827: break;
828:
829: case svc_particle:
830: R_ParseParticleEffect ();
831: break;
832:
833: case svc_spawnbaseline:
834: i = MSG_ReadShort ();
835: // must use CL_EntityNum() to force cl.num_entities up
836: CL_ParseBaseline (CL_EntityNum(i));
837: break;
838: case svc_spawnstatic:
839: CL_ParseStatic ();
840: break;
841: case svc_temp_entity:
842: CL_ParseTEnt ();
843: break;
844:
845: case svc_setpause:
1.1.1.3 ! root 846: {
! 847: cl.paused = MSG_ReadByte ();
! 848:
! 849: if (cl.paused)
! 850: {
! 851: CDAudio_Pause ();
! 852: #ifdef _WIN32
! 853: VID_HandlePause (true);
! 854: #endif
! 855: }
! 856: else
! 857: {
! 858: CDAudio_Resume ();
! 859: #ifdef _WIN32
! 860: VID_HandlePause (false);
! 861: #endif
! 862: }
! 863: }
1.1 root 864: break;
865:
866: case svc_signonnum:
867: i = MSG_ReadByte ();
868: if (i <= cls.signon)
869: Host_Error ("Received signon %i when at %i", i, cls.signon);
870: cls.signon = i;
871: CL_SignonReply ();
872: break;
873:
874: case svc_killedmonster:
875: cl.stats[STAT_MONSTERS]++;
876: break;
877:
878: case svc_foundsecret:
879: cl.stats[STAT_SECRETS]++;
880: break;
881:
882: case svc_updatestat:
883: i = MSG_ReadByte ();
884: if (i < 0 || i >= MAX_CL_STATS)
885: Sys_Error ("svc_updatestat: %i is invalid", i);
886: cl.stats[i] = MSG_ReadLong ();;
887: break;
888:
889: case svc_spawnstaticsound:
890: CL_ParseStaticSound ();
891: break;
892:
893: case svc_cdtrack:
894: cl.cdtrack = MSG_ReadByte ();
895: cl.looptrack = MSG_ReadByte ();
896: if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
897: CDAudio_Play ((byte)cls.forcetrack, true);
898: else
899: CDAudio_Play ((byte)cl.cdtrack, true);
900: break;
901:
902: case svc_intermission:
903: cl.intermission = 1;
904: cl.completed_time = cl.time;
905: vid.recalc_refdef = true; // go to full screen
906: break;
907:
908: case svc_finale:
909: cl.intermission = 2;
910: cl.completed_time = cl.time;
911: vid.recalc_refdef = true; // go to full screen
912: SCR_CenterPrint (MSG_ReadString ());
913: break;
1.1.1.3 ! root 914:
! 915: case svc_cutscene:
! 916: cl.intermission = 3;
! 917: cl.completed_time = cl.time;
! 918: vid.recalc_refdef = true; // go to full screen
! 919: SCR_CenterPrint (MSG_ReadString ());
! 920: break;
! 921:
1.1 root 922: case svc_sellscreen:
923: Cmd_ExecuteString ("help", src_command);
924: break;
925: }
926: }
927: }
928:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.