1 /*
2  * cl_parse.c -- parse a message received from the server
3  * $Id: cl_parse.c 5899 2017-07-16 10:53:21Z bszili $
4  *
5  * Copyright (C) 1996-1997  Id Software, Inc.
6  * Copyright (C) 1997-1998  Raven Software Corp.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or (at
11  * your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * See the GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23 
24 #include "quakedef.h"
25 #include "bgmusic.h"
26 #include "cdaudio.h"
27 #include "r_shared.h"
28 
29 static const char *svc_strings[] =
30 {
31 	"svc_bad",
32 	"svc_nop",
33 	"svc_disconnect",
34 	"svc_updatestat",
35 	"svc_version",		// [long] server version
36 	"svc_setview",		// [short] entity number
37 	"svc_sound",		// <see code>
38 	"svc_time",		// [float] server time
39 	"svc_print",		// [string] null terminated string
40 	"svc_stufftext",	// [string] stuffed into client's console buffer
41 				// the string should be \n terminated
42 	"svc_setangle",		// [vec3] set the view angle to this absolute value
43 
44 	"svc_serverinfo",	// [long] version
45 				// [string] signon string
46 				// [string]..[0]model cache [string]...[0]sounds cache
47 				// [string]..[0]item cache
48 	"svc_lightstyle",	// [byte] [string]
49 	"svc_updatename",	// [byte] [string]
50 	"svc_updatefrags",	// [byte] [short]
51 	"svc_clientdata",	// <shortbits + data>
52 	"svc_stopsound",	// <see code>
53 	"svc_updatecolors",	// [byte] [byte]
54 	"svc_particle",		// [vec3] <variable>
55 	"svc_damage",		// [byte] impact [byte] blood [vec3] from
56 
57 	"svc_spawnstatic",
58 	"svc_raineffect",
59 	"svc_spawnbaseline",
60 
61 	"svc_temp_entity",	// <variable>
62 	"svc_setpause",
63 	"svc_signonnum",
64 	"svc_centerprint",
65 	"svc_killedmonster",
66 	"svc_foundsecret",
67 	"svc_spawnstaticsound",
68 	"svc_intermission",
69 	"svc_finale",		// [string] music [string] text
70 	"svc_cdtrack",		// [byte] track [byte] looptrack
71 	"svc_sellscreen",
72 	"svc_particle2",	// [vec3] <variable>
73 	"svc_cutscene",
74 	"svc_midi_name",
75 	"svc_updateclass",	// [byte] client [byte] class
76 	"svc_particle3",
77 	"svc_particle4",
78 	"svc_set_view_flags",
79 	"svc_clear_view_flags",
80 	"svc_start_effect",
81 	"svc_end_effect",
82 	"svc_plaque",
83 	"svc_particle_explosion",
84 	"svc_set_view_tint",
85 	"svc_reference",
86 	"svc_clear_edicts",
87 	"svc_update_inv",
88 	"svc_setangle_interpolate",
89 	"svc_update_kingofhill",
90 	"svc_toggle_statbar",
91 	"svc_sound_update_pos",
92 	"svc_mod_name",	// UQE v1.13 by Korax, music file name
93 	"svc_skybox"	// UQE v1.13 by Korax, skybox name
94 };
95 #define	NUM_SVC_STRINGS	(sizeof(svc_strings) / sizeof(svc_strings[0]))
96 
97 int		cl_protocol;	/* protocol version used by the server */
98 int		LastServerMessageSize;
99 
100 qmodel_t	*player_models[MAX_PLAYER_CLASS];
101 
102 extern	cvar_t	precache;
103 extern	qboolean menu_disabled_mouse;
104 
105 
106 //=============================================================================
107 
108 
109 /*
110 ===============
111 CL_EntityNum
112 
113 This error checks and tracks the total number of entities
114 ===============
115 */
CL_EntityNum(int num)116 static entity_t *CL_EntityNum (int num)
117 {
118 	if (num >= cl.num_entities)
119 	{
120 		if (num >= MAX_EDICTS)
121 			Host_Error ("%s: %i is an invalid number", __thisfunc__, num);
122 		while (cl.num_entities <= num)
123 		{
124 			cl_entities[cl.num_entities].colormap = vid.colormap;
125 			cl.num_entities++;
126 		}
127 	}
128 
129 	return &cl_entities[num];
130 }
131 
132 
133 /*
134 ==================
135 CL_ParseStartSoundPacket
136 ==================
137 */
CL_ParseStartSoundPacket(void)138 static void CL_ParseStartSoundPacket(void)
139 {
140 	vec3_t	pos;
141 	int		channel, ent;
142 	int		sound_num, volume, field_mask;
143 	float	attenuation;
144 	int		i;
145 
146 	field_mask = MSG_ReadByte();
147 
148 	if (field_mask & SND_VOLUME)
149 		volume = MSG_ReadByte ();
150 	else	volume = DEFAULT_SOUND_PACKET_VOLUME;
151 
152 	if (field_mask & SND_ATTENUATION)
153 		attenuation = MSG_ReadByte () / 64.0;
154 	else	attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
155 
156 	channel = MSG_ReadShort ();
157 	sound_num = MSG_ReadByte ();
158 	if (field_mask & SND_OVERFLOW)
159 		sound_num += MAX_SOUNDS_OLD;
160 	if (field_mask & SND_OVERFLOW2)
161 	{
162 	/* this means the server has MAX_SOUNDS > 512 (== 1024)
163 	 * and is sending it to us as a byte: Kor Skarn's code.
164 	 * UQE does this but I haven't seen this in real life yet.
165 	 * Currently not supported.  TODO: in a newer protocol.
166 	 */
167 		sound_num += MAX_SOUNDS_H2MP;	/* +512  */
168 		Con_DPrintf("%s: field_mask & SND_OVERFLOW2 (%d)\n", __thisfunc__, sound_num);
169 		return;
170 	}
171 
172 	ent = channel >> 3;
173 	channel &= 7;
174 
175 	if (ent > MAX_EDICTS)
176 		Host_Error ("%s: ent = %i", __thisfunc__, ent);
177 
178 	for (i = 0; i < 3; i++)
179 		pos[i] = MSG_ReadCoord ();
180 
181 	S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
182 }
183 
184 /*
185 ==================
186 CL_KeepaliveMessage
187 
188 When the client is taking a long time to load stuff, send keepalive messages
189 so the server doesn't disconnect.
190 ==================
191 */
CL_KeepaliveMessage(void)192 static void CL_KeepaliveMessage (void)
193 {
194 	float	time;
195 	static float lastmsg;
196 	int		ret;
197 	sizebuf_t	old;
198 	byte		olddata[NET_MAXMESSAGE];
199 
200 	if (sv.active)
201 		return;		// no need if server is local
202 	if (cls.demoplayback)
203 		return;
204 
205 // read messages from server, should just be nops
206 	old = net_message;
207 	memcpy (olddata, net_message.data, net_message.cursize);
208 
209 	do
210 	{
211 		ret = CL_GetMessage ();
212 		switch (ret)
213 		{
214 		default:
215 			Host_Error ("%s: CL_GetMessage failed", __thisfunc__);
216 		case 0:
217 			break;	// nothing waiting
218 		case 1:
219 			Host_Error ("%s: received a message", __thisfunc__);
220 			break;
221 		case 2:
222 			if (MSG_ReadByte() != svc_nop)
223 				Host_Error ("%s: datagram wasn't a nop", __thisfunc__);
224 			break;
225 		}
226 	} while (ret);
227 
228 	net_message = old;
229 	memcpy (net_message.data, olddata, net_message.cursize);
230 
231 // check time
232 	time = Sys_DoubleTime ();
233 	if (time - lastmsg < 5)
234 		return;
235 	lastmsg = time;
236 
237 // write out a nop
238 	Con_Printf ("--> client to server keepalive\n");
239 
240 	MSG_WriteByte (&cls.message, clc_nop);
241 	NET_SendMessage (cls.netcon, &cls.message);
242 	SZ_Clear (&cls.message);
243 }
244 
245 /*
246 ==================
247 CL_ParseServerInfo
248 ==================
249 */
CL_ParseServerInfo(void)250 static void CL_ParseServerInfo (void)
251 {
252 	const char	*str;
253 	int		i;
254 	int		nummodels, numsounds;
255 	char	model_precache[MAX_MODELS][MAX_QPATH];
256 	char	sound_precache[MAX_SOUNDS][MAX_QPATH];
257 // rjr	edict_t		*ent;
258 
259 	Con_DPrintf ("Serverinfo packet received.\n");
260 
261 // bring up loading plaque for map changes within a demo.
262 // it will be hidden in CL_SignonReply() -- ericw
263 	if (cls.demoplayback)
264 		SCR_BeginLoadingPlaque();
265 
266 //
267 // wipe the client_state_t struct
268 //
269 	CL_ClearState ();
270 
271 // parse protocol version number
272 	cl_protocol = MSG_ReadLong ();
273 	switch (cl_protocol)
274 	{
275 	case PROTOCOL_RAVEN_111:
276 	case PROTOCOL_RAVEN_112:
277 	case PROTOCOL_UQE_113:
278 		Con_DPrintf ("\nServer using protocol %i\n", cl_protocol);
279 		break;
280 	default:
281 		Con_Printf ("\nServer returned version %i, not %i or %i\n",
282 				cl_protocol, PROTOCOL_RAVEN_112, PROTOCOL_UQE_113);
283 		return;
284 	}
285 
286 // parse maxclients
287 	cl.maxclients = MSG_ReadByte ();
288 	if (cl.maxclients < 1 || cl.maxclients > MAX_CLIENTS)
289 	{
290 		Con_Printf("Bad maxclients (%d) from server\n", cl.maxclients);
291 		return;
292 	}
293 	cl.scores = (scoreboard_t *) Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
294 
295 // parse gametype
296 	cl.gametype = MSG_ReadByte ();
297 
298 	if (cl.gametype == GAME_DEATHMATCH && cl_protocol > PROTOCOL_RAVEN_111)
299 		sv_kingofhill = MSG_ReadShort ();
300 
301 // parse signon message
302 	str = MSG_ReadString ();
303 	q_strlcpy (cl.levelname, str, sizeof(cl.levelname));
304 
305 // seperate the printfs so the server message can have a color
306 	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");
307 	Con_Printf ("%c%s\n", 2, str);
308 
309 //
310 // first we go through and touch all of the precache data that still
311 // happens to be in the cache, so precaching something else doesn't
312 // needlessly purge it
313 //
314 
315 // precache models
316 	memset (cl.model_precache, 0, sizeof(cl.model_precache));
317 	for (nummodels = 1 ; ; nummodels++)
318 	{
319 		str = MSG_ReadString ();
320 		if (!str[0])
321 			break;
322 		if (nummodels == MAX_MODELS)
323 		{
324 			Con_Printf ("Server sent too many model precaches\n");
325 			return;
326 		}
327 		q_strlcpy (model_precache[nummodels], str, MAX_QPATH);
328 		Mod_TouchModel (str);
329 	}
330 
331 // precache sounds
332 	memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
333 	for (numsounds = 1 ; ; numsounds++)
334 	{
335 		str = MSG_ReadString ();
336 		if (!str[0])
337 			break;
338 		if (numsounds == MAX_SOUNDS)
339 		{
340 			Con_Printf ("Server sent too many sound precaches\n");
341 			return;
342 		}
343 		q_strlcpy (sound_precache[numsounds], str, MAX_QPATH);
344 		S_TouchSound (str);
345 	}
346 
347 //
348 // now we try to load everything else until a cache allocation fails
349 //
350 
351 	if (precache.integer)
352 	{
353 		total_loading_size = nummodels + numsounds;
354 		current_loading_size = 1;
355 		loading_stage = 2;
356 	}
357 
358 	// copy the naked name of the map file to the cl structure
359 	COM_FileBase (model_precache[1], cl.mapname, sizeof(cl.mapname));
360 
361 	//always precache the world!!!
362 	cl.model_precache[1] = Mod_ForName (model_precache[1], false);
363 	for (i = 2; i < nummodels; i++)
364 	{
365 		if (precache.integer)
366 		{
367 			cl.model_precache[i] = Mod_ForName (model_precache[i], false);
368 			current_loading_size++;
369 			D_ShowLoadingSize();
370 		}
371 		else
372 			cl.model_precache[i] = (qmodel_t *)Mod_FindName (model_precache[i]);
373 
374 		if (cl.model_precache[i] == NULL)
375 		{
376 			Host_Error("Model %s not found", model_precache[i]);
377 			return;
378 		}
379 		CL_KeepaliveMessage ();
380 	}
381 
382 	player_models[0] = (qmodel_t *)Mod_FindName ("models/paladin.mdl");
383 	player_models[1] = !(gameflags & GAME_OLD_DEMO) ? (qmodel_t *)Mod_FindName ("models/crusader.mdl") : NULL;
384 	player_models[2] = !(gameflags & GAME_OLD_DEMO) ? (qmodel_t *)Mod_FindName ("models/necro.mdl") : NULL;
385 	player_models[3] = (qmodel_t *)Mod_FindName ("models/assassin.mdl");
386 	player_models[4] = (gameflags & GAME_PORTALS) ? (qmodel_t *)Mod_FindName ("models/succubus.mdl") : NULL;
387 
388 	S_BeginPrecaching ();
389 	for (i = 1; i < numsounds; i++)
390 	{
391 		cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
392 		if (precache.integer)
393 		{
394 			current_loading_size++;
395 			D_ShowLoadingSize();
396 		}
397 
398 		CL_KeepaliveMessage ();
399 	}
400 	S_EndPrecaching ();
401 
402 	total_loading_size = 0;
403 	loading_stage = 0;
404 
405 // local state
406 	cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
407 
408 	R_NewMap ();
409 
410 	if (!sv.active)
411 		Host_LoadStrings();
412 	CL_LoadPuzzleStrings();
413 	// mission pack, objectives strings
414 	if (gameflags & GAME_PORTALS)
415 		CL_LoadInfoStrings();
416 
417 	Hunk_Check ();		// make sure nothing is hurt
418 
419 // we connected to the server, make sure the mouse is going - S.A.
420 	menu_disabled_mouse = false;
421 	IN_ActivateMouse();
422 }
423 
424 
425 /*
426 ==================
427 CL_ParseUpdate
428 
429 Parse an entity update message from the server
430 If an entities model or origin changes from frame to frame, it must be
431 relinked.  Other attributes can change without relinking.
432 ==================
433 */
CL_ParseUpdate(int bits)434 static void CL_ParseUpdate (int bits)
435 {
436 	int		i;
437 	qmodel_t	*model;
438 	int		modnum;
439 	qboolean	forcelink;
440 	entity_t	*ent;
441 	int		num;
442 	entity_state2_t *ref_ent, *set_ent, build_ent, dummy;
443 
444 	if (cls.signon == SIGNONS - 1)
445 	{	// first update is the final signon stage
446 		cls.signon = SIGNONS;
447 		CL_SignonReply ();
448 	}
449 
450 	if (bits & U_MOREBITS)
451 	{
452 		i = MSG_ReadByte ();
453 		bits |= (i<<8);
454 	}
455 
456 	if (bits & U_MOREBITS2)
457 	{
458 		i = MSG_ReadByte ();
459 		bits |= (i<<16);
460 	}
461 
462 	if (bits & U_LONGENTITY)
463 		num = MSG_ReadShort ();
464 	else	num = MSG_ReadByte ();
465 
466 	ent = CL_EntityNum (num);
467 	ent->baseline.flags |= BE_ON;
468 	ref_ent = NULL;
469 
470 	for (i = 0; i < cl.frames[0].count; i++)
471 	{
472 		if (cl.frames[0].states[i].index == num)
473 		{
474 			ref_ent = &cl.frames[0].states[i];
475 			break;
476 		}
477 	}
478 	if (!ref_ent)
479 	{
480 		ref_ent = &build_ent;
481 
482 		build_ent.index = num;
483 		build_ent.origin[0] = ent->baseline.origin[0];
484 		build_ent.origin[1] = ent->baseline.origin[1];
485 		build_ent.origin[2] = ent->baseline.origin[2];
486 		build_ent.angles[0] = ent->baseline.angles[0];
487 		build_ent.angles[1] = ent->baseline.angles[1];
488 		build_ent.angles[2] = ent->baseline.angles[2];
489 		build_ent.modelindex = ent->baseline.modelindex;
490 		build_ent.frame = ent->baseline.frame;
491 		build_ent.colormap = ent->baseline.colormap;
492 		build_ent.skin = ent->baseline.skin;
493 		build_ent.effects = ent->baseline.effects;
494 		build_ent.scale = ent->baseline.scale;
495 		build_ent.drawflags = ent->baseline.drawflags;
496 		build_ent.abslight = ent->baseline.abslight;
497 	}
498 
499 	if (cl.need_build)
500 	{	// new sequence, first valid frame
501 		set_ent = &cl.frames[1].states[cl.frames[1].count];
502 		cl.frames[1].count++;
503 	}
504 	else
505 		set_ent = &dummy;
506 
507 	if (bits & U_CLEAR_ENT)
508 	{
509 		memset(ent, 0, sizeof(entity_t));
510 		memset(ref_ent, 0, sizeof(*ref_ent));
511 		ref_ent->index = num;
512 	}
513 
514 	*set_ent = *ref_ent;
515 
516 	if (ent->msgtime != cl.mtime[1])
517 		forcelink = true;	// no previous frame to lerp from
518 	else	forcelink = false;
519 
520 	ent->msgtime = cl.mtime[0];
521 
522 	if (bits & U_MODEL)
523 	{
524 		modnum = MSG_ReadShort ();
525 		if (modnum >= MAX_MODELS)
526 			Host_Error ("%s: bad modnum", __thisfunc__);
527 	}
528 	else	modnum = ref_ent->modelindex;
529 
530 	model = cl.model_precache[modnum];
531 	set_ent->modelindex = modnum;
532 	if (model != ent->model)
533 	{
534 		ent->model = model;
535 		// automatic animation (torches, etc) can
536 		// be either all together or randomized
537 		if (model)
538 		{
539 			if (model->synctype == ST_RAND)
540 				ent->syncbase = rand() * (1.0 / RAND_MAX);//(float)(rand() & 0x7fff) / 0x7fff;
541 			else	ent->syncbase = 0.0;
542 		}
543 		else	forcelink = true;	// hack to make null model players work
544 #ifdef GLQUAKE
545 		if (num > 0 && num <= cl.maxclients)
546 			R_TranslatePlayerSkin (num - 1);
547 #endif
548 	}
549 
550 	if (bits & U_FRAME)
551 		set_ent->frame = ent->frame = MSG_ReadByte ();
552 	else	ent->frame = ref_ent->frame;
553 
554 	if (bits & U_COLORMAP)
555 		set_ent->colormap = i = MSG_ReadByte();
556 	else	i = ref_ent->colormap;
557 
558 	if (num && num <= cl.maxclients)
559 		ent->colormap = ent->sourcecolormap = cl.scores[num-1].translations;
560 	else	ent->sourcecolormap = vid.colormap;
561 
562 #ifdef GLQUAKE
563 //	ent->colormap = vid.colormap;
564 #endif
565 
566 	if (!i)
567 	{
568 		ent->colorshade = i;
569 		ent->colormap = ent->sourcecolormap;
570 	}
571 	else
572 	{
573 		ent->colorshade = i;
574 #ifdef GLQUAKE
575 //		ent->colormap = vid.colormap;
576 		ent->colormap = globalcolormap;
577 #else
578 		ent->colormap = globalcolormap;
579 #endif
580 	}
581 
582 	if (bits & U_SKIN)
583 	{
584 		set_ent->skin = ent->skinnum = MSG_ReadByte();
585 		set_ent->drawflags = ent->drawflags = MSG_ReadByte();
586 	}
587 	else
588 	{
589 		ent->skinnum = ref_ent->skin;
590 		ent->drawflags = ref_ent->drawflags;
591 	}
592 
593 	if (bits & U_EFFECTS)
594 		set_ent->effects = ent->effects = MSG_ReadByte();
595 	else	ent->effects = ref_ent->effects;
596 
597 // shift the known values for interpolation
598 	VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
599 	VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
600 
601 	if (bits & U_ORIGIN1)
602 		set_ent->origin[0] = ent->msg_origins[0][0] = MSG_ReadCoord ();
603 	else	ent->msg_origins[0][0] = ref_ent->origin[0];
604 
605 	if (bits & U_ANGLE1)
606 		set_ent->angles[0] = ent->msg_angles[0][0] = MSG_ReadAngle();
607 	else	ent->msg_angles[0][0] = ref_ent->angles[0];
608 
609 	if (bits & U_ORIGIN2)
610 		set_ent->origin[1] = ent->msg_origins[0][1] = MSG_ReadCoord ();
611 	else	ent->msg_origins[0][1] = ref_ent->origin[1];
612 
613 	if (bits & U_ANGLE2)
614 		set_ent->angles[1] = ent->msg_angles[0][1] = MSG_ReadAngle();
615 	else	ent->msg_angles[0][1] = ref_ent->angles[1];
616 
617 	if (bits & U_ORIGIN3)
618 		set_ent->origin[2] = ent->msg_origins[0][2] = MSG_ReadCoord ();
619 	else	ent->msg_origins[0][2] = ref_ent->origin[2];
620 
621 	if (bits & U_ANGLE3)
622 		set_ent->angles[2] = ent->msg_angles[0][2] = MSG_ReadAngle();
623 	else	ent->msg_angles[0][2] = ref_ent->angles[2];
624 
625 	if (bits & U_SCALE)
626 	{
627 		set_ent->scale = ent->scale = MSG_ReadByte();
628 		set_ent->abslight = ent->abslight = MSG_ReadByte();
629 	}
630 	else
631 	{
632 		ent->scale = ref_ent->scale;
633 		ent->abslight = ref_ent->abslight;
634 	}
635 
636 	if (bits & U_NOLERP)
637 		ent->forcelink = true;
638 
639 	if (forcelink)
640 	{	// didn't have an update last message
641 		VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
642 		VectorCopy (ent->msg_origins[0], ent->origin);
643 		VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
644 		VectorCopy (ent->msg_angles[0], ent->angles);
645 		ent->forcelink = true;
646 	}
647 }
648 
CL_ParseUpdate2(int bits)649 static void CL_ParseUpdate2 (int bits)
650 {
651 	int	i;
652 
653 	if (bits & U_MOREBITS)
654 	{
655 		i = MSG_ReadByte ();
656 		bits |= (i<<8);
657 	}
658 	if (bits & U_MOREBITS2)
659 	{
660 		i = MSG_ReadByte ();
661 		bits |= (i<<16);
662 	}
663 	if (bits & U_LONGENTITY)
664 		MSG_ReadShort ();
665 	else	MSG_ReadByte ();
666 	if (bits & U_MODEL)
667 		MSG_ReadShort ();
668 	if (bits & U_FRAME)
669 		MSG_ReadByte ();
670 	if (bits & U_COLORMAP)
671 		MSG_ReadByte();
672 	if (bits & U_SKIN)
673 	{
674 		MSG_ReadByte();
675 		MSG_ReadByte();
676 	}
677 	if (bits & U_EFFECTS)
678 		MSG_ReadByte();
679 	if (bits & U_ORIGIN1)
680 		MSG_ReadCoord ();
681 	if (bits & U_ANGLE1)
682 		MSG_ReadAngle();
683 	if (bits & U_ORIGIN2)
684 		MSG_ReadCoord ();
685 	if (bits & U_ANGLE2)
686 		MSG_ReadAngle();
687 	if (bits & U_ORIGIN3)
688 		MSG_ReadCoord ();
689 	if (bits & U_ANGLE3)
690 		MSG_ReadAngle();
691 	if (bits & U_SCALE)
692 	{
693 		MSG_ReadByte();
694 		MSG_ReadByte();
695 	}
696 }
697 
698 /*
699 ==================
700 CL_ParseBaseline
701 ==================
702 */
CL_ParseBaseline(entity_t * ent)703 static void CL_ParseBaseline (entity_t *ent)
704 {
705 	int	i;
706 
707 	ent->baseline.modelindex = MSG_ReadShort ();
708 	ent->baseline.frame = MSG_ReadByte ();
709 	ent->baseline.colormap = MSG_ReadByte();
710 	ent->baseline.skin = MSG_ReadByte();
711 	ent->baseline.scale = MSG_ReadByte();
712 	ent->baseline.drawflags = MSG_ReadByte();
713 	ent->baseline.abslight = MSG_ReadByte();
714 	for (i = 0; i < 3; i++)
715 	{
716 		ent->baseline.origin[i] = MSG_ReadCoord ();
717 		ent->baseline.angles[i] = MSG_ReadAngle ();
718 	}
719 }
720 
721 
722 /*
723 ==================
724 CL_ParseClientdata
725 
726 Server information pertaining to this client only
727 ==================
728 */
CL_ParseClientdata(int bits)729 static void CL_ParseClientdata (int bits)
730 {
731 	int	i, j;
732 
733 	if (bits & SU_VIEWHEIGHT)
734 		cl.viewheight = MSG_ReadChar ();
735 //rjr	else	cl.viewheight = DEFAULT_VIEWHEIGHT;
736 
737 	if (bits & SU_IDEALPITCH)
738 		cl.idealpitch = MSG_ReadChar ();
739 
740 	if (bits & SU_IDEALROLL)
741 		cl.idealroll = MSG_ReadChar ();
742 //rjr	else	cl.idealroll = 0;
743 
744 	VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
745 	for (i = 0; i < 3; i++)
746 	{
747 		if (bits & (SU_PUNCH1<<i))
748 			cl.punchangle[i] = MSG_ReadChar();
749 //rjr		else	cl.punchangle[i] = 0;
750 		if (bits & (SU_VELOCITY1<<i))
751 			cl.mvelocity[0][i] = MSG_ReadChar()*16;
752 //rjr		else	cl.mvelocity[0][i] = 0;
753 	}
754 
755 	/*
756 	if (bits & SU_ITEMS)
757 		i = MSG_ReadLong ();
758 	*/
759 
760 	if (cl.items != i)
761 	{	// set flash times
762 		Sbar_Changed();
763 		for (j = 0; j < 32; j++)
764 			if ((i & (1<<j)) && !(cl.items & (1<<j)))
765 				cl.item_gettime[j] = cl.time;
766 		cl.items = i;
767 	}
768 
769 	cl.onground = ((bits & SU_ONGROUND) != 0);
770 	cl.inwater  = ((bits & SU_INWATER)  != 0);
771 
772 	if (bits & SU_WEAPONFRAME)
773 		cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
774 //rjr	else	cl.stats[STAT_WEAPONFRAME] = 0;
775 
776 	if (bits & SU_ARMOR)
777 	{
778 		cl.stats[STAT_ARMOR] = MSG_ReadByte ();
779 		//Sbar_Changed();
780 	}
781 
782 	if (bits & SU_WEAPON)
783 	{
784 		cl.stats[STAT_WEAPON] = MSG_ReadShort ();
785 		//Sbar_Changed();
786 	}
787 
788 	/*
789 	sc1 = sc2 = 0;
790 
791 	if (bits & SU_SC1)
792 		sc1 = MSG_ReadLong ();
793 	if (bits & SU_SC2)
794 		sc2 = MSG_ReadLong ();
795 
796 	if (sc1 & SC1_HEALTH)
797 		cl.v.health = MSG_ReadShort();
798 	if (sc1 & SC1_LEVEL)
799 		cl.v.level = MSG_ReadByte();
800 	if (sc1 & SC1_INTELLIGENCE)
801 		cl.v.intelligence = MSG_ReadByte();
802 	if (sc1 & SC1_WISDOM)
803 		cl.v.wisdom = MSG_ReadByte();
804 	if (sc1 & SC1_STRENGTH)
805 		cl.v.strength = MSG_ReadByte();
806 	if (sc1 & SC1_DEXTERITY)
807 		cl.v.dexterity = MSG_ReadByte();
808 	if (sc1 & SC1_WEAPON)
809 		cl.v.weapon = MSG_ReadByte();
810 	if (sc1 & SC1_BLUEMANA)
811 		cl.v.bluemana = MSG_ReadByte();
812 	if (sc1 & SC1_GREENMANA)
813 		cl.v.greenmana = MSG_ReadByte();
814 	if (sc1 & SC1_EXPERIENCE)
815 		cl.v.experience = MSG_ReadLong();
816 	if (sc1 & SC1_CNT_TORCH)
817 		cl.v.cnt_torch = MSG_ReadByte();
818 	if (sc1 & SC1_CNT_H_BOOST)
819 		cl.v.cnt_h_boost = MSG_ReadByte();
820 	if (sc1 & SC1_CNT_SH_BOOST)
821 		cl.v.cnt_sh_boost = MSG_ReadByte();
822 	if (sc1 & SC1_CNT_MANA_BOOST)
823 		cl.v.cnt_mana_boost = MSG_ReadByte();
824 	if (sc1 & SC1_CNT_TELEPORT)
825 		cl.v.cnt_teleport = MSG_ReadByte();
826 	if (sc1 & SC1_CNT_TOME)
827 		cl.v.cnt_tome = MSG_ReadByte();
828 	if (sc1 & SC1_CNT_SUMMON)
829 		cl.v.cnt_summon = MSG_ReadByte();
830 	if (sc1 & SC1_CNT_INVISIBILITY)
831 		cl.v.cnt_invisibility = MSG_ReadByte();
832 	if (sc1 & SC1_CNT_GLYPH)
833 		cl.v.cnt_glyph = MSG_ReadByte();
834 	if (sc1 & SC1_CNT_HASTE)
835 		cl.v.cnt_haste = MSG_ReadByte();
836 	if (sc1 & SC1_CNT_BLAST)
837 		cl.v.cnt_blast = MSG_ReadByte();
838 	if (sc1 & SC1_CNT_POLYMORPH)
839 		cl.v.cnt_polymorph = MSG_ReadByte();
840 	if (sc1 & SC1_CNT_FLIGHT)
841 		cl.v.cnt_flight = MSG_ReadByte();
842 	if (sc1 & SC1_CNT_CUBEOFFORCE)
843 		cl.v.cnt_cubeofforce = MSG_ReadByte();
844 	if (sc1 & SC1_CNT_INVINCIBILITY)
845 		cl.v.cnt_invincibility = MSG_ReadByte();
846 	if (sc1 & SC1_ARTIFACT_ACTIVE)
847 		cl.v.artifact_active = MSG_ReadFloat();
848 	if (sc1 & SC1_ARTIFACT_LOW)
849 		cl.v.artifact_low = MSG_ReadFloat();
850 	if (sc1 & SC1_MOVETYPE)
851 		cl.v.movetype = MSG_ReadByte();
852 	if (sc1 & SC1_CAMERAMODE)
853 		cl.v.cameramode = MSG_ReadByte();
854 	if (sc1 & SC1_HASTED)
855 		cl.v.hasted = MSG_ReadFloat();
856 	if (sc1 & SC1_INVENTORY)
857 		cl.v.inventory = MSG_ReadByte();
858 	if (sc1 & SC1_RINGS_ACTIVE)
859 		cl.v.rings_active = MSG_ReadFloat();
860 
861 	if (sc2 & SC2_RINGS_LOW)
862 		cl.v.rings_low = MSG_ReadFloat();
863 	if (sc2 & SC2_AMULET)
864 		cl.v.armor_amulet = MSG_ReadByte();
865 	if (sc2 & SC2_BRACER)
866 		cl.v.armor_bracer = MSG_ReadByte();
867 	if (sc2 & SC2_BREASTPLATE)
868 		cl.v.armor_breastplate = MSG_ReadByte();
869 	if (sc2 & SC2_HELMET)
870 		cl.v.armor_helmet = MSG_ReadByte();
871 	if (sc2 & SC2_FLIGHT_T)
872 		cl.v.ring_flight = MSG_ReadByte();
873 	if (sc2 & SC2_WATER_T)
874 		cl.v.ring_water = MSG_ReadByte();
875 	if (sc2 & SC2_TURNING_T)
876 		cl.v.ring_turning = MSG_ReadByte();
877 	if (sc2 & SC2_REGEN_T)
878 		cl.v.ring_regeneration = MSG_ReadByte();
879 	if (sc2 & SC2_HASTE_T)
880 		cl.v.haste_time = MSG_ReadFloat();
881 	if (sc2 & SC2_TOME_T)
882 		cl.v.tome_time = MSG_ReadFloat();
883 	if (sc2 & SC2_PUZZLE1)
884 		q_snprintf(cl.puzzle_pieces[0], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
885 	if (sc2 & SC2_PUZZLE2)
886 		q_snprintf(cl.puzzle_pieces[1], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
887 	if (sc2 & SC2_PUZZLE3)
888 		q_snprintf(cl.puzzle_pieces[2], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
889 	if (sc2 & SC2_PUZZLE4)
890 		q_snprintf(cl.puzzle_pieces[3], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
891 	if (sc2 & SC2_PUZZLE5)
892 		q_snprintf(cl.puzzle_pieces[4], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
893 	if (sc2 & SC2_PUZZLE6)
894 		q_snprintf(cl.puzzle_pieces[5], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
895 	if (sc2 & SC2_PUZZLE7)
896 		q_snprintf(cl.puzzle_pieces[6], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
897 	if (sc2 & SC2_PUZZLE8)
898 		q_snprintf(cl.puzzle_pieces[7], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
899 	if (sc2 & SC2_MAXHEALTH)
900 		cl.v.max_health = MSG_ReadShort();
901 	if (sc2 & SC2_MAXMANA)
902 		cl.v.max_mana = MSG_ReadByte();
903 	if (sc2 & SC2_FLAGS)
904 		cl.v.flags = MSG_ReadFloat();
905 
906 	if ((sc1 & SC1_STAT_BAR) || (sc2 & SC2_STAT_BAR))
907 		Sbar_Changed();
908 
909 	if ((sc1 & SC1_INV) || (sc2 & SC2_INV))
910 		SB_InvChanged();
911 	*/
912 }
913 
914 /*
915 =====================
916 CL_NewTranslation
917 =====================
918 */
CL_NewTranslation(int slot)919 static void CL_NewTranslation (int slot)
920 {
921 #ifndef GLQUAKE
922 	int	i, j;
923 	int	top, bottom;
924 	byte	*dest, *source, *sourceA, *sourceB, *colorA, *colorB;
925 #endif
926 
927 	if (slot >= cl.maxclients)
928 		Sys_Error ("%s: slot > cl.maxclients", __thisfunc__);
929 	if (!cl.scores[slot].playerclass)
930 		return;
931 
932 #ifdef GLQUAKE
933 	R_TranslatePlayerSkin (slot);
934 	return;
935 #else
936 
937 	dest = cl.scores[slot].translations;
938 	source = vid.colormap;
939 	memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations));
940 	top = (cl.scores[slot].colors & 0xf0) >> 4;
941 	bottom = (cl.scores[slot].colors & 15);
942 
943 	if (top > 11 || bottom > 11)
944 		Con_Printf("Invalid Player Color: %d,%d\n", top, bottom);
945 	if (top > 10)
946 		top = 0;
947 	if (bottom > 10)
948 		bottom = 0;
949 	top -= 1;
950 	bottom -= 1;
951 
952 //	Con_Printf("Class is %d for slot %d\n",(int)cl.scores[slot].playerclass,slot);
953 	for (i = 0; i < VID_GRADES; i++, dest += 256, source += 256)
954 	{
955 		colorA = playerTranslation + 256 + color_offsets[(int)cl.scores[slot].playerclass-1];
956 		colorB = colorA + 256;
957 		sourceA = colorB + 256 + (top * 256);
958 		sourceB = colorB + 256 + (bottom * 256);
959 		for (j = 0; j < 256; j++, colorA++, colorB++, sourceA++, sourceB++)
960 		{
961 			if (top >= 0 && (*colorA != 255))
962 				dest[j] = source[*sourceA];
963 			if (bottom >= 0 && (*colorB != 255))
964 				dest[j] = source[*sourceB];
965 		}
966 	}
967 #endif
968 }
969 
970 /*
971 =====================
972 CL_ParseStatic
973 =====================
974 */
CL_ParseStatic(void)975 static void CL_ParseStatic (void)
976 {
977 	entity_t *ent;
978 	int	i;
979 
980 	i = cl.num_statics;
981 	if (i >= MAX_STATIC_ENTITIES)
982 		Host_Error ("Too many static entities");
983 	ent = &cl_static_entities[i];
984 	cl.num_statics++;
985 	CL_ParseBaseline (ent);
986 
987 // copy it to the current state
988 	ent->model = cl.model_precache[ent->baseline.modelindex];
989 	ent->frame = ent->baseline.frame;
990 	ent->colormap = vid.colormap;
991 	ent->skinnum = ent->baseline.skin;
992 	ent->scale = ent->baseline.scale;
993 	ent->effects = ent->baseline.effects;
994 	ent->drawflags = ent->baseline.drawflags;
995 	ent->abslight = ent->baseline.abslight;
996 
997 	VectorCopy (ent->baseline.origin, ent->origin);
998 	VectorCopy (ent->baseline.angles, ent->angles);
999 	R_AddEfrags (ent);
1000 }
1001 
1002 /*
1003 ===================
1004 CL_ParseStaticSound
1005 ===================
1006 */
CL_ParseStaticSound(void)1007 static void CL_ParseStaticSound (void)
1008 {
1009 	vec3_t	org;
1010 	int	sound_num, vol, atten;
1011 	int	i;
1012 
1013 	for (i = 0; i < 3; i++)
1014 		org[i] = MSG_ReadCoord ();
1015 
1016 	if (cl_protocol == PROTOCOL_RAVEN_111)
1017 		sound_num = MSG_ReadByte ();
1018 	else	sound_num = MSG_ReadShort();
1019 	vol = MSG_ReadByte ();
1020 	atten = MSG_ReadByte ();
1021 
1022 	S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
1023 }
1024 
1025 
CL_Plaque(void)1026 static void CL_Plaque(void)
1027 {
1028 	int	idx;
1029 
1030 	idx = MSG_ReadShort ();
1031 
1032 	if (idx > 0 && idx <= host_string_count)
1033 		SCR_SetPlaqueMessage (Host_GetString(idx - 1));
1034 	else	SCR_SetPlaqueMessage ("");
1035 }
1036 
CL_ParticleExplosion(void)1037 static void CL_ParticleExplosion(void)
1038 {
1039 	vec3_t	org;
1040 	short	color, radius, counter;
1041 
1042 	org[0] = MSG_ReadCoord();
1043 	org[1] = MSG_ReadCoord();
1044 	org[2] = MSG_ReadCoord();
1045 	color = MSG_ReadShort();
1046 	radius = MSG_ReadShort();
1047 	counter = MSG_ReadShort();
1048 
1049 	R_ColoredParticleExplosion(org,color,radius,counter);
1050 }
1051 
CL_ParseRainEffect(void)1052 static void CL_ParseRainEffect(void)
1053 {
1054 	vec3_t	org, e_size;
1055 	short	color,count;
1056 	int	x_dir, y_dir;
1057 
1058 	org[0] = MSG_ReadCoord();
1059 	org[1] = MSG_ReadCoord();
1060 	org[2] = MSG_ReadCoord();
1061 	e_size[0] = MSG_ReadCoord();
1062 	e_size[1] = MSG_ReadCoord();
1063 	e_size[2] = MSG_ReadCoord();
1064 	x_dir = MSG_ReadAngle();
1065 	y_dir = MSG_ReadAngle();
1066 	color = MSG_ReadShort();
1067 	count = MSG_ReadShort();
1068 
1069 	R_RainEffect(org,e_size,x_dir,y_dir,color,count);
1070 }
1071 
1072 #if 0	/* for debugging. from fteqw. */
1073 static void CL_DumpPacket (void)
1074 {
1075 	int			i, pos;
1076 	char	*packet = net_message.data;
1077 
1078 	Con_Printf("%s, BEGIN:\n", __thisfunc__);
1079 	pos = 0;
1080 	while (pos < net_message.cursize)
1081 	{
1082 		Con_Printf("%5i ", pos);
1083 		for (i = 0; i < 16; i++)
1084 		{
1085 			if (pos >= net_message.cursize)
1086 				Con_Printf(" X ");
1087 			else	Con_Printf("%2x ", (unsigned char)packet[pos]);
1088 			pos++;
1089 		}
1090 		pos -= 16;
1091 		for (i = 0; i < 16; i++)
1092 		{
1093 			if (pos >= net_message.cursize)
1094 				Con_Printf("X");
1095 			else if (packet[pos] == 0)
1096 				Con_Printf(".");
1097 			else	Con_Printf("%c", (unsigned char)packet[pos]);
1098 			pos++;
1099 		}
1100 		Con_Printf("\n");
1101 	}
1102 
1103 	Con_Printf("%s, --- END ---\n", __thisfunc__);
1104 }
1105 #endif	/* CL_DumpPacket */
1106 
1107 #define SHOWNET(S)						\
1108 do {								\
1109 	if (cl_shownet.integer == 2)				\
1110 		Con_Printf ("%3i:%s\n", msg_readcount-1, (S));	\
1111 } while (0)
1112 
1113 /*
1114 =====================
1115 CL_ParseServerMessage
1116 =====================
1117 */
CL_ParseServerMessage(void)1118 void CL_ParseServerMessage (void)
1119 {
1120 	int		cmd;
1121 	int		i, j, k;
1122 	int		EntityCount = 0;
1123 	int		EntitySize = 0;
1124 	int		before;
1125 	static		double lasttime;
1126 	static		qboolean packet_loss = false;
1127 	entity_t	*ent;
1128 	int		sc1, sc2;
1129 	byte		test;
1130 	float		compangles[2][3];
1131 	vec3_t		deltaangles;
1132 
1133 // if recording demos, copy the message out
1134 	if (net_message.cursize > LastServerMessageSize)
1135 	{
1136 		LastServerMessageSize = net_message.cursize;
1137 	}
1138 	if (cl_shownet.integer == 1)
1139 	{
1140 		Con_Printf ("Time: %2.2f Pck: %i ", realtime - lasttime, net_message.cursize);
1141 		lasttime = realtime;
1142 	}
1143 	else if (cl_shownet.integer == 2)
1144 	{
1145 		Con_Printf ("------------------\n");
1146 	}
1147 
1148 	cl.onground = false;	// unless the server says otherwise
1149 
1150 // parse the message
1151 	MSG_BeginReading ();
1152 
1153 	while (1)
1154 	{
1155 		if (msg_badread)
1156 			Host_Error ("%s: Bad server message", __thisfunc__);
1157 
1158 		cmd = MSG_ReadByte ();
1159 		if (cmd == -1)
1160 		{
1161 			if (cl_shownet.integer == 1)
1162 				Con_Printf ("Ent: %i (%i bytes)", EntityCount, EntitySize);
1163 			SHOWNET("END OF MESSAGE");
1164 			return; // end of message
1165 		}
1166 
1167 	// if the high bit of the command byte is set, it is a fast update
1168 		if (cmd & 128)
1169 		{
1170 			before = msg_readcount;
1171 			SHOWNET("fast update");
1172 			if (packet_loss)
1173 				CL_ParseUpdate2 (cmd & 127);
1174 			else	CL_ParseUpdate (cmd & 127);
1175 
1176 			EntityCount++;
1177 			EntitySize += msg_readcount - before + 1;
1178 			continue;
1179 		}
1180 
1181 		if (cmd < (int)NUM_SVC_STRINGS) {
1182 			SHOWNET(svc_strings[cmd]);
1183 		}
1184 
1185 	// other commands
1186 		switch (cmd)
1187 		{
1188 		default:
1189 		//	CL_DumpPacket ();
1190 			Host_Error ("%s: Illegible server message %d", __thisfunc__, cmd);
1191 			break;
1192 
1193 		case svc_nop:
1194 		//	Con_Printf ("svc_nop\n");
1195 			break;
1196 
1197 		case svc_time:
1198 			cl.mtime[1] = cl.mtime[0];
1199 			cl.mtime[0] = MSG_ReadFloat ();
1200 			break;
1201 
1202 		case svc_clientdata:
1203 			i = MSG_ReadShort ();
1204 			CL_ParseClientdata (i);
1205 			break;
1206 
1207 		case svc_version:
1208 			cl_protocol = MSG_ReadLong ();
1209 			switch (cl_protocol)
1210 			{
1211 			case PROTOCOL_RAVEN_111:
1212 			case PROTOCOL_RAVEN_112:
1213 			case PROTOCOL_UQE_113:
1214 				Con_Printf ("Server using protocol %i\n", cl_protocol);
1215 				break;
1216 			default:
1217 				Host_Error ("%s: Server is protocol %i instead of %i or %i",
1218 						__thisfunc__, cl_protocol,
1219 						PROTOCOL_RAVEN_112, PROTOCOL_UQE_113);
1220 			}
1221 			break;
1222 
1223 		case svc_disconnect:
1224 			Host_EndGame ("Server disconnected\n");
1225 			break;
1226 
1227 		case svc_print:
1228 			if (intro_playing) {
1229 				MSG_ReadString ();
1230 				break;
1231 			}
1232 			Con_Printf ("%s", MSG_ReadString ());
1233 			break;
1234 
1235 		case svc_centerprint:
1236 			SCR_CenterPrint (MSG_ReadString ());
1237 			break;
1238 
1239 		case svc_stufftext:
1240 			Cbuf_AddText (MSG_ReadString ());
1241 			break;
1242 
1243 		case svc_damage:
1244 			V_ParseDamage ();
1245 			break;
1246 
1247 		case svc_serverinfo:
1248 			CL_ParseServerInfo ();
1249 			vid.recalc_refdef = true;	// leave intermission full screen
1250 			break;
1251 
1252 		case svc_setangle:
1253 			for (i = 0; i < 3; i++)
1254 				cl.viewangles[i] = MSG_ReadAngle ();
1255 			break;
1256 
1257 		case svc_setangle_interpolate:
1258 			compangles[0][0] = MSG_ReadAngle();
1259 			compangles[0][1] = MSG_ReadAngle();
1260 			compangles[0][2] = MSG_ReadAngle();
1261 			for (i = 0; i < 3; i++)
1262 			{
1263 				compangles[1][i] = cl.viewangles[i];
1264 				for (j = 0; j < 2; j++)
1265 				{//standardize both old and new angles to +-180
1266 					if (compangles[j][i] >= 360)
1267 						compangles[j][i] -= 360*((int)(compangles[j][i]/360));
1268 					else if (compangles[j][i] <= 360)
1269 						compangles[j][i] += 360*(1+(int)(-compangles[j][i]/360));
1270 					if (compangles[j][i] > 180)
1271 						compangles[j][i] = -360 + compangles[j][i];
1272 					else if (compangles[j][i] < -180)
1273 						compangles[j][i] = 360 + compangles[j][i];
1274 				}
1275 				//get delta
1276 				deltaangles[i] = compangles[0][i] - compangles[1][i];
1277 				//cap delta to <=180,>=-180
1278 				if (deltaangles[i] > 180)
1279 					deltaangles[i] += -360;
1280 				else if (deltaangles[i] < -180)
1281 					deltaangles[i] += 360;
1282 				//add the delta
1283 				cl.viewangles[i]+=(deltaangles[i]/8);//8 step interpolation
1284 				//cap newangles to +-180
1285 				if (cl.viewangles[i] >= 360)
1286 					cl.viewangles[i] -= 360*((int)(cl.viewangles[i]/360));
1287 				else if (cl.viewangles[i] <= 360)
1288 					cl.viewangles[i] += 360*(1+(int)(-cl.viewangles[i]/360));
1289 				if (cl.viewangles[i] > 180)
1290 					cl.viewangles[i] += -360;
1291 				else if (cl.viewangles[i] < -180)
1292 					cl.viewangles[i] += 360;
1293 			}
1294 			break;
1295 
1296 		case svc_setview:
1297 			cl.viewentity = MSG_ReadShort ();
1298 			break;
1299 
1300 		case svc_lightstyle:
1301 			i = MSG_ReadByte ();
1302 			if (i >= MAX_LIGHTSTYLES)
1303 				Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
1304 			q_strlcpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING);
1305 			cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1306 			break;
1307 
1308 		case svc_sound:
1309 			CL_ParseStartSoundPacket();
1310 			break;
1311 
1312 		case svc_sound_update_pos:
1313 		  {	// FIXME: put a field on the entity that lists the channels
1314 			// it should update when it moves- if a certain flag
1315 			// is on the ent, this update_channels field could
1316 			// be set automatically by each sound and stopSound
1317 			// called for this ent?
1318 			vec3_t	pos;
1319 			int	channel, ent_num;
1320 
1321 			channel = MSG_ReadShort ();
1322 			ent_num = channel >> 3;
1323 			channel &= 7;
1324 
1325 			if (ent_num > MAX_EDICTS)
1326 				Host_Error ("svc_sound_update_pos: ent = %i", ent_num);
1327 
1328 			for (i = 0; i < 3; i++)
1329 				pos[i] = MSG_ReadCoord ();
1330 
1331 			S_UpdateSoundPos (ent_num, channel, pos);
1332 		  }	break;
1333 
1334 		case svc_stopsound:
1335 			i = MSG_ReadShort();
1336 			S_StopSound(i>>3, i&7);
1337 			break;
1338 
1339 		case svc_updatename:
1340 			Sbar_Changed();
1341 			i = MSG_ReadByte ();
1342 			if (i >= cl.maxclients)
1343 				Host_Error ("%s: svc_updatename > MAX_CLIENTS", __thisfunc__);
1344 			q_strlcpy (cl.scores[i].name, MSG_ReadString(), MAX_SCOREBOARDNAME);
1345 			break;
1346 
1347 		case svc_updateclass:
1348 			Sbar_Changed();
1349 			i = MSG_ReadByte ();
1350 			if (i >= cl.maxclients)
1351 				Host_Error ("%s: svc_updateclass > MAX_CLIENTS", __thisfunc__);
1352 			cl.scores[i].playerclass = (float)MSG_ReadByte();
1353 			CL_NewTranslation(i); // update the color
1354 			break;
1355 
1356 		case svc_updatefrags:
1357 			Sbar_Changed();
1358 			i = MSG_ReadByte ();
1359 			if (i >= cl.maxclients)
1360 				Host_Error ("%s: svc_updatefrags > MAX_CLIENTS", __thisfunc__);
1361 			cl.scores[i].frags = MSG_ReadShort ();
1362 			break;
1363 
1364 		case svc_update_kingofhill:
1365 			sv_kingofhill = MSG_ReadShort() - 1;
1366 			break;
1367 
1368 		case svc_updatecolors:
1369 			Sbar_Changed();
1370 			i = MSG_ReadByte ();
1371 			if (i >= cl.maxclients)
1372 				Host_Error ("%s: svc_updatecolors > MAX_CLIENTS", __thisfunc__);
1373 			cl.scores[i].colors = MSG_ReadByte ();
1374 			CL_NewTranslation (i);
1375 			break;
1376 
1377 		case svc_particle:
1378 			R_ParseParticleEffect ();
1379 			break;
1380 
1381 		case svc_particle2:
1382 			R_ParseParticleEffect2 ();
1383 			break;
1384 		case svc_particle3:
1385 			R_ParseParticleEffect3 ();
1386 			break;
1387 		case svc_particle4:
1388 			R_ParseParticleEffect4 ();
1389 			break;
1390 
1391 		case svc_spawnbaseline:
1392 			i = MSG_ReadShort ();
1393 			// must use CL_EntityNum() to force cl.num_entities up
1394 			CL_ParseBaseline (CL_EntityNum(i));
1395 			break;
1396 		case svc_spawnstatic:
1397 			CL_ParseStatic ();
1398 			break;
1399 
1400 		case svc_raineffect:
1401 			CL_ParseRainEffect();
1402 			break;
1403 
1404 		case svc_temp_entity:
1405 			CL_ParseTEnt ();
1406 			break;
1407 
1408 		case svc_setpause:
1409 			cl.paused = MSG_ReadByte ();
1410 			if (cl.paused)
1411 			{
1412 				CDAudio_Pause ();
1413 				BGM_Pause ();
1414 				VID_HandlePause (true);
1415 			}
1416 			else
1417 			{
1418 				CDAudio_Resume ();
1419 				BGM_Resume ();
1420 				VID_HandlePause (false);
1421 			}
1422 			break;
1423 
1424 		case svc_signonnum:
1425 			i = MSG_ReadByte ();
1426 			if (i <= cls.signon)
1427 				Host_Error ("Received signon %i when at %i", i, cls.signon);
1428 			cls.signon = i;
1429 			CL_SignonReply ();
1430 			break;
1431 
1432 		case svc_killedmonster:
1433 			cl.stats[STAT_MONSTERS]++;
1434 			break;
1435 
1436 		case svc_foundsecret:
1437 			cl.stats[STAT_SECRETS]++;
1438 			break;
1439 
1440 		case svc_updatestat:
1441 			i = MSG_ReadByte ();
1442 			if (i < 0 || i >= MAX_CL_STATS)
1443 				Sys_Error ("svc_updatestat: %i is invalid", i);
1444 			cl.stats[i] = MSG_ReadLong ();
1445 			break;
1446 
1447 		case svc_spawnstaticsound:
1448 			CL_ParseStaticSound ();
1449 			break;
1450 
1451 		case svc_cdtrack:
1452 			cl.cdtrack = MSG_ReadByte ();
1453 			cl.looptrack = MSG_ReadByte ();
1454 			if (q_strcasecmp(bgmtype.string,"cd") != 0)
1455 				CDAudio_Stop ();
1456 			else if ((cls.demoplayback || cls.demorecording) &&
1457 						cls.forcetrack != -1)
1458 				CDAudio_Play ((byte)cls.forcetrack, true);
1459 			else	CDAudio_Play ((byte)cl.cdtrack, true);
1460 			break;
1461 
1462 		case svc_midi_name:
1463 			q_strlcpy (cl.midi_name, MSG_ReadString(), sizeof(cl.midi_name));
1464 			if (q_strcasecmp(bgmtype.string,"midi") != 0)
1465 				BGM_Stop();
1466 			else	BGM_PlayMIDIorMusic(cl.midi_name);
1467 			break;
1468 
1469 		case svc_toggle_statbar:
1470 			break;
1471 
1472 		case svc_intermission:
1473 			CL_SetupIntermission (MSG_ReadByte());
1474 			vid.recalc_refdef = true;	// go to full screen
1475 			break;
1476 
1477 		/*
1478 		case svc_finale:
1479 			cl.intermission = 2;
1480 			cl.completed_time = cl.time;
1481 			vid.recalc_refdef = true;	// go to full screen
1482 			SCR_CenterPrint (MSG_ReadString ());
1483 			break;
1484 
1485 		case svc_cutscene:
1486 			cl.intermission = 3;
1487 			cl.completed_time = cl.time;
1488 			vid.recalc_refdef = true;	// go to full screen
1489 			SCR_CenterPrint (MSG_ReadString ());
1490 			break;
1491 
1492 		case svc_sellscreen:
1493 			Cmd_ExecuteString ("help", src_command);
1494 			break;
1495 		*/
1496 
1497 		case svc_set_view_flags:
1498 			cl.viewent.drawflags |= MSG_ReadByte();
1499 			break;
1500 
1501 		case svc_clear_view_flags:
1502 			cl.viewent.drawflags &= ~MSG_ReadByte();
1503 			break;
1504 
1505 		case svc_start_effect:
1506 			CL_ParseEffect();
1507 			break;
1508 		case svc_end_effect:
1509 			CL_EndEffect();
1510 			break;
1511 
1512 		case svc_plaque:
1513 			CL_Plaque();
1514 			break;
1515 
1516 		case svc_particle_explosion:
1517 			CL_ParticleExplosion();
1518 			break;
1519 
1520 		case svc_set_view_tint:
1521 			i = MSG_ReadByte();
1522 			cl.viewent.colorshade = i;
1523 			break;
1524 
1525 		case svc_reference:
1526 		  {	short RemovePlace, OrigPlace, NewPlace, AddedIndex;
1527 
1528 			packet_loss = false;
1529 			cl.last_frame = cl.current_frame;
1530 			cl.last_sequence = cl.current_sequence;
1531 			cl.current_frame = MSG_ReadByte();
1532 			cl.current_sequence = MSG_ReadByte();
1533 			if (cl.need_build == 2)
1534 			{
1535 			//	Con_Printf("CL: NB2 CL(%d,%d) R(%d)\n",
1536 			//		cl.current_sequence, cl.current_frame, cl.reference_frame);
1537 				cl.frames[0].count = cl.frames[1].count = cl.frames[2].count = 0;
1538 				cl.need_build = 1;
1539 				cl.reference_frame = cl.current_frame;
1540 			}
1541 			else if (cl.last_sequence != cl.current_sequence)
1542 			{
1543 			//	Con_Printf("CL: Sequence CL(%d,%d) R(%d)\n",
1544 			//		cl.current_sequence, cl.current_frame, cl.reference_frame);
1545 				if (cl.reference_frame >= 1 && cl.reference_frame <= MAX_FRAMES)
1546 				{
1547 					RemovePlace = OrigPlace = NewPlace = AddedIndex = 0;
1548 					for (i = 0; i < cl.num_entities; i++)
1549 					{
1550 						if (RemovePlace >= cl.NumToRemove ||
1551 						    cl.RemoveList[RemovePlace] != i)
1552 						{
1553 							if (NewPlace < cl.frames[1].count &&
1554 							    cl.frames[1].states[NewPlace].index == i)
1555 							{
1556 								cl.frames[2].states[AddedIndex] =
1557 									cl.frames[1].states[NewPlace];
1558 								AddedIndex++;
1559 								cl.frames[2].count++;
1560 							}
1561 							else if (OrigPlace < cl.frames[0].count &&
1562 								 cl.frames[0].states[OrigPlace].index == i)
1563 							{
1564 								cl.frames[2].states[AddedIndex] =
1565 									cl.frames[0].states[OrigPlace];
1566 								AddedIndex++;
1567 								cl.frames[2].count++;
1568 							}
1569 						}
1570 						else	RemovePlace++;
1571 
1572 						if (cl.frames[0].states[OrigPlace].index == i)
1573 							OrigPlace++;
1574 						if (cl.frames[1].states[NewPlace].index == i)
1575 							NewPlace++;
1576 					}
1577 					cl.frames[0] = cl.frames[2];
1578 				}
1579 				cl.frames[1].count = cl.frames[2].count = 0;
1580 				cl.need_build = 1;
1581 				cl.reference_frame = cl.current_frame;
1582 			}
1583 			else
1584 			{
1585 			//	Con_Printf("CL: Normal CL(%d,%d) R(%d)\n",
1586 			//		cl.current_sequence, cl.current_frame,cl.reference_frame);
1587 				cl.need_build = 0;
1588 			}
1589 
1590 			for (i = 1, ent = cl_entities+1; i < cl.num_entities; i++, ent++)
1591 				ent->baseline.flags &= ~BE_ON;
1592 			for (i = 0; i < cl.frames[0].count; i++)
1593 			{
1594 				ent = CL_EntityNum (cl.frames[0].states[i].index);
1595 				ent->model = cl.model_precache[cl.frames[0].states[i].modelindex];
1596 				ent->baseline.flags |= BE_ON;
1597 			}
1598 		  }	break;
1599 
1600 		case svc_clear_edicts:
1601 			j = MSG_ReadByte();
1602 			if (cl.need_build)
1603 				cl.NumToRemove = j;
1604 			for (i = 0; i < j; i++)
1605 			{
1606 				k = MSG_ReadShort();
1607 				if (cl.need_build)
1608 					cl.RemoveList[i] = k;
1609 				ent = CL_EntityNum (k);
1610 				ent->baseline.flags &= ~BE_ON;
1611 			}
1612 			break;
1613 
1614 		case svc_update_inv:
1615 			sc1 = sc2 = 0;
1616 
1617 			test = MSG_ReadByte();
1618 			if (test & 1)
1619 				sc1 |= ((int)MSG_ReadByte());
1620 			if (test & 2)
1621 				sc1 |= ((int)MSG_ReadByte())<<8;
1622 			if (test & 4)
1623 				sc1 |= ((int)MSG_ReadByte())<<16;
1624 			if (test & 8)
1625 				sc1 |= ((int)MSG_ReadByte())<<24;
1626 			if (test & 16)
1627 				sc2 |= ((int)MSG_ReadByte());
1628 			if (test & 32)
1629 				sc2 |= ((int)MSG_ReadByte())<<8;
1630 			if (test & 64)
1631 				sc2 |= ((int)MSG_ReadByte())<<16;
1632 			if (test & 128)
1633 				sc2 |= ((int)MSG_ReadByte())<<24;
1634 
1635 			if (sc1 & SC1_HEALTH)
1636 				cl.v.health = MSG_ReadShort();
1637 			if (sc1 & SC1_LEVEL)
1638 				cl.v.level = MSG_ReadByte();
1639 			if (sc1 & SC1_INTELLIGENCE)
1640 				cl.v.intelligence = MSG_ReadByte();
1641 			if (sc1 & SC1_WISDOM)
1642 				cl.v.wisdom = MSG_ReadByte();
1643 			if (sc1 & SC1_STRENGTH)
1644 				cl.v.strength = MSG_ReadByte();
1645 			if (sc1 & SC1_DEXTERITY)
1646 				cl.v.dexterity = MSG_ReadByte();
1647 			if (sc1 & SC1_WEAPON)
1648 				cl.v.weapon = MSG_ReadByte();
1649 			if (sc1 & SC1_BLUEMANA)
1650 				cl.v.bluemana = MSG_ReadByte();
1651 			if (sc1 & SC1_GREENMANA)
1652 				cl.v.greenmana = MSG_ReadByte();
1653 			if (sc1 & SC1_EXPERIENCE)
1654 				cl.v.experience = MSG_ReadLong();
1655 			if (sc1 & SC1_CNT_TORCH)
1656 				cl.v.cnt_torch = MSG_ReadByte();
1657 			if (sc1 & SC1_CNT_H_BOOST)
1658 				cl.v.cnt_h_boost = MSG_ReadByte();
1659 			if (sc1 & SC1_CNT_SH_BOOST)
1660 				cl.v.cnt_sh_boost = MSG_ReadByte();
1661 			if (sc1 & SC1_CNT_MANA_BOOST)
1662 				cl.v.cnt_mana_boost = MSG_ReadByte();
1663 			if (sc1 & SC1_CNT_TELEPORT)
1664 				cl.v.cnt_teleport = MSG_ReadByte();
1665 			if (sc1 & SC1_CNT_TOME)
1666 				cl.v.cnt_tome = MSG_ReadByte();
1667 			if (sc1 & SC1_CNT_SUMMON)
1668 				cl.v.cnt_summon = MSG_ReadByte();
1669 			if (sc1 & SC1_CNT_INVISIBILITY)
1670 				cl.v.cnt_invisibility = MSG_ReadByte();
1671 			if (sc1 & SC1_CNT_GLYPH)
1672 				cl.v.cnt_glyph = MSG_ReadByte();
1673 			if (sc1 & SC1_CNT_HASTE)
1674 				cl.v.cnt_haste = MSG_ReadByte();
1675 			if (sc1 & SC1_CNT_BLAST)
1676 				cl.v.cnt_blast = MSG_ReadByte();
1677 			if (sc1 & SC1_CNT_POLYMORPH)
1678 				cl.v.cnt_polymorph = MSG_ReadByte();
1679 			if (sc1 & SC1_CNT_FLIGHT)
1680 				cl.v.cnt_flight = MSG_ReadByte();
1681 			if (sc1 & SC1_CNT_CUBEOFFORCE)
1682 				cl.v.cnt_cubeofforce = MSG_ReadByte();
1683 			if (sc1 & SC1_CNT_INVINCIBILITY)
1684 				cl.v.cnt_invincibility = MSG_ReadByte();
1685 			if (sc1 & SC1_ARTIFACT_ACTIVE)
1686 				cl.v.artifact_active = MSG_ReadFloat();
1687 			if (sc1 & SC1_ARTIFACT_LOW)
1688 				cl.v.artifact_low = MSG_ReadFloat();
1689 			if (sc1 & SC1_MOVETYPE)
1690 				cl.v.movetype = MSG_ReadByte();
1691 			if (sc1 & SC1_CAMERAMODE)
1692 				cl.v.cameramode = MSG_ReadByte();
1693 			if (sc1 & SC1_HASTED)
1694 				cl.v.hasted = MSG_ReadFloat();
1695 			if (sc1 & SC1_INVENTORY)
1696 				cl.v.inventory = MSG_ReadByte();
1697 			if (sc1 & SC1_RINGS_ACTIVE)
1698 				cl.v.rings_active = MSG_ReadFloat();
1699 
1700 			if (sc2 & SC2_RINGS_LOW)
1701 				cl.v.rings_low = MSG_ReadFloat();
1702 			if (sc2 & SC2_AMULET)
1703 				cl.v.armor_amulet = MSG_ReadByte();
1704 			if (sc2 & SC2_BRACER)
1705 				cl.v.armor_bracer = MSG_ReadByte();
1706 			if (sc2 & SC2_BREASTPLATE)
1707 				cl.v.armor_breastplate = MSG_ReadByte();
1708 			if (sc2 & SC2_HELMET)
1709 				cl.v.armor_helmet = MSG_ReadByte();
1710 			if (sc2 & SC2_FLIGHT_T)
1711 				cl.v.ring_flight = MSG_ReadByte();
1712 			if (sc2 & SC2_WATER_T)
1713 				cl.v.ring_water = MSG_ReadByte();
1714 			if (sc2 & SC2_TURNING_T)
1715 				cl.v.ring_turning = MSG_ReadByte();
1716 			if (sc2 & SC2_REGEN_T)
1717 				cl.v.ring_regeneration = MSG_ReadByte();
1718 			if (sc2 & SC2_HASTE_T)
1719 				cl.v.haste_time = MSG_ReadFloat();
1720 			if (sc2 & SC2_TOME_T)
1721 				cl.v.tome_time = MSG_ReadFloat();
1722 			if (sc2 & SC2_PUZZLE1)
1723 				q_snprintf(cl.puzzle_pieces[0], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1724 			if (sc2 & SC2_PUZZLE2)
1725 				q_snprintf(cl.puzzle_pieces[1], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1726 			if (sc2 & SC2_PUZZLE3)
1727 				q_snprintf(cl.puzzle_pieces[2], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1728 			if (sc2 & SC2_PUZZLE4)
1729 				q_snprintf(cl.puzzle_pieces[3], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1730 			if (sc2 & SC2_PUZZLE5)
1731 				q_snprintf(cl.puzzle_pieces[4], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1732 			if (sc2 & SC2_PUZZLE6)
1733 				q_snprintf(cl.puzzle_pieces[5], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1734 			if (sc2 & SC2_PUZZLE7)
1735 				q_snprintf(cl.puzzle_pieces[6], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1736 			if (sc2 & SC2_PUZZLE8)
1737 				q_snprintf(cl.puzzle_pieces[7], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1738 			if (sc2 & SC2_MAXHEALTH)
1739 				cl.v.max_health = MSG_ReadShort();
1740 			if (sc2 & SC2_MAXMANA)
1741 				cl.v.max_mana = MSG_ReadByte();
1742 			if (sc2 & SC2_FLAGS)
1743 				cl.v.flags = MSG_ReadFloat();
1744 
1745 			/* SC2_OBJ, SC2_OBJ2: mission pack objectives
1746 			 * With protocol 18 (PROTOCOL_RAVEN_111), these
1747 			 * bits get set somehow (?!): let's avoid them. */
1748 			if (cl_protocol > PROTOCOL_RAVEN_111)
1749 			{
1750 				if (sc2 & SC2_OBJ)
1751 					cl.info_mask = MSG_ReadLong();
1752 				if (sc2 & SC2_OBJ2)
1753 					cl.info_mask2 = MSG_ReadLong();
1754 			}
1755 
1756 			if ((sc1 & SC1_STAT_BAR) || (sc2 & SC2_STAT_BAR))
1757 				Sbar_Changed();
1758 
1759 			if ((sc1 & SC1_INV) || (sc2 & SC2_INV))
1760 				SB_InvChanged();
1761 			break;
1762 
1763 		case svc_mod_name:
1764 		case svc_skybox:
1765 			MSG_ReadString();
1766 			Con_DPrintf ("Ignored server msg %d (%s)\n", cmd, svc_strings[cmd]);
1767 			break;
1768 		}
1769 	}
1770 }
1771 
1772