1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 
21 #include "q_shared.h"
22 #include "com_public.h"
23 #include "protocol.h"
24 #include "q_msg.h"
25 
26 sizebuf_t	msg_write;
27 byte		msg_write_buffer[MAX_MSGLEN];
28 
29 sizebuf_t	msg_read;
30 byte		msg_read_buffer[MAX_MSGLEN];
31 
32 /*
33 ==============================================================================
34 
35 			MESSAGE IO FUNCTIONS
36 
37 Handles byte ordering and avoids alignment errors
38 ==============================================================================
39 */
40 
41 static const entity_state_t	nullEntityState;
42 static const playerStateEx_t	nullPlayerState;
43 static const usercmd_t		nullUserCmd;
44 
45 
46 /*
47 =============
48 MSG_Init
49 =============
50 */
MSG_Init(void)51 void MSG_Init( void ) {
52 	// initialize default buffers
53 	SZ_Init( &msg_read, msg_read_buffer, sizeof( msg_read_buffer ) );
54 	SZ_Init( &msg_write, msg_write_buffer, sizeof( msg_write_buffer ) );
55 
56 	// don't allow them to overflow
57 	msg_read.allowoverflow = qfalse;
58 	msg_write.allowoverflow = qfalse;
59 
60 }
61 
62 
63 //
64 // writing functions
65 //
66 
67 /*
68 =============
69 MSG_BeginWriting
70 =============
71 */
MSG_BeginWriting(void)72 void MSG_BeginWriting( void ) {
73 	msg_write.cursize = 0;
74 	msg_write.bitpos = 0;
75 	msg_write.overflowed = qfalse;
76 }
77 
78 /*
79 =============
80 MSG_WriteChar
81 =============
82 */
MSG_WriteChar(int c)83 void MSG_WriteChar( int c ) {
84 	byte	*buf;
85 
86 #ifdef PARANOID
87 	if( c < -128 || c > 127 )
88 		Com_Error( ERR_FATAL, "MSG_WriteChar: range error" );
89 #endif
90 
91 	buf = SZ_GetSpace( &msg_write, 1 );
92 	buf[0] = c;
93 }
94 
95 /*
96 =============
97 MSG_WriteByte
98 =============
99 */
MSG_WriteByte(int c)100 void MSG_WriteByte( int c ) {
101 	byte	*buf;
102 
103 #ifdef PARANOID
104 	if( c < 0 || c > 255 )
105 		Com_Error( ERR_FATAL, "MSG_WriteByte: range error" );
106 #endif
107 
108 	buf = SZ_GetSpace( &msg_write, 1 );
109 	buf[0] = c;
110 }
111 
112 /*
113 =============
114 MSG_WriteShort
115 =============
116 */
MSG_WriteShort(int c)117 void MSG_WriteShort( int c ) {
118 	byte	*buf;
119 
120 #ifdef PARANOID
121 	if (c < ((short)0x8000) || c > (short)0x7fff)
122 		Com_Error (ERR_FATAL, "MSG_WriteShort: range error");
123 #endif
124 
125 	buf = SZ_GetSpace( &msg_write, 2 );
126 	buf[0] = c & 0xff;
127 	buf[1] = c >> 8;
128 }
129 
130 /*
131 =============
132 MSG_WriteLong
133 =============
134 */
MSG_WriteLong(int c)135 void MSG_WriteLong( int c ) {
136 	byte	*buf;
137 
138 	buf = SZ_GetSpace( &msg_write, 4 );
139 	buf[0] = c & 0xff;
140 	buf[1] = ( c >> 8 ) & 0xff;
141 	buf[2] = ( c >> 16 ) & 0xff;
142 	buf[3] = c >> 24;
143 }
144 
145 /*
146 =============
147 MSG_WriteString
148 =============
149 */
MSG_WriteString(const char * string)150 void MSG_WriteString( const char *string ) {
151 	int length;
152 	int c;
153 
154 	if( !string ) {
155 		MSG_WriteByte( 0 );
156 		return;
157 	}
158 
159 	length = strlen( string );
160 	if( length > MAX_NET_STRING - 1 ) {
161 		Com_WPrintf( "MSG_WriteString: overflow: %d chars", length );
162 		MSG_WriteByte( 0 );
163 		return;
164 	}
165 
166 	while( *string ) {
167 		c = *string++;
168 		if( c == '\xFF' ) {
169 			c = '.';
170 		}
171 		MSG_WriteByte( c );
172 	}
173 
174 	MSG_WriteByte( 0 );
175 }
176 
177 /*
178 =============
179 MSG_WriteCoord
180 =============
181 */
MSG_WriteCoord(float f)182 void MSG_WriteCoord( float f ) {
183 	MSG_WriteShort( ( int )( f * 8 ) );
184 }
185 
186 /*
187 =============
188 MSG_WritePos
189 =============
190 */
MSG_WritePos(const vec3_t pos)191 void MSG_WritePos( const vec3_t pos ) {
192 	MSG_WriteShort( ( int )( pos[0] * 8 ) );
193 	MSG_WriteShort( ( int )( pos[1] * 8 ) );
194 	MSG_WriteShort( ( int )( pos[2] * 8 ) );
195 }
196 
197 /*
198 =============
199 MSG_WriteAngle
200 =============
201 */
MSG_WriteAngle(float f)202 void MSG_WriteAngle( float f ) {
203 	MSG_WriteByte( ( int )( f * 256 / 360 ) & 255 );
204 }
205 
206 /*
207 =============
208 MSG_WriteAngle16
209 =============
210 */
MSG_WriteAngle16(float f)211 void MSG_WriteAngle16( float f ) {
212 	MSG_WriteShort( ANGLE2SHORT( f ) );
213 }
214 
215 /*
216 =============
217 MSG_WriteDeltaUsercmd
218 =============
219 */
MSG_WriteDeltaUsercmd(const usercmd_t * from,const usercmd_t * cmd)220 int MSG_WriteDeltaUsercmd( const usercmd_t *from, const usercmd_t *cmd ) {
221 	int		bits;
222 
223 	if( !from ) {
224 		from = &nullUserCmd;
225 	}
226 
227 //
228 // send the movement message
229 //
230 	bits = 0;
231 	if( cmd->angles[0] != from->angles[0] )
232 		bits |= CM_ANGLE1;
233 	if( cmd->angles[1] != from->angles[1] )
234 		bits |= CM_ANGLE2;
235 	if( cmd->angles[2] != from->angles[2] )
236 		bits |= CM_ANGLE3;
237 	if( cmd->forwardmove != from->forwardmove )
238 		bits |= CM_FORWARD;
239 	if( cmd->sidemove != from->sidemove )
240 		bits |= CM_SIDE;
241 	if( cmd->upmove != from->upmove )
242 		bits |= CM_UP;
243 	if( cmd->buttons != from->buttons )
244 		bits |= CM_BUTTONS;
245 	if( cmd->impulse != from->impulse )
246 		bits |= CM_IMPULSE;
247 
248     MSG_WriteByte ( bits );
249 
250 	if( bits & CM_ANGLE1 )
251 		MSG_WriteShort( cmd->angles[0] );
252 	if( bits & CM_ANGLE2 )
253 		MSG_WriteShort( cmd->angles[1] );
254 	if( bits & CM_ANGLE3 )
255 		MSG_WriteShort( cmd->angles[2] );
256 
257 	if( bits & CM_FORWARD )
258 		MSG_WriteShort( cmd->forwardmove );
259 	if( bits & CM_SIDE )
260 	  	MSG_WriteShort( cmd->sidemove );
261 	if( bits & CM_UP )
262 		MSG_WriteShort( cmd->upmove );
263 
264  	if( bits & CM_BUTTONS )
265 	  	MSG_WriteByte( cmd->buttons );
266  	if( bits & CM_IMPULSE )
267 	    MSG_WriteByte( cmd->impulse );
268 
269     MSG_WriteByte( cmd->msec );
270 
271 	return bits;
272 }
273 
274 /*
275 =============
276 MSG_WriteBits
277 =============
278 */
MSG_WriteBits(int value,int bits)279 void MSG_WriteBits( int value, int bits ) {
280 	int i, bitpos;
281 
282 	if( bits == 0 || bits < -31 || bits > 32 ) {
283 		Com_Error( ERR_FATAL, "MSG_WriteBits: bad bits: %d", bits );
284 	}
285 
286 	if( msg_write.maxsize - msg_write.cursize < 4 ) {
287 		Com_Error( ERR_FATAL, "MSG_WriteBits: overflow" );
288 	}
289 
290 	if( bits < 0 ) {
291 		bits = -bits;
292 	}
293 
294 	bitpos = msg_write.bitpos;
295 	if( ( bitpos & 7 ) == 0 ) {
296 		/* optimized case */
297 		switch( bits ) {
298 		case 8:
299 			MSG_WriteByte( value );
300 			return;
301 		case 16:
302 			MSG_WriteShort( value );
303 			return;
304 		case 32:
305 			MSG_WriteLong( value );
306 			return;
307 		default:
308 			break;
309 		}
310 	}
311 	for( i = 0; i < bits; i++, bitpos++ ) {
312 		if( ( bitpos & 7 ) == 0 ) {
313 			msg_write.data[ bitpos >> 3 ] = 0;
314 		}
315 		msg_write.data[ bitpos >> 3 ] |= ( value & 1 ) << ( bitpos & 7 );
316 		value >>= 1;
317 	}
318 	msg_write.bitpos = bitpos;
319 	msg_write.cursize = ( bitpos + 7 ) >> 3;
320 }
321 
322 /*
323 =============
324 MSG_WriteDeltaUsercmd_Enhanced
325 =============
326 */
MSG_WriteDeltaUsercmd_Enhanced(const usercmd_t * from,const usercmd_t * cmd)327 int MSG_WriteDeltaUsercmd_Enhanced( const usercmd_t *from, const usercmd_t *cmd ) {
328 	int		bits, delta;
329 
330 	if( !from ) {
331 		from = &nullUserCmd;
332 	}
333 
334 //
335 // send the movement message
336 //
337 	bits = 0;
338 	if( cmd->angles[0] != from->angles[0] )
339 		bits |= CM_ANGLE1;
340 	if( cmd->angles[1] != from->angles[1] )
341 		bits |= CM_ANGLE2;
342 	if( cmd->angles[2] != from->angles[2] )
343 		bits |= CM_ANGLE3;
344 	if( cmd->forwardmove != from->forwardmove )
345 		bits |= CM_FORWARD;
346 	if( cmd->sidemove != from->sidemove )
347 		bits |= CM_SIDE;
348 	if( cmd->upmove != from->upmove )
349 		bits |= CM_UP;
350 	if( cmd->buttons != from->buttons )
351 		bits |= CM_BUTTONS;
352 	if( cmd->msec != from->msec )
353 		bits |= CM_IMPULSE;
354 
355 	if( !bits ) {
356 		MSG_WriteBits( 0, 1 );
357 		return 0;
358 	}
359 
360 	MSG_WriteBits( 1, 1 );
361     MSG_WriteBits( bits, 8 );
362 
363 	if( bits & CM_ANGLE1 ) {
364 		delta = cmd->angles[0] - from->angles[0];
365 		if( delta >= -128 && delta <= 127 ) {
366 			MSG_WriteBits( 1, 1 );
367 			MSG_WriteBits( delta, -8 );
368 		} else {
369 			MSG_WriteBits( 0, 1 );
370 			MSG_WriteBits( cmd->angles[0], -16 );
371 		}
372 	}
373 	if( bits & CM_ANGLE2 ) {
374 		delta = cmd->angles[1] - from->angles[1];
375 		if( delta >= -128 && delta <= 127 ) {
376 			MSG_WriteBits( 1, 1 );
377 			MSG_WriteBits( delta, -8 );
378 		} else {
379 			MSG_WriteBits( 0, 1 );
380 			MSG_WriteBits( cmd->angles[1], -16 );
381 		}
382 	}
383 	if( bits & CM_ANGLE3 ) {
384 		MSG_WriteBits( cmd->angles[2], -16 );
385 	}
386 
387 	if( bits & CM_FORWARD ) {
388 		MSG_WriteBits( cmd->forwardmove, -16 );
389 	}
390 	if( bits & CM_SIDE ) {
391 		MSG_WriteBits( cmd->sidemove, -16 );
392 	}
393 	if( bits & CM_UP ) {
394 		MSG_WriteBits( cmd->upmove, -16 );
395 	}
396 
397 	if( bits & CM_BUTTONS ) {
398 		MSG_WriteBits( cmd->buttons, 8 );
399 	}
400 	if( bits & CM_IMPULSE ) {
401 		MSG_WriteBits( cmd->msec, 8 );
402 	}
403 
404 	return bits;
405 }
406 
MSG_WriteDir(const vec3_t dir)407 void MSG_WriteDir( const vec3_t dir ) {
408 	int		best;
409 
410 	best = DirToByte( dir );
411 	MSG_WriteByte( best );
412 }
413 
MSG_WriteData(const void * data,int length)414 void MSG_WriteData( const void *data, int length ) {
415 	memcpy( SZ_GetSpace( &msg_write, length ), data, length );
416 }
417 
418 /* values transmitted over network are discrete, so
419  * we use special macros to check for delta conditions
420  */
421 #define Delta_Angle( a, b ) \
422   ( ((int)((a)*256/360) & 255) != ((int)((b)*256/360) & 255) )
423 
424 #define Delta_Coord( a, b ) \
425   ( (int)((b)*8) != (int)((a)*8) )
426 
427 #define Delta_Pos( a, b ) \
428   ( (int)((b)[0]*8) != (int)((a)[0]*8) || \
429     (int)((b)[1]*8) != (int)((a)[1]*8) || \
430     (int)((b)[2]*8) != (int)((a)[2]*8) )
431 
432 #define Delta_VecChar( a, b ) \
433   ( (int)((b)[0]*4) != (int)((a)[0]*4) || \
434 	(int)((b)[1]*4) != (int)((a)[1]*4) || \
435 	(int)((b)[2]*4) != (int)((a)[2]*4) )
436 
437 #define Delta_Blend( a, b ) \
438   ( (int)((b)[0]*255) != (int)((a)[0]*255) || \
439     (int)((b)[1]*255) != (int)((a)[1]*255) || \
440     (int)((b)[2]*255) != (int)((a)[2]*255) || \
441     (int)((b)[3]*255) != (int)((a)[3]*255) )
442 
443 #define Delta_Angle16( a, b ) \
444 	( ANGLE2SHORT(b) != ANGLE2SHORT(a) )
445 
446 #define Delta_VecAngle16( a, b ) \
447   ( ANGLE2SHORT((b)[0]) != ANGLE2SHORT((a)[0]) || \
448     ANGLE2SHORT((b)[1]) != ANGLE2SHORT((a)[1]) || \
449     ANGLE2SHORT((b)[2]) != ANGLE2SHORT((a)[2]) )
450 
451 #define Delta_Fov( a, b ) \
452 	( (int)(b) != (int)(a) )
453 
454 /*
455 ==================
456 MSG_WriteDeltaEntity
457 
458 Writes part of a packetentities message.
459 Can delta from either a baseline or a previous packet_entity
460 ==================
461 */
MSG_WriteDeltaEntity(const entity_state_t * from,entity_state_t * to,msgEsFlags_t flags)462 void MSG_WriteDeltaEntity( const entity_state_t *from, entity_state_t *to, msgEsFlags_t flags ) {
463 	int		bits;
464 
465 	if( !from && !to ) {
466 		Com_Error( ERR_DROP, "MSG_WriteDeltaEntity: NULL" );
467 	}
468 
469 	if( !to ) {
470 		bits = U_REMOVE;
471 		if( from->number >= 256 ) {
472 			bits |= U_NUMBER16 | U_MOREBITS1;
473 		}
474 
475 		MSG_WriteByte( bits & 255 );
476 		if( bits & 0x0000ff00 )
477 			MSG_WriteByte( ( bits >> 8 ) & 255 );
478 
479 		if( bits & U_NUMBER16 )
480 			MSG_WriteShort( from->number );
481 		else
482 			MSG_WriteByte( from->number );
483 
484 		return; // remove entity
485 	}
486 
487 	if( to->number < 1 || to->number >= MAX_EDICTS ) {
488 		Com_Error( ERR_DROP, "MSG_WriteDeltaEntity: bad entity number %i", to->number );
489 	}
490 
491 	if( !from ) {
492 		from = &nullEntityState;
493 	}
494 
495 // send an update
496 	bits = 0;
497 
498 	if( !( flags & MSG_ES_FIRSTPERSON ) ) {
499 		if( Delta_Coord( to->origin[0], from->origin[0] ) )
500 			bits |= U_ORIGIN1;
501 		if( Delta_Coord( to->origin[1], from->origin[1] ) )
502 			bits |= U_ORIGIN2;
503 		if( Delta_Coord( to->origin[2], from->origin[2] ) )
504 			bits |= U_ORIGIN3;
505 
506 		if( Delta_Angle( to->angles[0], from->angles[0] ) )
507 			bits |= U_ANGLE1;
508 		if( Delta_Angle( to->angles[1], from->angles[1] ) )
509 			bits |= U_ANGLE2;
510 		if( Delta_Angle( to->angles[2], from->angles[2] ) )
511 			bits |= U_ANGLE3;
512 	} else {
513 		/* clear delta state */
514 		VectorCopy( from->origin, to->origin );
515 		VectorCopy( from->angles, to->angles );
516 	}
517 
518 	if ( to->skinnum != from->skinnum ) {
519 		if ((unsigned)to->skinnum < 256)
520 			bits |= U_SKIN8;
521 		else if ((unsigned)to->skinnum < 0x10000)
522 			bits |= U_SKIN16;
523 		else
524 			bits |= (U_SKIN8|U_SKIN16);
525 	}
526 
527 	if ( to->frame != from->frame ) {
528 		if (to->frame < 256)
529 			bits |= U_FRAME8;
530 		else
531 			bits |= U_FRAME16;
532 	}
533 
534 	if ( to->effects != from->effects ) {
535 		if (to->effects < 256)
536 			bits |= U_EFFECTS8;
537 		else if (to->effects < 0x8000)
538 			bits |= U_EFFECTS16;
539 		else
540 			bits |= U_EFFECTS8|U_EFFECTS16;
541 	}
542 
543 	if ( to->renderfx != from->renderfx ) {
544 		if (to->renderfx < 256)
545 			bits |= U_RENDERFX8;
546 		else if (to->renderfx < 0x8000)
547 			bits |= U_RENDERFX16;
548 		else
549 			bits |= U_RENDERFX8|U_RENDERFX16;
550 	}
551 
552 	if ( to->solid != from->solid )
553 		bits |= U_SOLID;
554 
555 	// event is not delta compressed, just 0 compressed
556 	if ( to->event  )
557 		bits |= U_EVENT;
558 
559 	if ( to->modelindex != from->modelindex )
560 		bits |= U_MODEL;
561 	if ( to->modelindex2 != from->modelindex2 )
562 		bits |= U_MODEL2;
563 	if ( to->modelindex3 != from->modelindex3 )
564 		bits |= U_MODEL3;
565 	if ( to->modelindex4 != from->modelindex4 )
566 		bits |= U_MODEL4;
567 
568 	if ( to->sound != from->sound )
569 		bits |= U_SOUND;
570 
571 	if( ( to->renderfx & RF_BEAM ) )
572 		bits |= U_OLDORIGIN;
573 
574 	if( flags & MSG_ES_NEWENTITY ) {
575 		if( !( flags & MSG_ES_FIRSTPERSON ) ) {
576 			if( Delta_Pos( to->old_origin, from->old_origin ) ) {
577 				bits |= U_OLDORIGIN;
578 			}
579 		} else {
580 			VectorCopy( from->old_origin, to->old_origin );
581 		}
582 	}
583 
584 	//
585 	// write the message
586 	//
587 	if( !bits && !( flags & MSG_ES_FORCE ) )
588 		return;		// nothing to send!
589 
590 	//----------
591 
592 	if (to->number >= 256)
593 		bits |= U_NUMBER16;		// number8 is implicit otherwise
594 
595 	if (bits & 0xff000000)
596 		bits |= U_MOREBITS3 | U_MOREBITS2 | U_MOREBITS1;
597 	else if (bits & 0x00ff0000)
598 		bits |= U_MOREBITS2 | U_MOREBITS1;
599 	else if (bits & 0x0000ff00)
600 		bits |= U_MOREBITS1;
601 
602 	MSG_WriteByte (bits&255 );
603 
604 	if (bits & 0xff000000) {
605 		MSG_WriteByte ((bits>>8)&255 );
606 		MSG_WriteByte ((bits>>16)&255 );
607 		MSG_WriteByte ((bits>>24)&255 );
608 	}
609 	else if (bits & 0x00ff0000) {
610 		MSG_WriteByte ((bits>>8)&255 );
611 		MSG_WriteByte ((bits>>16)&255 );
612 	}
613 	else if (bits & 0x0000ff00) {
614 		MSG_WriteByte ((bits>>8)&255 );
615 	}
616 
617 	//----------
618 
619 	if (bits & U_NUMBER16)
620 		MSG_WriteShort (to->number);
621 	else
622 		MSG_WriteByte (to->number);
623 
624 	if (bits & U_MODEL)
625 		MSG_WriteByte (to->modelindex);
626 	if (bits & U_MODEL2)
627 		MSG_WriteByte (to->modelindex2);
628 	if (bits & U_MODEL3)
629 		MSG_WriteByte (to->modelindex3);
630 	if (bits & U_MODEL4)
631 		MSG_WriteByte (to->modelindex4);
632 
633 	if (bits & U_FRAME8)
634 		MSG_WriteByte (to->frame);
635 	if (bits & U_FRAME16)
636 		MSG_WriteShort (to->frame);
637 
638 	if ((bits & (U_SKIN8|U_SKIN16)) == (U_SKIN8|U_SKIN16) )		//used for laser colors
639 		MSG_WriteLong (to->skinnum);
640 	else if (bits & U_SKIN8)
641 		MSG_WriteByte (to->skinnum);
642 	else if (bits & U_SKIN16)
643 		MSG_WriteShort (to->skinnum);
644 
645 
646 	if ( (bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16) )
647 		MSG_WriteLong (to->effects);
648 	else if (bits & U_EFFECTS8)
649 		MSG_WriteByte (to->effects);
650 	else if (bits & U_EFFECTS16)
651 		MSG_WriteShort (to->effects);
652 
653 	if ( (bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16) )
654 		MSG_WriteLong (to->renderfx);
655 	else if (bits & U_RENDERFX8)
656 		MSG_WriteByte (to->renderfx);
657 	else if (bits & U_RENDERFX16)
658 		MSG_WriteShort (to->renderfx);
659 
660 	if (bits & U_ORIGIN1)
661 		MSG_WriteCoord (to->origin[0]);
662 	if (bits & U_ORIGIN2)
663 		MSG_WriteCoord (to->origin[1]);
664 	if (bits & U_ORIGIN3)
665 		MSG_WriteCoord (to->origin[2]);
666 
667 	if (bits & U_ANGLE1)
668 		MSG_WriteAngle(to->angles[0]);
669 	if (bits & U_ANGLE2){
670 		MSG_WriteAngle(to->angles[1]);
671 	}
672 	if (bits & U_ANGLE3)
673 		MSG_WriteAngle(to->angles[2]);
674 
675 	if (bits & U_OLDORIGIN) {
676 		MSG_WriteCoord (to->old_origin[0]);
677 		MSG_WriteCoord (to->old_origin[1]);
678 		MSG_WriteCoord (to->old_origin[2]);
679 	}
680 
681 	if (bits & U_SOUND)
682 		MSG_WriteByte (to->sound);
683 	if (bits & U_EVENT)
684 		MSG_WriteByte (to->event);
685 	if (bits & U_SOLID)
686 		MSG_WriteShort (to->solid);
687 }
688 
689 /*
690 ==================
691 MSG_WriteDeltaPlayerstate_Default
692 ==================
693 */
MSG_WriteDeltaPlayerstate_Default(const player_state_t * from,const player_state_t * to)694 void MSG_WriteDeltaPlayerstate_Default( const player_state_t *from, const player_state_t *to ) {
695 	int				i;
696 	int				pflags;
697 	int				statbits;
698 
699 	if( !to ) {
700 		Com_Error( ERR_DROP, "MSG_WriteDeltaPlayerstate_Default: NULL" );
701 	}
702 
703 	if( !from ) {
704 		from = &nullPlayerState.ps;
705 	}
706 
707 	//
708 	// determine what needs to be sent
709 	//
710 	pflags = 0;
711 
712 	if( to->pmove.pm_type != from->pmove.pm_type )
713 		pflags |= PS_M_TYPE;
714 
715 	if( to->pmove.origin[0] != from->pmove.origin[0] ||
716 		to->pmove.origin[1] != from->pmove.origin[1] ||
717 		to->pmove.origin[2] != from->pmove.origin[2] )
718 	{
719 		pflags |= PS_M_ORIGIN;
720 	}
721 
722 	if( to->pmove.velocity[0] != from->pmove.velocity[0] ||
723 		to->pmove.velocity[1] != from->pmove.velocity[1] ||
724 		to->pmove.velocity[2] != from->pmove.velocity[2] )
725 	{
726 		pflags |= PS_M_VELOCITY;
727 	}
728 
729 	if( to->pmove.pm_time != from->pmove.pm_time )
730 		pflags |= PS_M_TIME;
731 
732 	if( to->pmove.pm_flags != from->pmove.pm_flags )
733 		pflags |= PS_M_FLAGS;
734 
735 	if( to->pmove.gravity != from->pmove.gravity )
736 		pflags |= PS_M_GRAVITY;
737 
738 	if( to->pmove.delta_angles[0] != from->pmove.delta_angles[0] ||
739 		to->pmove.delta_angles[1] != from->pmove.delta_angles[1] ||
740 		to->pmove.delta_angles[2] != from->pmove.delta_angles[2] )
741 	{
742 		pflags |= PS_M_DELTA_ANGLES;
743 	}
744 
745 	if( Delta_VecChar( to->viewoffset, from->viewoffset ) ) {
746 		pflags |= PS_VIEWOFFSET;
747 	}
748 
749 	if( Delta_VecAngle16( to->viewangles, from->viewangles ) ) {
750 		pflags |= PS_VIEWANGLES;
751 	}
752 
753 	if( Delta_VecChar( to->kick_angles, from->kick_angles ) ) {
754 		pflags |= PS_KICKANGLES;
755 	}
756 
757 	if( Delta_Blend( to->blend, from->blend ) ) {
758 		pflags |= PS_BLEND;
759 	}
760 
761 	if( Delta_Fov( to->fov, from->fov ) )
762 		pflags |= PS_FOV;
763 
764 	if( to->rdflags != from->rdflags )
765 		pflags |= PS_RDFLAGS;
766 
767 	if( to->gunframe != from->gunframe ||
768 		Delta_VecChar( to->gunoffset, from->gunoffset ) ||
769 		Delta_VecChar( to->gunangles, from->gunangles ) )
770 	{
771 		pflags |= PS_WEAPONFRAME;
772 	}
773 
774 	if( to->gunindex != from->gunindex )
775 		pflags |= PS_WEAPONINDEX;
776 
777 
778 	//
779 	// write it
780 	//
781 	MSG_WriteShort( pflags );
782 
783 	//
784 	// write the pmove_state_t
785 	//
786 	if( pflags & PS_M_TYPE )
787 		MSG_WriteByte( to->pmove.pm_type );
788 
789 	if( pflags & PS_M_ORIGIN ) {
790 		MSG_WriteShort( to->pmove.origin[0] );
791 		MSG_WriteShort( to->pmove.origin[1] );
792 		MSG_WriteShort( to->pmove.origin[2] );
793 	}
794 
795 	if( pflags & PS_M_VELOCITY ) {
796 		MSG_WriteShort( to->pmove.velocity[0] );
797 		MSG_WriteShort( to->pmove.velocity[1] );
798 		MSG_WriteShort( to->pmove.velocity[2] );
799 	}
800 
801 	if( pflags & PS_M_TIME )
802 		MSG_WriteByte( to->pmove.pm_time );
803 
804 	if( pflags & PS_M_FLAGS )
805 		MSG_WriteByte( to->pmove.pm_flags );
806 
807 	if( pflags & PS_M_GRAVITY )
808 		MSG_WriteShort( to->pmove.gravity );
809 
810 	if( pflags & PS_M_DELTA_ANGLES ) {
811 		MSG_WriteShort( to->pmove.delta_angles[0] );
812 		MSG_WriteShort( to->pmove.delta_angles[1] );
813 		MSG_WriteShort( to->pmove.delta_angles[2] );
814 	}
815 
816 	//
817 	// write the rest of the player_state_t
818 	//
819 	if( pflags & PS_VIEWOFFSET ) {
820 		MSG_WriteChar( to->viewoffset[0] * 4 );
821 		MSG_WriteChar( to->viewoffset[1] * 4 );
822 		MSG_WriteChar( to->viewoffset[2] * 4 );
823 	}
824 
825 	if( pflags & PS_VIEWANGLES ) {
826 		MSG_WriteAngle16( to->viewangles[0] );
827 		MSG_WriteAngle16( to->viewangles[1] );
828 		MSG_WriteAngle16( to->viewangles[2] );
829 	}
830 
831 	if( pflags & PS_KICKANGLES ) {
832 		MSG_WriteChar( to->kick_angles[0] * 4 );
833 		MSG_WriteChar( to->kick_angles[1] * 4 );
834 		MSG_WriteChar( to->kick_angles[2] * 4 );
835 	}
836 
837 	if( pflags & PS_WEAPONINDEX ) {
838 		MSG_WriteByte( to->gunindex );
839 	}
840 
841 	if( pflags & PS_WEAPONFRAME ) {
842 		MSG_WriteByte( to->gunframe );
843 		MSG_WriteChar( to->gunoffset[0] * 4 );
844 		MSG_WriteChar( to->gunoffset[1] * 4 );
845 		MSG_WriteChar( to->gunoffset[2] * 4 );
846 		MSG_WriteChar( to->gunangles[0] * 4 );
847 		MSG_WriteChar( to->gunangles[1] * 4 );
848 		MSG_WriteChar( to->gunangles[2] * 4 );
849 	}
850 
851 	if( pflags & PS_BLEND ) {
852 		MSG_WriteByte( to->blend[0] * 255 );
853 		MSG_WriteByte( to->blend[1] * 255 );
854 		MSG_WriteByte( to->blend[2] * 255 );
855 		MSG_WriteByte( to->blend[3] * 255 );
856 	}
857 
858 	if( pflags & PS_FOV )
859 		MSG_WriteByte( to->fov );
860 
861 	if( pflags & PS_RDFLAGS )
862 		MSG_WriteByte( to->rdflags );
863 
864 	// send stats
865 	statbits = 0;
866 	for( i = 0; i < MAX_STATS; i++ )
867 		if( to->stats[i] != from->stats[i] )
868 			statbits |= 1 << i;
869 
870 	MSG_WriteLong( statbits );
871 	for( i = 0; i < MAX_STATS; i++ )
872 		if( statbits & ( 1 << i ) )
873 			MSG_WriteShort( to->stats[i] );
874 }
875 
876 /*
877 ==================
878 MSG_WriteDeltaPlayerstate_Enhanced
879 ==================
880 */
MSG_WriteDeltaPlayerstate_Enhanced(const playerStateEx_t * from,playerStateEx_t * to,msgPsFlags_t flags)881 int MSG_WriteDeltaPlayerstate_Enhanced( const playerStateEx_t *from, playerStateEx_t *to, msgPsFlags_t flags ) {
882 	int				i;
883 	int				pflags, extraflags;
884 	int				statbits;
885 
886 	if( !to ) {
887 		Com_Error( ERR_DROP, "MSG_WriteDeltaPlayerstate_Enhanced: NULL" );
888 	}
889 
890 	if( !from ) {
891 		from = &nullPlayerState;
892 	}
893 
894 	//
895 	// determine what needs to be sent
896 	//
897 	pflags = 0;
898 	extraflags = 0;
899 
900 	if( to->ps.pmove.pm_type != from->ps.pmove.pm_type )
901 		pflags |= PS_M_TYPE;
902 
903 	if( to->ps.pmove.origin[0] != from->ps.pmove.origin[0] ||
904 		to->ps.pmove.origin[1] != from->ps.pmove.origin[1] )
905 	{
906 		pflags |= PS_M_ORIGIN;
907 	}
908 
909 	if( to->ps.pmove.origin[2] != from->ps.pmove.origin[2] ) {
910 		extraflags |= EPS_M_ORIGIN2;
911 	}
912 
913 	if( !( flags & MSG_PS_IGNORE_PREDICTION ) ) {
914 		if( to->ps.pmove.velocity[0] != from->ps.pmove.velocity[0] ||
915 			to->ps.pmove.velocity[1] != from->ps.pmove.velocity[1] )
916 		{
917 			pflags |= PS_M_VELOCITY;
918 		}
919 
920 		if( to->ps.pmove.velocity[2] != from->ps.pmove.velocity[2] ) {
921 			extraflags |= EPS_M_VELOCITY2;
922 		}
923 
924 		if( to->ps.pmove.pm_time != from->ps.pmove.pm_time )
925 			pflags |= PS_M_TIME;
926 
927 		if( to->ps.pmove.pm_flags != from->ps.pmove.pm_flags )
928 			pflags |= PS_M_FLAGS;
929 
930 		if( to->ps.pmove.gravity != from->ps.pmove.gravity )
931 			pflags |= PS_M_GRAVITY;
932 	} else {
933 		/* clear delta state */
934 		VectorCopy( from->ps.pmove.velocity, to->ps.pmove.velocity );
935 		to->ps.pmove.pm_time = from->ps.pmove.pm_time;
936 		to->ps.pmove.pm_flags = from->ps.pmove.pm_flags;
937 		to->ps.pmove.gravity = from->ps.pmove.gravity;
938 	}
939 
940 	if( !( flags & MSG_PS_IGNORE_DELTAANGLES ) ) {
941 		if( to->ps.pmove.delta_angles[0] != from->ps.pmove.delta_angles[0] ||
942 			to->ps.pmove.delta_angles[1] != from->ps.pmove.delta_angles[1] ||
943 			to->ps.pmove.delta_angles[2] != from->ps.pmove.delta_angles[2] )
944 		{
945 			pflags |= PS_M_DELTA_ANGLES;
946 		}
947 	} else {
948 		/* clear delta state */
949 		VectorCopy( from->ps.pmove.delta_angles, to->ps.pmove.delta_angles );
950 	}
951 
952 	if( Delta_VecChar( from->ps.viewoffset, to->ps.viewoffset ) ) {
953 		pflags |= PS_VIEWOFFSET;
954 	}
955 
956 	if( !( flags & MSG_PS_IGNORE_VIEWANGLES ) ) {
957 		if( Delta_Angle16( from->ps.viewangles[0], to->ps.viewangles[0] ) ||
958 			Delta_Angle16( from->ps.viewangles[1], to->ps.viewangles[1] ) )
959 		{
960 			pflags |= PS_VIEWANGLES;
961 		}
962 
963 		if( Delta_Angle16( from->ps.viewangles[2], to->ps.viewangles[2] ) ) {
964 			extraflags |= EPS_VIEWANGLE2;
965 		}
966 	} else {
967 		/* clear delta state */
968 		to->ps.viewangles[0] = from->ps.viewangles[0];
969 		to->ps.viewangles[1] = from->ps.viewangles[1];
970 		to->ps.viewangles[2] = from->ps.viewangles[2];
971 	}
972 
973 	if( Delta_VecChar( from->ps.kick_angles, to->ps.kick_angles ) ) {
974 		pflags |= PS_KICKANGLES;
975 	}
976 
977 	if( !( flags & MSG_PS_IGNORE_BLEND ) ) {
978 		if( Delta_Blend( from->ps.blend, to->ps.blend ) ) {
979 			pflags |= PS_BLEND;
980 		}
981 	} else {
982 		/* clear delta state */
983 		to->ps.blend[0] = from->ps.blend[0];
984 		to->ps.blend[1] = from->ps.blend[1];
985 		to->ps.blend[2] = from->ps.blend[2];
986 		to->ps.blend[3] = from->ps.blend[3];
987 	}
988 
989 	if( Delta_Fov( from->ps.fov, to->ps.fov ) )
990 		pflags |= PS_FOV;
991 
992 	if( to->ps.rdflags != from->ps.rdflags )
993 		pflags |= PS_RDFLAGS;
994 
995 	if( !( flags & MSG_PS_IGNORE_GUNINDEX ) ) {
996 		if( to->ps.gunindex != from->ps.gunindex )
997 			pflags |= PS_WEAPONINDEX;
998 	} else {
999 		/* clear delta state */
1000 		to->ps.gunindex = from->ps.gunindex;
1001 	}
1002 
1003 	if( !( flags & MSG_PS_IGNORE_GUNFRAMES ) ) {
1004 		if( to->ps.gunframe != from->ps.gunframe )
1005 			pflags |= PS_WEAPONFRAME;
1006 
1007 		if( Delta_VecChar( from->ps.gunoffset, to->ps.gunoffset ) ) {
1008 			extraflags |= EPS_GUNOFFSET;
1009 		}
1010 
1011 		if( Delta_VecChar( from->ps.gunangles, to->ps.gunangles ) ) {
1012 			extraflags |= EPS_GUNANGLES;
1013 		}
1014 	} else {
1015 		/* clear delta state */
1016 		to->ps.gunframe = from->ps.gunframe;
1017 
1018 		to->ps.gunoffset[0] = from->ps.gunoffset[0];
1019 		to->ps.gunoffset[1] = from->ps.gunoffset[1];
1020 		to->ps.gunoffset[2] = from->ps.gunoffset[2];
1021 
1022 		to->ps.gunangles[0] = from->ps.gunangles[0];
1023 		to->ps.gunangles[1] = from->ps.gunangles[1];
1024 		to->ps.gunangles[2] = from->ps.gunangles[2];
1025 	}
1026 
1027 	if( flags & MSG_PS_WRITE_CLIENTNUM ) {
1028 		if( from->clientNum != to->clientNum ) {
1029 			extraflags |= EPS_CLIENTNUM;
1030 		}
1031 	}
1032 
1033 	statbits = 0;
1034 	for( i = 0; i < MAX_STATS; i++ ) {
1035 		if( to->ps.stats[i] != from->ps.stats[i] ) {
1036 			statbits |= 1 << i;
1037 		}
1038 	}
1039 
1040 	if( statbits ) {
1041 		extraflags |= EPS_STATS;
1042 	}
1043 
1044 	//
1045 	// write it
1046 	//
1047 	MSG_WriteShort( pflags );
1048 
1049 	//
1050 	// write the pmove_state_t
1051 	//
1052 	if( pflags & PS_M_TYPE )
1053 		MSG_WriteByte( to->ps.pmove.pm_type );
1054 
1055 	if( pflags & PS_M_ORIGIN ) {
1056 		MSG_WriteShort( to->ps.pmove.origin[0] );
1057 		MSG_WriteShort( to->ps.pmove.origin[1] );
1058 	}
1059 
1060 	if( extraflags & EPS_M_ORIGIN2 ) {
1061 		MSG_WriteShort( to->ps.pmove.origin[2] );
1062 	}
1063 
1064 	if( pflags & PS_M_VELOCITY ) {
1065 		MSG_WriteShort( to->ps.pmove.velocity[0] );
1066 		MSG_WriteShort( to->ps.pmove.velocity[1] );
1067 	}
1068 
1069 	if( extraflags & EPS_M_VELOCITY2 ) {
1070 		MSG_WriteShort( to->ps.pmove.velocity[2] );
1071 	}
1072 
1073 	if( pflags & PS_M_TIME ) {
1074 		MSG_WriteByte( to->ps.pmove.pm_time );
1075 	}
1076 
1077 	if( pflags & PS_M_FLAGS ) {
1078 		MSG_WriteByte( to->ps.pmove.pm_flags );
1079 	}
1080 
1081 	if( pflags & PS_M_GRAVITY ) {
1082 		MSG_WriteShort( to->ps.pmove.gravity );
1083 	}
1084 
1085 	if( pflags & PS_M_DELTA_ANGLES ) {
1086 		MSG_WriteShort( to->ps.pmove.delta_angles[0] );
1087 		MSG_WriteShort( to->ps.pmove.delta_angles[1] );
1088 		MSG_WriteShort( to->ps.pmove.delta_angles[2] );
1089 	}
1090 
1091 	//
1092 	// write the rest of the player_state_t
1093 	//
1094 	if( pflags & PS_VIEWOFFSET ) {
1095 		MSG_WriteChar( to->ps.viewoffset[0] * 4 );
1096 		MSG_WriteChar( to->ps.viewoffset[1] * 4 );
1097 		MSG_WriteChar( to->ps.viewoffset[2] * 4 );
1098 	}
1099 
1100 	if( pflags & PS_VIEWANGLES ) {
1101 		MSG_WriteAngle16( to->ps.viewangles[0] );
1102 		MSG_WriteAngle16( to->ps.viewangles[1] );
1103 
1104 	}
1105 
1106 	if( extraflags & EPS_VIEWANGLE2 ) {
1107 		MSG_WriteAngle16( to->ps.viewangles[2] );
1108 	}
1109 
1110 	if( pflags & PS_KICKANGLES ) {
1111 		MSG_WriteChar( to->ps.kick_angles[0] * 4 );
1112 		MSG_WriteChar( to->ps.kick_angles[1] * 4 );
1113 		MSG_WriteChar( to->ps.kick_angles[2] * 4 );
1114 	}
1115 
1116 	if( pflags & PS_WEAPONINDEX ) {
1117 		MSG_WriteByte( to->ps.gunindex );
1118 	}
1119 
1120 	if( pflags & PS_WEAPONFRAME ) {
1121 		MSG_WriteByte( to->ps.gunframe );
1122 	}
1123 
1124 	if( extraflags & EPS_GUNOFFSET ) {
1125 		MSG_WriteChar( to->ps.gunoffset[0] * 4 );
1126 		MSG_WriteChar( to->ps.gunoffset[1] * 4 );
1127 		MSG_WriteChar( to->ps.gunoffset[2] * 4 );
1128 	}
1129 
1130 	if( extraflags & EPS_GUNANGLES ) {
1131 		MSG_WriteChar( to->ps.gunangles[0] * 4 );
1132 		MSG_WriteChar( to->ps.gunangles[1] * 4 );
1133 		MSG_WriteChar( to->ps.gunangles[2] * 4 );
1134 	}
1135 
1136 	if( pflags & PS_BLEND ) {
1137 		MSG_WriteByte( to->ps.blend[0] * 255 );
1138 		MSG_WriteByte( to->ps.blend[1] * 255 );
1139 		MSG_WriteByte( to->ps.blend[2] * 255 );
1140 		MSG_WriteByte( to->ps.blend[3] * 255 );
1141 	}
1142 
1143 	if( pflags & PS_FOV )
1144 		MSG_WriteByte( to->ps.fov );
1145 
1146 	if( pflags & PS_RDFLAGS )
1147 		MSG_WriteByte( to->ps.rdflags );
1148 
1149 	if( extraflags & EPS_CLIENTNUM ) {
1150 		MSG_WriteByte( to->clientNum );
1151 	}
1152 
1153 	// send stats
1154 	if( extraflags & EPS_STATS ) {
1155 		MSG_WriteLong( statbits );
1156 		for( i = 0; i < MAX_STATS; i++ ) {
1157 			if( statbits & ( 1 << i ) ) {
1158 				MSG_WriteShort( to->ps.stats[i] );
1159 			}
1160 		}
1161 	}
1162 
1163 	return extraflags;
1164 }
1165 
1166 /*
1167 ==================
1168 MSG_WriteDeltaPlayerstate_Packet
1169 ==================
1170 */
MSG_WriteDeltaPlayerstate_Packet(const playerStateEx_t * from,playerStateEx_t * to,msgPsFlags_t flags)1171 void MSG_WriteDeltaPlayerstate_Packet( const playerStateEx_t *from, playerStateEx_t *to, msgPsFlags_t flags ) {
1172 	int				i;
1173 	int				pflags, extraflags;
1174 	int				statbits;
1175 	int				playerNum;
1176 
1177 	if( !to ) {
1178 		if( !from ) {
1179 			Com_Error( ERR_DROP, "MSG_WriteDeltaPlayerstate_Packet: NULL" );
1180 		}
1181 		MSG_WriteByte( from->number );
1182 		MSG_WriteShort( PS_REMOVE );
1183 		return;
1184 	}
1185 
1186 	playerNum = to->number;
1187 	if( playerNum < 0 || playerNum > MAX_CLIENTS - 1 ) {
1188 		Com_Error( ERR_DROP, "MSG_WriteDeltaPlayerstate_Packet: bad player number %i", playerNum );
1189 	}
1190 
1191 	if( !from ) {
1192 		from = &nullPlayerState;
1193 	}
1194 
1195 	//
1196 	// determine what needs to be sent
1197 	//
1198 	pflags = 0;
1199 	extraflags = 0;
1200 
1201 	if( to->ps.pmove.pm_type != from->ps.pmove.pm_type )
1202 		pflags |= PS_M_TYPE;
1203 
1204 	if( to->ps.pmove.origin[0] != from->ps.pmove.origin[0] ||
1205 		to->ps.pmove.origin[1] != from->ps.pmove.origin[1] )
1206 	{
1207 		pflags |= PS_M_ORIGIN;
1208 	}
1209 
1210 	if( to->ps.pmove.origin[2] != from->ps.pmove.origin[2] ) {
1211 		extraflags |= EPS_M_ORIGIN2;
1212 	}
1213 
1214 	if( !( flags & MSG_PS_IGNORE_PREDICTION ) ) {
1215 		if( to->ps.pmove.velocity[0] != from->ps.pmove.velocity[0] ||
1216 			to->ps.pmove.velocity[1] != from->ps.pmove.velocity[1] )
1217 		{
1218 			pflags |= PS_M_VELOCITY;
1219 		}
1220 
1221 		if( to->ps.pmove.velocity[2] != from->ps.pmove.velocity[2] ) {
1222 			extraflags |= EPS_M_VELOCITY2;
1223 		}
1224 
1225 		if( to->ps.pmove.pm_time != from->ps.pmove.pm_time )
1226 			pflags |= PS_M_TIME;
1227 
1228 		if( to->ps.pmove.pm_flags != from->ps.pmove.pm_flags )
1229 			pflags |= PS_M_FLAGS;
1230 
1231 		if( to->ps.pmove.gravity != from->ps.pmove.gravity )
1232 			pflags |= PS_M_GRAVITY;
1233 	} else {
1234 		/* clear delta state */
1235 		VectorCopy( from->ps.pmove.velocity, to->ps.pmove.velocity );
1236 		to->ps.pmove.pm_time = from->ps.pmove.pm_time;
1237 		to->ps.pmove.pm_flags = from->ps.pmove.pm_flags;
1238 		to->ps.pmove.gravity = from->ps.pmove.gravity;
1239 	}
1240 
1241 	if( !( flags & MSG_PS_IGNORE_DELTAANGLES ) ) {
1242 		if( to->ps.pmove.delta_angles[0] != from->ps.pmove.delta_angles[0] ||
1243 			to->ps.pmove.delta_angles[1] != from->ps.pmove.delta_angles[1] ||
1244 			to->ps.pmove.delta_angles[2] != from->ps.pmove.delta_angles[2] )
1245 		{
1246 			pflags |= PS_M_DELTA_ANGLES;
1247 		}
1248 	} else {
1249 		/* clear delta state */
1250 		VectorCopy( from->ps.pmove.delta_angles, to->ps.pmove.delta_angles );
1251 	}
1252 
1253 	if( Delta_VecChar( from->ps.viewoffset, to->ps.viewoffset ) ) {
1254 		pflags |= PS_VIEWOFFSET;
1255 	}
1256 
1257 	if( Delta_Angle16( from->ps.viewangles[0], to->ps.viewangles[0] ) ||
1258 		Delta_Angle16( from->ps.viewangles[1], to->ps.viewangles[1] ) )
1259 	{
1260 		pflags |= PS_VIEWANGLES;
1261 	}
1262 
1263 	if( Delta_Angle16( from->ps.viewangles[2], to->ps.viewangles[2] ) ) {
1264 		extraflags |= EPS_VIEWANGLE2;
1265 	}
1266 
1267 	if( Delta_VecChar( from->ps.kick_angles, to->ps.kick_angles ) ) {
1268 		pflags |= PS_KICKANGLES;
1269 	}
1270 
1271 	if( !( flags & MSG_PS_IGNORE_BLEND ) ) {
1272 		if( Delta_Blend( from->ps.blend, to->ps.blend ) ) {
1273 			pflags |= PS_BLEND;
1274 		}
1275 	} else {
1276 		/* clear delta state */
1277 		to->ps.blend[0] = from->ps.blend[0];
1278 		to->ps.blend[1] = from->ps.blend[1];
1279 		to->ps.blend[2] = from->ps.blend[2];
1280 		to->ps.blend[3] = from->ps.blend[3];
1281 	}
1282 
1283 	if( Delta_Fov( from->ps.fov, to->ps.fov ) )
1284 		pflags |= PS_FOV;
1285 
1286 	if( to->ps.rdflags != from->ps.rdflags )
1287 		pflags |= PS_RDFLAGS;
1288 
1289 	if( !( flags & MSG_PS_IGNORE_GUNINDEX ) ) {
1290 		if( to->ps.gunindex != from->ps.gunindex )
1291 			pflags |= PS_WEAPONINDEX;
1292 	} else {
1293 		/* clear delta state */
1294 		to->ps.gunindex = from->ps.gunindex;
1295 	}
1296 
1297 	if( !( flags & MSG_PS_IGNORE_GUNFRAMES ) ) {
1298 		if( to->ps.gunframe != from->ps.gunframe )
1299 			pflags |= PS_WEAPONFRAME;
1300 
1301 		if( Delta_VecChar( from->ps.gunoffset, to->ps.gunoffset ) ) {
1302 			extraflags |= EPS_GUNOFFSET;
1303 		}
1304 
1305 		if( Delta_VecChar( from->ps.gunangles, to->ps.gunangles ) ) {
1306 			extraflags |= EPS_GUNANGLES;
1307 		}
1308 	} else {
1309 		/* clear delta state */
1310 		to->ps.gunframe = from->ps.gunframe;
1311 
1312 		to->ps.gunoffset[0] = from->ps.gunoffset[0];
1313 		to->ps.gunoffset[1] = from->ps.gunoffset[1];
1314 		to->ps.gunoffset[2] = from->ps.gunoffset[2];
1315 
1316 		to->ps.gunangles[0] = from->ps.gunangles[0];
1317 		to->ps.gunangles[1] = from->ps.gunangles[1];
1318 		to->ps.gunangles[2] = from->ps.gunangles[2];
1319 	}
1320 
1321 	statbits = 0;
1322 	for( i = 0; i < MAX_STATS; i++ ) {
1323 		if( to->ps.stats[i] != from->ps.stats[i] ) {
1324 			statbits |= 1 << i;
1325 		}
1326 	}
1327 
1328 	if( statbits ) {
1329 		extraflags |= EPS_STATS;
1330 	}
1331 
1332 	if( !pflags && !extraflags && !( flags & MSG_PS_FORCE ) ) {
1333 		return;
1334 	}
1335 
1336 	//
1337 	// write it
1338 	//
1339 	MSG_WriteByte( playerNum );
1340 	MSG_WriteShort( pflags );
1341 	MSG_WriteByte( extraflags );
1342 
1343 	//
1344 	// write the pmove_state_t
1345 	//
1346 	if( pflags & PS_M_TYPE )
1347 		MSG_WriteByte( to->ps.pmove.pm_type );
1348 
1349 	if( pflags & PS_M_ORIGIN ) {
1350 		MSG_WriteShort( to->ps.pmove.origin[0] );
1351 		MSG_WriteShort( to->ps.pmove.origin[1] );
1352 	}
1353 
1354 	if( extraflags & EPS_M_ORIGIN2 ) {
1355 		MSG_WriteShort( to->ps.pmove.origin[2] );
1356 	}
1357 
1358 	if( pflags & PS_M_VELOCITY ) {
1359 		MSG_WriteShort( to->ps.pmove.velocity[0] );
1360 		MSG_WriteShort( to->ps.pmove.velocity[1] );
1361 	}
1362 
1363 	if( extraflags & EPS_M_VELOCITY2 ) {
1364 		MSG_WriteShort( to->ps.pmove.velocity[2] );
1365 	}
1366 
1367 	if( pflags & PS_M_TIME )
1368 		MSG_WriteByte( to->ps.pmove.pm_time );
1369 
1370 	if( pflags & PS_M_FLAGS )
1371 		MSG_WriteByte( to->ps.pmove.pm_flags );
1372 
1373 	if( pflags & PS_M_GRAVITY )
1374 		MSG_WriteShort( to->ps.pmove.gravity );
1375 
1376 	if( pflags & PS_M_DELTA_ANGLES ) {
1377 		MSG_WriteShort( to->ps.pmove.delta_angles[0] );
1378 		MSG_WriteShort( to->ps.pmove.delta_angles[1] );
1379 		MSG_WriteShort( to->ps.pmove.delta_angles[2] );
1380 	}
1381 
1382 	//
1383 	// write the rest of the player_state_t
1384 	//
1385 	if( pflags & PS_VIEWOFFSET ) {
1386 		MSG_WriteChar( to->ps.viewoffset[0] * 4 );
1387 		MSG_WriteChar( to->ps.viewoffset[1] * 4 );
1388 		MSG_WriteChar( to->ps.viewoffset[2] * 4 );
1389 	}
1390 
1391 	if( pflags & PS_VIEWANGLES ) {
1392 		MSG_WriteAngle16( to->ps.viewangles[0] );
1393 		MSG_WriteAngle16( to->ps.viewangles[1] );
1394 	}
1395 
1396 	if( extraflags & EPS_VIEWANGLE2 ) {
1397 		MSG_WriteAngle16( to->ps.viewangles[2] );
1398 	}
1399 
1400 	if( pflags & PS_KICKANGLES ) {
1401 		MSG_WriteChar( to->ps.kick_angles[0] * 4 );
1402 		MSG_WriteChar( to->ps.kick_angles[1] * 4 );
1403 		MSG_WriteChar( to->ps.kick_angles[2] * 4 );
1404 	}
1405 
1406 	if( pflags & PS_WEAPONINDEX ) {
1407 		MSG_WriteByte( to->ps.gunindex );
1408 	}
1409 
1410 	if( pflags & PS_WEAPONFRAME ) {
1411 		MSG_WriteByte( to->ps.gunframe );
1412 	}
1413 
1414 	if( extraflags & EPS_GUNOFFSET ) {
1415 		MSG_WriteChar( to->ps.gunoffset[0] * 4 );
1416 		MSG_WriteChar( to->ps.gunoffset[1] * 4 );
1417 		MSG_WriteChar( to->ps.gunoffset[2] * 4 );
1418 	}
1419 
1420 	if( extraflags & EPS_GUNANGLES ) {
1421 		MSG_WriteChar( to->ps.gunangles[0] * 4 );
1422 		MSG_WriteChar( to->ps.gunangles[1] * 4 );
1423 		MSG_WriteChar( to->ps.gunangles[2] * 4 );
1424 	}
1425 
1426 	if( pflags & PS_BLEND ) {
1427 		MSG_WriteByte( to->ps.blend[0] * 255 );
1428 		MSG_WriteByte( to->ps.blend[1] * 255 );
1429 		MSG_WriteByte( to->ps.blend[2] * 255 );
1430 		MSG_WriteByte( to->ps.blend[3] * 255 );
1431 	}
1432 
1433 	if( pflags & PS_FOV )
1434 		MSG_WriteByte( to->ps.fov );
1435 
1436 	if( pflags & PS_RDFLAGS )
1437 		MSG_WriteByte( to->ps.rdflags );
1438 
1439 	// send stats
1440 	if( extraflags & EPS_STATS ) {
1441 		MSG_WriteLong( statbits );
1442 		for( i = 0; i < MAX_STATS; i++ ) {
1443 			if( statbits & ( 1 << i ) ) {
1444 				MSG_WriteShort( to->ps.stats[i] );
1445 			}
1446 		}
1447 	}
1448 }
1449 
1450 /*
1451 =============
1452 MSG_FlushTo
1453 =============
1454 */
MSG_FlushTo(sizebuf_t * dest)1455 void MSG_FlushTo( sizebuf_t *dest ) {
1456 	memcpy( SZ_GetSpace( dest, msg_write.cursize ), msg_write.data, msg_write.cursize );
1457 	SZ_Clear( &msg_write );
1458 }
1459 
1460 
1461 //============================================================
1462 
1463 //
1464 // reading functions
1465 //
1466 
MSG_BeginReading(void)1467 void MSG_BeginReading( void ) {
1468 	msg_read.readcount = 0;
1469 	msg_read.bitpos = 0;
1470 }
1471 
1472 // returns -1 if no more characters are available
MSG_ReadChar(void)1473 int MSG_ReadChar (void)
1474 {
1475 	int	c;
1476 
1477 	if (msg_read.readcount+1 > msg_read.cursize)
1478 		c = -1;
1479 	else
1480 		c = (signed char)msg_read.data[msg_read.readcount];
1481 	msg_read.readcount++;
1482 	msg_read.bitpos = msg_read.readcount << 3;
1483 
1484 	return c;
1485 }
1486 
MSG_ReadByte(void)1487 int MSG_ReadByte( void )
1488 {
1489 	int	c;
1490 
1491 	if (msg_read.readcount+1 > msg_read.cursize)
1492 		c = -1;
1493 	else
1494 		c = (unsigned char)msg_read.data[msg_read.readcount];
1495 	msg_read.readcount++;
1496 	msg_read.bitpos = msg_read.readcount << 3;
1497 
1498 	return c;
1499 }
1500 
MSG_ReadShort(void)1501 int MSG_ReadShort( void )
1502 {
1503 	int	c;
1504 
1505 	if (msg_read.readcount+2 > msg_read.cursize)
1506 		c = -1;
1507 	else
1508 		c = (short)(msg_read.data[msg_read.readcount]
1509 		+ (msg_read.data[msg_read.readcount+1]<<8));
1510 
1511 	msg_read.readcount += 2;
1512 	msg_read.bitpos = msg_read.readcount << 3;
1513 
1514 	return c;
1515 }
1516 
MSG_ReadLong(void)1517 int MSG_ReadLong ( void )
1518 {
1519 	int	c;
1520 
1521 	if (msg_read.readcount+4 > msg_read.cursize)
1522 		c = -1;
1523 	else
1524 		c = msg_read.data[msg_read.readcount]
1525 		+ (msg_read.data[msg_read.readcount+1]<<8)
1526 		+ (msg_read.data[msg_read.readcount+2]<<16)
1527 		+ (msg_read.data[msg_read.readcount+3]<<24);
1528 
1529 	msg_read.readcount += 4;
1530 	msg_read.bitpos = msg_read.readcount << 3;
1531 
1532 	return c;
1533 }
1534 
1535 
MSG_ReadString(void)1536 char *MSG_ReadString( void ) {
1537 	static char	string[2][MAX_NET_STRING];
1538 	static int index;
1539 	char	*s;
1540 	int		l, c;
1541 
1542 	s = string[index];
1543 	index ^= 1;
1544 
1545 	l = 0;
1546 	do {
1547 		c = MSG_ReadByte();
1548 		if( c == -1 || c == 0 ) {
1549 			break;
1550 		}
1551 		if( c == 0xFF ) {
1552 			c = '.';
1553 		}
1554 		s[l++] = c;
1555 	} while( l < MAX_NET_STRING - 1 );
1556 
1557 	s[l] = 0;
1558 
1559 	return s;
1560 }
1561 
MSG_ReadStringLine(void)1562 char *MSG_ReadStringLine( void ) {
1563 	static char	string[2][MAX_STRING_CHARS];
1564 	static int index;
1565 	char	*s;
1566 	int		l, c;
1567 
1568 	s = string[index];
1569 	index ^= 1;
1570 
1571 	l = 0;
1572 	do {
1573 		c = MSG_ReadByte();
1574 		if( c == -1 || c == 0 || c == '\n' ) {
1575 			break;
1576 		}
1577 		if( c == 0xFF ) {
1578 			c = '.';
1579 		}
1580 		s[l++] = c;
1581 	} while( l < MAX_STRING_CHARS - 1 );
1582 
1583 	s[l] = 0;
1584 
1585 	return s;
1586 }
1587 
MSG_ReadCoord(void)1588 float MSG_ReadCoord (void)
1589 {
1590 	return MSG_ReadShort() * (1.0/8);
1591 }
1592 
MSG_ReadPos(vec3_t pos)1593 void MSG_ReadPos ( vec3_t pos)
1594 {
1595 	pos[0] = MSG_ReadShort() * (1.0/8);
1596 	pos[1] = MSG_ReadShort() * (1.0/8);
1597 	pos[2] = MSG_ReadShort() * (1.0/8);
1598 }
1599 
MSG_ReadExactPos(vec3_t pos)1600 void MSG_ReadExactPos( vec3_t pos ) {
1601 	*( int * )&pos[0] = MSG_ReadLong();
1602 	*( int * )&pos[1] = MSG_ReadLong();
1603 	*( int * )&pos[2] = MSG_ReadLong();
1604 }
1605 
MSG_ReadAngle(void)1606 float MSG_ReadAngle (void)
1607 {
1608 	return MSG_ReadChar() * (360.0/256);
1609 }
1610 
MSG_ReadAngle16(void)1611 float MSG_ReadAngle16 (void)
1612 {
1613 	return SHORT2ANGLE(MSG_ReadShort());
1614 }
1615 
MSG_ReadDir(vec3_t dir)1616 void MSG_ReadDir( vec3_t dir ) {
1617 	int		b;
1618 
1619 	b = MSG_ReadByte();
1620 	if( b < 0 || b >= NUMVERTEXNORMALS )
1621 		Com_Error( ERR_DROP, "MSG_ReadDir: out of range" );
1622 	VectorCopy( bytedirs[b], dir );
1623 }
1624 
MSG_ReadDeltaUsercmd(const usercmd_t * from,usercmd_t * to)1625 void MSG_ReadDeltaUsercmd( const usercmd_t *from, usercmd_t *to ) {
1626 	int bits;
1627 
1628 	if( from ) {
1629 		memcpy( to, from, sizeof( *to ) );
1630 	} else {
1631 		memset( to, 0, sizeof( *to ) );
1632 	}
1633 
1634 	bits = MSG_ReadByte();
1635 
1636 // read current angles
1637 	if( bits & CM_ANGLE1 )
1638 		to->angles[0] = MSG_ReadShort();
1639 	if( bits & CM_ANGLE2 )
1640 		to->angles[1] = MSG_ReadShort();
1641 	if( bits & CM_ANGLE3 )
1642 		to->angles[2] = MSG_ReadShort();
1643 
1644 // read movement
1645 	if( bits & CM_FORWARD )
1646 		to->forwardmove = MSG_ReadShort();
1647 	if( bits & CM_SIDE )
1648 		to->sidemove = MSG_ReadShort();
1649 	if( bits & CM_UP )
1650 		to->upmove = MSG_ReadShort();
1651 
1652 // read buttons
1653 	if( bits & CM_BUTTONS )
1654 		to->buttons = MSG_ReadByte();
1655 
1656 	if( bits & CM_IMPULSE )
1657 		to->impulse = MSG_ReadByte();
1658 
1659 // read time to run command
1660 	to->msec = MSG_ReadByte();
1661 
1662 // read the light level
1663 	to->lightlevel = MSG_ReadByte();
1664 }
1665 
MSG_ReadBits(int bits)1666 int MSG_ReadBits( int bits ) {
1667 	int i, get, bitpos;
1668 	qboolean sgn;
1669 	int value;
1670 
1671 	if( bits == 0 || bits < -31 || bits > 32 ) {
1672 		Com_Error( ERR_FATAL, "MSG_ReadBits: bad bits: %d", bits );
1673 	}
1674 
1675 	bitpos = msg_read.bitpos;
1676 	if( ( bitpos & 7 ) == 0 ) {
1677 		/* optimized case */
1678 		switch( bits ) {
1679 		case -8:
1680 			value = MSG_ReadChar();
1681 			return value;
1682 		case 8:
1683 			value = MSG_ReadByte();
1684 			return value;
1685 		case -16:
1686 			value = MSG_ReadShort();
1687 			return value;
1688 		case 32:
1689 			value = MSG_ReadLong();
1690 			return value;
1691 		default:
1692 			break;
1693 		}
1694 	}
1695 
1696 	sgn = qfalse;
1697 	if( bits < 0 ) {
1698 		bits = -bits;
1699 		sgn = qtrue;
1700 	}
1701 
1702 	value = 0;
1703 	for( i = 0; i < bits; i++, bitpos++ ) {
1704 		get = ( msg_read.data[ bitpos >> 3 ] >> ( bitpos & 7 ) ) & 1;
1705 		value |= get << i;
1706 	}
1707 	msg_read.bitpos = bitpos;
1708 	msg_read.readcount = ( bitpos + 7 ) >> 3;
1709 
1710 	if( sgn ) {
1711 		if( value & ( 1 << ( bits - 1 ) ) ) {
1712 			value |= -1 ^ ( ( 1 << bits ) - 1 );
1713 		}
1714 	}
1715 
1716 	return value;
1717 }
1718 
MSG_ReadDeltaUsercmd_Enhanced(const usercmd_t * from,usercmd_t * to)1719 void MSG_ReadDeltaUsercmd_Enhanced( const usercmd_t *from, usercmd_t *to ) {
1720 	int bits;
1721 
1722 	if( from ) {
1723 		memcpy( to, from, sizeof( *to ) );
1724 	} else {
1725 		memset( to, 0, sizeof( *to ) );
1726 	}
1727 
1728 	if( !MSG_ReadBits( 1 ) ) {
1729 		return;
1730 	}
1731 
1732 	bits = MSG_ReadBits( 8 );
1733 
1734 // read current angles
1735 	if( bits & CM_ANGLE1 ) {
1736 		if( MSG_ReadBits( 1 ) ) {
1737 			to->angles[0] += MSG_ReadBits( -8 );
1738 		} else {
1739 			to->angles[0] = MSG_ReadBits( -16 );
1740 		}
1741 	}
1742 	if( bits & CM_ANGLE2 ) {
1743 		if( MSG_ReadBits( 1 ) ) {
1744 			to->angles[1] += MSG_ReadBits( -8 );
1745 		} else {
1746 			to->angles[1] = MSG_ReadBits( -16 );
1747 		}
1748 	}
1749 	if( bits & CM_ANGLE3 ) {
1750 		to->angles[2] = MSG_ReadBits( -16 );
1751 	}
1752 
1753 // read movement
1754 	if( bits & CM_FORWARD ) {
1755 		to->forwardmove = MSG_ReadBits( -16 );
1756 	}
1757 	if( bits & CM_SIDE ) {
1758 		to->sidemove = MSG_ReadBits( -16 );
1759 	}
1760 	if( bits & CM_UP ) {
1761 		to->upmove = MSG_ReadBits( -16 );
1762 	}
1763 
1764 // read buttons
1765 	if( bits & CM_BUTTONS ) {
1766 		to->buttons = MSG_ReadBits( 8 );
1767 	}
1768 
1769 // read time to run command
1770 	if( bits & CM_IMPULSE ) {
1771 		to->msec = MSG_ReadBits( 8 );
1772 	}
1773 }
1774 
1775 
MSG_ReadData(void * data,int len)1776 void MSG_ReadData ( void *data, int len)
1777 {
1778 	int		i;
1779 
1780 	for (i=0 ; i<len ; i++)
1781 		((byte *)data)[i] = MSG_ReadByte ();
1782 }
1783 
1784 /*
1785 =================
1786 MSG_ParseEntityBits
1787 
1788 Returns the entity number and the header bits
1789 =================
1790 */
1791 static int	bitcounts[32];	/// just for protocol profiling
1792 
MSG_ParseEntityBits(int * bits)1793 int MSG_ParseEntityBits( int *bits ) {
1794 	int     	b, total;
1795 	int			i;
1796 	int			number;
1797 
1798 	total = MSG_ReadByte();
1799 	if( total & U_MOREBITS1 ) {
1800 		b = MSG_ReadByte();
1801 		total |= b<<8;
1802 	}
1803 	if( total & U_MOREBITS2 ) {
1804 		b = MSG_ReadByte();
1805 		total |= b<<16;
1806 	}
1807 	if( total & U_MOREBITS3 ) {
1808 		b = MSG_ReadByte();
1809 		total |= b<<24;
1810 	}
1811 
1812 	// count the bits for net profiling
1813 	for( i=0 ; i<32 ; i++ )
1814 		if( total & (1 << i) )
1815 			bitcounts[i]++;
1816 
1817 	if( total & U_NUMBER16 )
1818 		number = MSG_ReadShort();
1819 	else
1820 		number = MSG_ReadByte();
1821 
1822 	*bits = total;
1823 
1824 	return number;
1825 }
1826 
1827 /*
1828 ==================
1829 MSG_ParseDeltaEntity
1830 
1831 Can go from either a baseline or a previous packet_entity
1832 ==================
1833 */
MSG_ParseDeltaEntity(const entity_state_t * from,entity_state_t * to,int number,int bits)1834 void MSG_ParseDeltaEntity( const entity_state_t *from, entity_state_t *to, int number, int bits ) {
1835 	if( !to ) {
1836 		Com_Error( ERR_DROP, "MSG_ParseDeltaEntity: NULL" );
1837 	}
1838 
1839 	if( number < 1 || number >= MAX_EDICTS ) {
1840 		Com_Error( ERR_DROP, "MSG_ParseDeltaEntity: bad entity number %i", number );
1841 	}
1842 
1843 	// set everything to the state we are delta'ing from
1844 	if( from ) {
1845 		memcpy( to, from, sizeof( *to ) );
1846 		VectorCopy( from->origin, to->old_origin );
1847 	} else {
1848 		memset( to, 0, sizeof( *to ) );
1849 		from = &nullEntityState;
1850 	}
1851 
1852 	to->number = number;
1853 
1854 	if( !bits ) {
1855 		to->event = 0; // FIXME
1856 		return;
1857 	}
1858 
1859 	if( bits & U_MODEL ) {
1860 		to->modelindex = MSG_ReadByte();
1861 	}
1862 	if( bits & U_MODEL2 ) {
1863 		to->modelindex2 = MSG_ReadByte();
1864 	}
1865 	if( bits & U_MODEL3 ) {
1866 		to->modelindex3 = MSG_ReadByte();
1867 	}
1868 	if( bits & U_MODEL4 ) {
1869 		to->modelindex4 = MSG_ReadByte();
1870 	}
1871 
1872 	if( bits & U_FRAME8 )
1873 		to->frame = MSG_ReadByte();
1874 	if( bits & U_FRAME16 )
1875 		to->frame = MSG_ReadShort();
1876 
1877 	if( (bits & U_SKIN8) && (bits & U_SKIN16) )		//used for laser colors
1878 		to->skinnum = MSG_ReadLong();
1879 	else if( bits & U_SKIN8 )
1880 		to->skinnum = MSG_ReadByte();
1881 	else if( bits & U_SKIN16 )
1882 		to->skinnum = MSG_ReadShort();
1883 
1884 	if( (bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16) )
1885 		to->effects = MSG_ReadLong();
1886 	else if( bits & U_EFFECTS8 )
1887 		to->effects = MSG_ReadByte();
1888 	else if( bits & U_EFFECTS16 )
1889 		to->effects = MSG_ReadShort();
1890 
1891 	if( (bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16) )
1892 		to->renderfx = MSG_ReadLong();
1893 	else if( bits & U_RENDERFX8 )
1894 		to->renderfx = MSG_ReadByte();
1895 	else if( bits & U_RENDERFX16 )
1896 		to->renderfx = MSG_ReadShort();
1897 
1898 	if( bits & U_ORIGIN1 ) {
1899 		to->origin[0] = MSG_ReadCoord();
1900 	}
1901 	if( bits & U_ORIGIN2 ) {
1902 		to->origin[1] = MSG_ReadCoord();
1903 	}
1904 	if( bits & U_ORIGIN3 ) {
1905 		to->origin[2] = MSG_ReadCoord();
1906 	}
1907 
1908 	if( bits & U_ANGLE1 ) {
1909 		to->angles[0] = MSG_ReadAngle();
1910 	}
1911 	if( bits & U_ANGLE2 ) {
1912 		to->angles[1] = MSG_ReadAngle();
1913 		//Com_Printf( "read %.3f\n", to->angles[1] );
1914 	}
1915 	if( bits & U_ANGLE3 ) {
1916 		to->angles[2] = MSG_ReadAngle();
1917 	}
1918 
1919 	if( bits & U_OLDORIGIN ) {
1920 		MSG_ReadPos( to->old_origin );
1921 	}
1922 
1923 	if( bits & U_SOUND ) {
1924 		to->sound = MSG_ReadByte();
1925 	}
1926 
1927 	if( bits & U_EVENT ) {
1928 		to->event = MSG_ReadByte();
1929 	} else {
1930 		to->event = 0;
1931 	}
1932 
1933 	if( bits & U_SOLID ) {
1934 		to->solid = MSG_ReadShort();
1935 	}
1936 
1937 }
1938 
1939 /*
1940 ===================
1941 MSG_ParseDeltaPlayerstate_Default
1942 ===================
1943 */
MSG_ParseDeltaPlayerstate_Default(const player_state_t * from,player_state_t * to,int flags)1944 void MSG_ParseDeltaPlayerstate_Default( const player_state_t *from, player_state_t *to, int flags ) {
1945 	int			i;
1946 	int			statbits;
1947 
1948 	if( !to ) {
1949 		Com_Error( ERR_DROP, "MSG_ParseDeltaPlayerstate_Default: NULL" );
1950 	}
1951 
1952 	// clear to old value before delta parsing
1953 	if( from ) {
1954 		memcpy( to, from, sizeof( *to ) );
1955 	} else {
1956 		memset( to, 0, sizeof( *to ) );
1957 	}
1958 
1959 	//
1960 	// parse the pmove_state_t
1961 	//
1962 	if( flags & PS_M_TYPE )
1963 		to->pmove.pm_type = MSG_ReadByte();
1964 
1965 	if( flags & PS_M_ORIGIN ) {
1966 		to->pmove.origin[0] = MSG_ReadShort();
1967 		to->pmove.origin[1] = MSG_ReadShort();
1968 		to->pmove.origin[2] = MSG_ReadShort();
1969 	}
1970 
1971 	if( flags & PS_M_VELOCITY ) {
1972 		to->pmove.velocity[0] = MSG_ReadShort();
1973 		to->pmove.velocity[1] = MSG_ReadShort();
1974 		to->pmove.velocity[2] = MSG_ReadShort();
1975 	}
1976 
1977 	if( flags & PS_M_TIME )
1978 		to->pmove.pm_time = MSG_ReadByte();
1979 
1980 	if( flags & PS_M_FLAGS )
1981 		to->pmove.pm_flags = MSG_ReadByte();
1982 
1983 	if( flags & PS_M_GRAVITY )
1984 		to->pmove.gravity = MSG_ReadShort();
1985 
1986 	if( flags & PS_M_DELTA_ANGLES ) {
1987 		to->pmove.delta_angles[0] = MSG_ReadShort();
1988 		to->pmove.delta_angles[1] = MSG_ReadShort();
1989 		to->pmove.delta_angles[2] = MSG_ReadShort();
1990 	}
1991 
1992 	//
1993 	// parse the rest of the player_state_t
1994 	//
1995 	if( flags & PS_VIEWOFFSET ) {
1996 		to->viewoffset[0] = MSG_ReadChar() * 0.25f;
1997 		to->viewoffset[1] = MSG_ReadChar() * 0.25f;
1998 		to->viewoffset[2] = MSG_ReadChar() * 0.25f;
1999 	}
2000 
2001 	if( flags & PS_VIEWANGLES ) {
2002 		to->viewangles[0] = MSG_ReadAngle16();
2003 		to->viewangles[1] = MSG_ReadAngle16();
2004 		to->viewangles[2] = MSG_ReadAngle16();
2005 	}
2006 
2007 	if( flags & PS_KICKANGLES ) {
2008 		to->kick_angles[0] = MSG_ReadChar() * 0.25f;
2009 		to->kick_angles[1] = MSG_ReadChar() * 0.25f;
2010 		to->kick_angles[2] = MSG_ReadChar() * 0.25f;
2011 	}
2012 
2013 	if( flags & PS_WEAPONINDEX ) {
2014 		to->gunindex = MSG_ReadByte();
2015 	}
2016 
2017 	if( flags & PS_WEAPONFRAME ) {
2018 		to->gunframe = MSG_ReadByte();
2019 		to->gunoffset[0] = MSG_ReadChar() * 0.25f;
2020 		to->gunoffset[1] = MSG_ReadChar() * 0.25f;
2021 		to->gunoffset[2] = MSG_ReadChar() * 0.25f;
2022 		to->gunangles[0] = MSG_ReadChar() * 0.25f;
2023 		to->gunangles[1] = MSG_ReadChar() * 0.25f;
2024 		to->gunangles[2] = MSG_ReadChar() * 0.25f;
2025 	}
2026 
2027 	if( flags & PS_BLEND ) {
2028 		to->blend[0] = MSG_ReadByte() / 255.0f;
2029 		to->blend[1] = MSG_ReadByte() / 255.0f;
2030 		to->blend[2] = MSG_ReadByte() / 255.0f;
2031 		to->blend[3] = MSG_ReadByte() / 255.0f;
2032 	}
2033 
2034 	if( flags & PS_FOV )
2035 		to->fov = MSG_ReadByte();
2036 
2037 	if( flags & PS_RDFLAGS )
2038 		to->rdflags = MSG_ReadByte();
2039 
2040 	// parse stats
2041 	statbits = MSG_ReadLong();
2042 	for( i = 0; i < MAX_STATS; i++ )
2043 		if( statbits & ( 1 << i ) )
2044 			to->stats[i] = MSG_ReadShort();
2045 }
2046 
2047 
2048 /*
2049 ===================
2050 MSG_ParseDeltaPlayerstate_Default
2051 ===================
2052 */
MSG_ParseDeltaPlayerstate_Enhanced(const playerStateEx_t * from,playerStateEx_t * to,int flags)2053 void MSG_ParseDeltaPlayerstate_Enhanced( const playerStateEx_t *from, playerStateEx_t *to, int flags ) {
2054 	int			i;
2055 	int			statbits;
2056 	int			extraflags;
2057 
2058 	if( !to ) {
2059 		Com_Error( ERR_DROP, "MSG_ParseDeltaPlayerstate_Enhanced: NULL" );
2060 	}
2061 
2062 	// clear to old value before delta parsing
2063 	if( from ) {
2064 		memcpy( to, from, sizeof( *to ) );
2065 	} else {
2066 		memset( to, 0, sizeof( *to ) );
2067 	}
2068 
2069 	extraflags = flags >> PS_BITS;
2070 	flags &= PS_MASK;
2071 
2072 	//
2073 	// parse the pmove_state_t
2074 	//
2075 	if( flags & PS_M_TYPE )
2076 		to->ps.pmove.pm_type = MSG_ReadByte();
2077 
2078 	if( flags & PS_M_ORIGIN ) {
2079 		to->ps.pmove.origin[0] = MSG_ReadShort();
2080 		to->ps.pmove.origin[1] = MSG_ReadShort();
2081 	}
2082 
2083 	if( extraflags & EPS_M_ORIGIN2 ) {
2084 		to->ps.pmove.origin[2] = MSG_ReadShort();
2085 	}
2086 
2087 	if( flags & PS_M_VELOCITY ) {
2088 		to->ps.pmove.velocity[0] = MSG_ReadShort();
2089 		to->ps.pmove.velocity[1] = MSG_ReadShort();
2090 	}
2091 
2092 	if( extraflags & EPS_M_VELOCITY2 ) {
2093 		to->ps.pmove.velocity[2] = MSG_ReadShort();
2094 	}
2095 
2096 	if( flags & PS_M_TIME )
2097 		to->ps.pmove.pm_time = MSG_ReadByte();
2098 
2099 	if( flags & PS_M_FLAGS )
2100 		to->ps.pmove.pm_flags = MSG_ReadByte();
2101 
2102 	if( flags & PS_M_GRAVITY )
2103 		to->ps.pmove.gravity = MSG_ReadShort();
2104 
2105 	if( flags & PS_M_DELTA_ANGLES ) {
2106 		to->ps.pmove.delta_angles[0] = MSG_ReadShort();
2107 		to->ps.pmove.delta_angles[1] = MSG_ReadShort();
2108 		to->ps.pmove.delta_angles[2] = MSG_ReadShort();
2109 	}
2110 
2111 	//
2112 	// parse the rest of the player_state_t
2113 	//
2114 	if( flags & PS_VIEWOFFSET ) {
2115 		to->ps.viewoffset[0] = MSG_ReadChar() * 0.25f;
2116 		to->ps.viewoffset[1] = MSG_ReadChar() * 0.25f;
2117 		to->ps.viewoffset[2] = MSG_ReadChar() * 0.25f;
2118 	}
2119 
2120 	if( flags & PS_VIEWANGLES ) {
2121 		to->ps.viewangles[0] = MSG_ReadAngle16();
2122 		to->ps.viewangles[1] = MSG_ReadAngle16();
2123 	}
2124 
2125 	if( extraflags & EPS_VIEWANGLE2 ) {
2126 		to->ps.viewangles[2] = MSG_ReadAngle16();
2127 	}
2128 
2129 	if( flags & PS_KICKANGLES ) {
2130 		to->ps.kick_angles[0] = MSG_ReadChar() * 0.25f;
2131 		to->ps.kick_angles[1] = MSG_ReadChar() * 0.25f;
2132 		to->ps.kick_angles[2] = MSG_ReadChar() * 0.25f;
2133 	}
2134 
2135 	if( flags & PS_WEAPONINDEX ) {
2136 		to->ps.gunindex = MSG_ReadByte();
2137 	}
2138 
2139 	if( flags & PS_WEAPONFRAME ) {
2140 		to->ps.gunframe = MSG_ReadByte();
2141 	}
2142 
2143 	if( extraflags & EPS_GUNOFFSET ) {
2144 		to->ps.gunoffset[0] = MSG_ReadChar() * 0.25f;
2145 		to->ps.gunoffset[1] = MSG_ReadChar() * 0.25f;
2146 		to->ps.gunoffset[2] = MSG_ReadChar() * 0.25f;
2147 	}
2148 
2149 	if( extraflags & EPS_GUNANGLES ) {
2150 		to->ps.gunangles[0] = MSG_ReadChar() * 0.25f;
2151 		to->ps.gunangles[1] = MSG_ReadChar() * 0.25f;
2152 		to->ps.gunangles[2] = MSG_ReadChar() * 0.25f;
2153 	}
2154 
2155 	if( flags & PS_BLEND ) {
2156 		to->ps.blend[0] = MSG_ReadByte() / 255.0f;
2157 		to->ps.blend[1] = MSG_ReadByte() / 255.0f;
2158 		to->ps.blend[2] = MSG_ReadByte() / 255.0f;
2159 		to->ps.blend[3] = MSG_ReadByte() / 255.0f;
2160 	}
2161 
2162 	if( flags & PS_FOV )
2163 		to->ps.fov = MSG_ReadByte();
2164 
2165 	if( flags & PS_RDFLAGS )
2166 		to->ps.rdflags = MSG_ReadByte();
2167 
2168 	if( extraflags & EPS_CLIENTNUM ) {
2169 		to->clientNum = MSG_ReadByte();
2170 	}
2171 
2172 	// parse stats
2173 	if( extraflags & EPS_STATS ) {
2174 		statbits = MSG_ReadLong();
2175 		for( i = 0; i < MAX_STATS; i++ ) {
2176 			if( statbits & ( 1 << i ) ) {
2177 				to->ps.stats[i] = MSG_ReadShort();
2178 			}
2179 		}
2180 	}
2181 
2182 }
2183 
2184 #define SHOWBITS( data ) \
2185 	do { Com_Printf( "%s ", data ); } while( 0 )
2186 
MSG_ShowDeltaEntityBits(int bits)2187 void MSG_ShowDeltaEntityBits( int bits ) {
2188 	if( bits & U_MODEL ) {
2189 		SHOWBITS( "modelindex" );
2190 	}
2191 	if( bits & U_MODEL2 ) {
2192 		SHOWBITS( "modelindex2" );
2193 	}
2194 	if( bits & U_MODEL3 ) {
2195 		SHOWBITS( "modelindex3" );
2196 	}
2197 	if( bits & U_MODEL4 ) {
2198 		SHOWBITS( "modelindex4" );
2199 	}
2200 
2201 	if( bits & U_FRAME8 )
2202 		SHOWBITS( "frame8" );
2203 	if( bits & U_FRAME16 )
2204 		SHOWBITS( "frame16" );
2205 
2206 	if( ( bits & ( U_SKIN8 | U_SKIN16 ) ) == ( U_SKIN8 | U_SKIN16 ) )
2207 		SHOWBITS( "skinnum32" );
2208 	else if( bits & U_SKIN8 )
2209 		SHOWBITS( "skinnum8" );
2210 	else if( bits & U_SKIN16 )
2211 		SHOWBITS( "skinnum16" );
2212 
2213 	if( ( bits & ( U_EFFECTS8 | U_EFFECTS16 ) ) == ( U_EFFECTS8 | U_EFFECTS16 ) )
2214 		SHOWBITS( "effects32" );
2215 	else if( bits & U_EFFECTS8 )
2216 		SHOWBITS( "effects8" );
2217 	else if( bits & U_EFFECTS16 )
2218 		SHOWBITS( "effects16" );
2219 
2220 	if( ( bits & ( U_RENDERFX8 | U_RENDERFX16 ) ) == ( U_RENDERFX8 | U_RENDERFX16 ) )
2221 		SHOWBITS( "renderfx32" );
2222 	else if( bits & U_RENDERFX8 )
2223 		SHOWBITS( "renderfx8" );
2224 	else if( bits & U_RENDERFX16 )
2225 		SHOWBITS( "renderfx16" );
2226 
2227 	if( bits & U_ORIGIN1 ) {
2228 		SHOWBITS( "origin[0]" );
2229 	}
2230 	if( bits & U_ORIGIN2 ) {
2231 		SHOWBITS( "origin[1]" );
2232 	}
2233 	if( bits & U_ORIGIN3 ) {
2234 		SHOWBITS( "origin[2]" );
2235 	}
2236 
2237 	if( bits & U_ANGLE1 ) {
2238 		SHOWBITS( "angles[0]" );
2239 	}
2240 	if( bits & U_ANGLE2 ) {
2241 		SHOWBITS( "angles[2]" );
2242 	}
2243 	if( bits & U_ANGLE3 ) {
2244 		SHOWBITS( "angles[3]" );
2245 	}
2246 
2247 	if( bits & U_OLDORIGIN ) {
2248 		SHOWBITS( "old_origin" );
2249 	}
2250 
2251 	if( bits & U_SOUND ) {
2252 		SHOWBITS( "sound" );
2253 	}
2254 
2255 	if( bits & U_EVENT ) {
2256 		SHOWBITS( "event" );
2257 	}
2258 
2259 	if( bits & U_SOLID ) {
2260 		SHOWBITS( "solid" );
2261 	}
2262 
2263 }
2264 
MSG_ShowDeltaPlayerstateBits_Default(int flags)2265 void MSG_ShowDeltaPlayerstateBits_Default( int flags ) {
2266 	if( flags & PS_M_TYPE ) {
2267 		SHOWBITS( "pmove.pm_type" );
2268 	}
2269 
2270 	if( flags & PS_M_ORIGIN ) {
2271 		SHOWBITS( "pmove.origin" );
2272 	}
2273 
2274 	if( flags & PS_M_VELOCITY ) {
2275 		SHOWBITS( "pmove.velocity" );
2276 	}
2277 
2278 	if( flags & PS_M_TIME ) {
2279 		SHOWBITS( "pmove.pm_time" );
2280 	}
2281 
2282 	if( flags & PS_M_FLAGS ) {
2283 		SHOWBITS( "pmove.pm_flags" );
2284 	}
2285 
2286 	if( flags & PS_M_GRAVITY ) {
2287 		SHOWBITS( "pmove.gravity" );
2288 	}
2289 
2290 	if( flags & PS_M_DELTA_ANGLES ) {
2291 		SHOWBITS( "pmove.delta_angles" );
2292 	}
2293 
2294 	if( flags & PS_VIEWOFFSET ) {
2295 		SHOWBITS( "viewoffset" );
2296 	}
2297 
2298 	if( flags & PS_VIEWANGLES ) {
2299 		SHOWBITS( "viewangles" );
2300 	}
2301 
2302 	if( flags & PS_KICKANGLES ) {
2303 		SHOWBITS( "kick_angles" );
2304 	}
2305 
2306 	if( flags & PS_WEAPONINDEX ) {
2307 		SHOWBITS( "gunindex" );
2308 	}
2309 
2310 	if( flags & PS_WEAPONFRAME ) {
2311 		SHOWBITS( "gunframe" );
2312 	}
2313 
2314 	if( flags & PS_BLEND ) {
2315 		SHOWBITS( "blend" );
2316 	}
2317 
2318 	if( flags & PS_FOV ) {
2319 		SHOWBITS( "fov" );
2320 	}
2321 
2322 	if( flags & PS_RDFLAGS ) {
2323 		SHOWBITS( "rdflags" );
2324 	}
2325 
2326 }
2327 
MSG_ShowDeltaPlayerstateBits_Enhanced(int flags)2328 void MSG_ShowDeltaPlayerstateBits_Enhanced( int flags ) {
2329 	int extraflags;
2330 
2331 	extraflags = flags >> PS_BITS;
2332 	flags &= PS_MASK;
2333 
2334 	if( flags & PS_M_TYPE ) {
2335 		SHOWBITS( "pmove.pm_type" );
2336 	}
2337 
2338 	if( flags & PS_M_ORIGIN ) {
2339 		SHOWBITS( "pmove.origin[0,1]" );
2340 	}
2341 
2342 	if( extraflags & EPS_M_ORIGIN2 ) {
2343 		SHOWBITS( "pmove.origin[2]" );
2344 	}
2345 
2346 	if( flags & PS_M_VELOCITY ) {
2347 		SHOWBITS( "pmove.velocity[0,1]" );
2348 	}
2349 
2350 	if( extraflags & EPS_M_VELOCITY2 ) {
2351 		SHOWBITS( "pmove.velocity[2]" );
2352 	}
2353 
2354 	if( flags & PS_M_TIME ) {
2355 		SHOWBITS( "pmove.pm_time" );
2356 	}
2357 
2358 	if( flags & PS_M_FLAGS ) {
2359 		SHOWBITS( "pmove.pm_flags" );
2360 	}
2361 
2362 	if( flags & PS_M_GRAVITY ) {
2363 		SHOWBITS( "pmove.gravity" );
2364 	}
2365 
2366 	if( flags & PS_M_DELTA_ANGLES ) {
2367 		SHOWBITS( "pmove.delta_angles" );
2368 	}
2369 
2370 	if( flags & PS_VIEWOFFSET ) {
2371 		SHOWBITS( "viewoffset" );
2372 	}
2373 
2374 	if( flags & PS_VIEWANGLES ) {
2375 		SHOWBITS( "viewangles[0,1]" );
2376 	}
2377 
2378 	if( extraflags & EPS_VIEWANGLE2 ) {
2379 		SHOWBITS( "viewangles[2]" );
2380 	}
2381 
2382 	if( flags & PS_KICKANGLES ) {
2383 		SHOWBITS( "kick_angles" );
2384 	}
2385 
2386 	if( flags & PS_WEAPONINDEX ) {
2387 		SHOWBITS( "gunindex" );
2388 	}
2389 
2390 	if( flags & PS_WEAPONFRAME ) {
2391 		SHOWBITS( "gunframe" );
2392 	}
2393 
2394 	if( extraflags & EPS_GUNOFFSET ) {
2395 		SHOWBITS( "gunoffset" );
2396 	}
2397 
2398 	if( extraflags & EPS_GUNANGLES ) {
2399 		SHOWBITS( "gunangles" );
2400 	}
2401 
2402 	if( flags & PS_BLEND ) {
2403 		SHOWBITS( "blend" );
2404 	}
2405 
2406 	if( flags & PS_FOV ) {
2407 		SHOWBITS( "fov" );
2408 	}
2409 
2410 	if( flags & PS_RDFLAGS ) {
2411 		SHOWBITS( "rdflags" );
2412 	}
2413 
2414 	if( extraflags & EPS_STATS ) {
2415 		SHOWBITS( "stats" );
2416 	}
2417 }
2418 
MSG_ShowDeltaUsercmdBits_Enhanced(int bits)2419 void MSG_ShowDeltaUsercmdBits_Enhanced( int bits ) {
2420 	if( !bits ) {
2421 		SHOWBITS( "<none>" );
2422 		return;
2423 	}
2424 	if( bits & CM_ANGLE1 )
2425 		SHOWBITS( "angle1" );
2426 	if( bits & CM_ANGLE2 )
2427 		SHOWBITS( "angle2" );
2428 	if( bits & CM_ANGLE3 )
2429 		SHOWBITS( "angle3" );
2430 
2431 	if( bits & CM_FORWARD )
2432 		SHOWBITS( "forward" );
2433 	if( bits & CM_SIDE )
2434 	  	SHOWBITS( "side" );
2435 	if( bits & CM_UP )
2436 		SHOWBITS( "up" );
2437 
2438  	if( bits & CM_BUTTONS )
2439 	  	SHOWBITS( "buttons" );
2440  	if( bits & CM_IMPULSE )
2441 	    SHOWBITS( "msec" );
2442 }
2443 
MSG_ServerCommandString(int cmd)2444 const char *MSG_ServerCommandString( int cmd ) {
2445     const char *s;
2446 
2447 #define MAPSVC( x )		case x: s = #x; break;
2448 
2449 	switch( cmd ) {
2450 		MAPSVC( svc_bad )
2451 		MAPSVC( svc_muzzleflash )
2452 		MAPSVC( svc_muzzleflash2 )
2453 		MAPSVC( svc_temp_entity )
2454 		MAPSVC( svc_layout )
2455 		MAPSVC( svc_inventory )
2456 		MAPSVC( svc_disconnect )
2457 		MAPSVC( svc_reconnect )
2458 		MAPSVC( svc_sound )
2459 		MAPSVC( svc_print )
2460 		MAPSVC( svc_stufftext )
2461 		MAPSVC( svc_serverdata )
2462 		MAPSVC( svc_configstring )
2463 		MAPSVC( svc_spawnbaseline )
2464 		MAPSVC( svc_centerprint )
2465 		MAPSVC( svc_download )
2466 		MAPSVC( svc_playerinfo )
2467 		MAPSVC( svc_packetentities )
2468 		MAPSVC( svc_deltapacketentities )
2469 		MAPSVC( svc_frame )
2470 		MAPSVC( svc_zpacket )
2471 		MAPSVC( svc_zdownload )
2472 		MAPSVC( svc_unicast )
2473 		MAPSVC( svc_multicast )
2474 		MAPSVC( svc_nop )
2475 		case -1: s = "END OF MESSAGE"; break;
2476 		default: s = "UNKNOWN COMMAND"; break;
2477 	}
2478 
2479 #undef MAPSVC
2480 
2481     return s;
2482 }
2483 
2484 //===========================================================================
2485 
SZ_Init(sizebuf_t * buf,byte * data,int length)2486 void SZ_Init( sizebuf_t *buf, byte *data, int length ) {
2487 	memset( buf, 0, sizeof( *buf ) );
2488 	buf->data = data;
2489 	buf->maxsize = length;
2490 	buf->allowoverflow = qtrue;
2491 }
2492 
SZ_Clear(sizebuf_t * buf)2493 void SZ_Clear( sizebuf_t *buf ) {
2494 	buf->cursize = 0;
2495 	buf->readcount = 0;
2496 	buf->bitpos = 0;
2497 	buf->overflowed = qfalse;
2498 }
2499 
SZ_GetSpace(sizebuf_t * buf,int length)2500 void *SZ_GetSpace( sizebuf_t *buf, int length ) {
2501 	void	*data;
2502 
2503 	if( buf->cursize + length > buf->maxsize ) {
2504 		if( !buf->allowoverflow ) {
2505 			Com_Error( ERR_FATAL, "SZ_GetSpace: overflow without allowoverflow set" );
2506 		}
2507 		if( length > buf->maxsize ) {
2508 			Com_Error( ERR_FATAL, "SZ_GetSpace: %i is > full buffer size", length );
2509 		}
2510 
2511 		Com_WPrintf( "SZ_GetSpace: overflow\n" );
2512 		SZ_Clear( buf );
2513 		buf->overflowed = qtrue;
2514 	}
2515 
2516 	data = buf->data + buf->cursize;
2517 	buf->cursize += length;
2518 	buf->bitpos = buf->cursize << 3;
2519 
2520 	return data;
2521 }
2522 
SZ_Write(sizebuf_t * buf,const void * data,int length)2523 void SZ_Write( sizebuf_t *buf, const void *data, int length ) {
2524 	memcpy( SZ_GetSpace( buf, length ), data, length );
2525 }
2526 
SZ_WriteByte(sizebuf_t * sb,int c)2527 void SZ_WriteByte( sizebuf_t *sb, int c ) {
2528 	byte	*buf;
2529 
2530 	buf = SZ_GetSpace( sb, 1 );
2531 	buf[0] = c;
2532 }
2533 
SZ_WriteShort(sizebuf_t * sb,int c)2534 void SZ_WriteShort( sizebuf_t *sb, int c ) {
2535 	byte	*buf;
2536 
2537 	buf = SZ_GetSpace( sb, 2 );
2538 	buf[0] = c & 0xff;
2539 	buf[1] = c >> 8;
2540 }
2541 
SZ_WriteLong(sizebuf_t * sb,int c)2542 void SZ_WriteLong( sizebuf_t *sb, int c ) {
2543 	byte	*buf;
2544 
2545 	buf = SZ_GetSpace( sb, 4 );
2546 	buf[0] = c & 0xff;
2547 	buf[1] = ( c >> 8 ) & 0xff;
2548 	buf[2] = ( c >> 16 ) & 0xff;
2549 	buf[3] = c >> 24;
2550 }
2551 
SZ_WritePos(sizebuf_t * sb,const vec3_t pos)2552 void SZ_WritePos( sizebuf_t *sb, const vec3_t pos ) {
2553 	SZ_WriteShort( sb, ( int )( pos[0] * 8 ) );
2554 	SZ_WriteShort( sb, ( int )( pos[1] * 8 ) );
2555 	SZ_WriteShort( sb, ( int )( pos[2] * 8 ) );
2556 }
2557 
SZ_WriteExactPos(sizebuf_t * sb,const vec3_t pos)2558 void SZ_WriteExactPos( sizebuf_t *sb, const vec3_t pos ) {
2559 	SZ_WriteLong( sb, *( int * )&pos[0] );
2560 	SZ_WriteLong( sb, *( int * )&pos[1] );
2561 	SZ_WriteLong( sb, *( int * )&pos[2] );
2562 }
2563 
SZ_WriteString(sizebuf_t * sb,const char * string)2564 void SZ_WriteString( sizebuf_t *sb, const char *string ) {
2565 	int length;
2566 	int c;
2567 
2568 	if( !string ) {
2569 		SZ_WriteByte( sb, 0 );
2570 		return;
2571 	}
2572 
2573 	length = strlen( string );
2574 	if( length > MAX_NET_STRING - 1 ) {
2575 		Com_WPrintf( "SZ_WriteString: overflow: %d chars", length );
2576 		SZ_WriteByte( sb, 0 );
2577 		return;
2578 	}
2579 
2580 	while( *string ) {
2581 		c = *string++;
2582 		if( c == '\xFF' ) {
2583 			c = '.';
2584 		}
2585 		SZ_WriteByte( sb, c );
2586 	}
2587 
2588 	SZ_WriteByte( sb, 0 );
2589 }
2590 
2591 
2592 
2593 
2594