diff options
author | zakk <zakk@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-08-26 17:39:27 +0000 |
---|---|---|
committer | zakk <zakk@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-08-26 17:39:27 +0000 |
commit | 6bf20c78f5b69d40bcc4931df93d29198435ab67 (patch) | |
tree | e3eda937a05d7db42de725b7013bd0344b987f34 /code/qcommon/msg.c | |
parent | 872d4d7f55af706737ffb361bb76ad13e7496770 (diff) | |
download | ioquake3-aero-6bf20c78f5b69d40bcc4931df93d29198435ab67.tar.gz ioquake3-aero-6bf20c78f5b69d40bcc4931df93d29198435ab67.zip |
newlines fixed
git-svn-id: svn://svn.icculus.org/quake3/trunk@6 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'code/qcommon/msg.c')
-rwxr-xr-x | code/qcommon/msg.c | 3514 |
1 files changed, 1757 insertions, 1757 deletions
diff --git a/code/qcommon/msg.c b/code/qcommon/msg.c index 27891cc..0d8ff17 100755 --- a/code/qcommon/msg.c +++ b/code/qcommon/msg.c @@ -1,1757 +1,1757 @@ -/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Foobar; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-#include "../game/q_shared.h"
-#include "qcommon.h"
-
-static huffman_t msgHuff;
-
-static qboolean msgInit = qfalse;
-
-int pcount[256];
-
-/*
-==============================================================================
-
- MESSAGE IO FUNCTIONS
-
-Handles byte ordering and avoids alignment errors
-==============================================================================
-*/
-
-int oldsize = 0;
-
-void MSG_initHuffman();
-
-void MSG_Init( msg_t *buf, byte *data, int length ) {
- if (!msgInit) {
- MSG_initHuffman();
- }
- Com_Memset (buf, 0, sizeof(*buf));
- buf->data = data;
- buf->maxsize = length;
-}
-
-void MSG_InitOOB( msg_t *buf, byte *data, int length ) {
- if (!msgInit) {
- MSG_initHuffman();
- }
- Com_Memset (buf, 0, sizeof(*buf));
- buf->data = data;
- buf->maxsize = length;
- buf->oob = qtrue;
-}
-
-void MSG_Clear( msg_t *buf ) {
- buf->cursize = 0;
- buf->overflowed = qfalse;
- buf->bit = 0; //<- in bits
-}
-
-
-void MSG_Bitstream( msg_t *buf ) {
- buf->oob = qfalse;
-}
-
-void MSG_BeginReading( msg_t *msg ) {
- msg->readcount = 0;
- msg->bit = 0;
- msg->oob = qfalse;
-}
-
-void MSG_BeginReadingOOB( msg_t *msg ) {
- msg->readcount = 0;
- msg->bit = 0;
- msg->oob = qtrue;
-}
-
-void MSG_Copy(msg_t *buf, byte *data, int length, msg_t *src)
-{
- if (length<src->cursize) {
- Com_Error( ERR_DROP, "MSG_Copy: can't copy into a smaller msg_t buffer");
- }
- Com_Memcpy(buf, src, sizeof(msg_t));
- buf->data = data;
- Com_Memcpy(buf->data, src->data, src->cursize);
-}
-
-/*
-=============================================================================
-
-bit functions
-
-=============================================================================
-*/
-
-int overflows;
-
-// negative bit values include signs
-void MSG_WriteBits( msg_t *msg, int value, int bits ) {
- int i;
-// FILE* fp;
-
- oldsize += bits;
-
- // this isn't an exact overflow check, but close enough
- if ( msg->maxsize - msg->cursize < 4 ) {
- msg->overflowed = qtrue;
- return;
- }
-
- if ( bits == 0 || bits < -31 || bits > 32 ) {
- Com_Error( ERR_DROP, "MSG_WriteBits: bad bits %i", bits );
- }
-
- // check for overflows
- if ( bits != 32 ) {
- if ( bits > 0 ) {
- if ( value > ( ( 1 << bits ) - 1 ) || value < 0 ) {
- overflows++;
- }
- } else {
- int r;
-
- r = 1 << (bits-1);
-
- if ( value > r - 1 || value < -r ) {
- overflows++;
- }
- }
- }
- if ( bits < 0 ) {
- bits = -bits;
- }
- if (msg->oob) {
- if (bits==8) {
- msg->data[msg->cursize] = value;
- msg->cursize += 1;
- msg->bit += 8;
- } else if (bits==16) {
- unsigned short *sp = (unsigned short *)&msg->data[msg->cursize];
- *sp = LittleShort(value);
- msg->cursize += 2;
- msg->bit += 16;
- } else if (bits==32) {
- unsigned int *ip = (unsigned int *)&msg->data[msg->cursize];
- *ip = LittleLong(value);
- msg->cursize += 4;
- msg->bit += 8;
- } else {
- Com_Error(ERR_DROP, "can't read %d bits\n", bits);
- }
- } else {
-// fp = fopen("c:\\netchan.bin", "a");
- value &= (0xffffffff>>(32-bits));
- if (bits&7) {
- int nbits;
- nbits = bits&7;
- for(i=0;i<nbits;i++) {
- Huff_putBit((value&1), msg->data, &msg->bit);
- value = (value>>1);
- }
- bits = bits - nbits;
- }
- if (bits) {
- for(i=0;i<bits;i+=8) {
-// fwrite(bp, 1, 1, fp);
- Huff_offsetTransmit (&msgHuff.compressor, (value&0xff), msg->data, &msg->bit);
- value = (value>>8);
- }
- }
- msg->cursize = (msg->bit>>3)+1;
-// fclose(fp);
- }
-}
-
-int MSG_ReadBits( msg_t *msg, int bits ) {
- int value;
- int get;
- qboolean sgn;
- int i, nbits;
-// FILE* fp;
-
- value = 0;
-
- if ( bits < 0 ) {
- bits = -bits;
- sgn = qtrue;
- } else {
- sgn = qfalse;
- }
-
- if (msg->oob) {
- if (bits==8) {
- value = msg->data[msg->readcount];
- msg->readcount += 1;
- msg->bit += 8;
- } else if (bits==16) {
- unsigned short *sp = (unsigned short *)&msg->data[msg->readcount];
- value = LittleShort(*sp);
- msg->readcount += 2;
- msg->bit += 16;
- } else if (bits==32) {
- unsigned int *ip = (unsigned int *)&msg->data[msg->readcount];
- value = LittleLong(*ip);
- msg->readcount += 4;
- msg->bit += 32;
- } else {
- Com_Error(ERR_DROP, "can't read %d bits\n", bits);
- }
- } else {
- nbits = 0;
- if (bits&7) {
- nbits = bits&7;
- for(i=0;i<nbits;i++) {
- value |= (Huff_getBit(msg->data, &msg->bit)<<i);
- }
- bits = bits - nbits;
- }
- if (bits) {
-// fp = fopen("c:\\netchan.bin", "a");
- for(i=0;i<bits;i+=8) {
- Huff_offsetReceive (msgHuff.decompressor.tree, &get, msg->data, &msg->bit);
-// fwrite(&get, 1, 1, fp);
- value |= (get<<(i+nbits));
- }
-// fclose(fp);
- }
- msg->readcount = (msg->bit>>3)+1;
- }
- if ( sgn ) {
- if ( value & ( 1 << ( bits - 1 ) ) ) {
- value |= -1 ^ ( ( 1 << bits ) - 1 );
- }
- }
-
- return value;
-}
-
-
-
-//================================================================================
-
-//
-// writing functions
-//
-
-void MSG_WriteChar( msg_t *sb, int c ) {
-#ifdef PARANOID
- if (c < -128 || c > 127)
- Com_Error (ERR_FATAL, "MSG_WriteChar: range error");
-#endif
-
- MSG_WriteBits( sb, c, 8 );
-}
-
-void MSG_WriteByte( msg_t *sb, int c ) {
-#ifdef PARANOID
- if (c < 0 || c > 255)
- Com_Error (ERR_FATAL, "MSG_WriteByte: range error");
-#endif
-
- MSG_WriteBits( sb, c, 8 );
-}
-
-void MSG_WriteData( msg_t *buf, const void *data, int length ) {
- int i;
- for(i=0;i<length;i++) {
- MSG_WriteByte(buf, ((byte *)data)[i]);
- }
-}
-
-void MSG_WriteShort( msg_t *sb, int c ) {
-#ifdef PARANOID
- if (c < ((short)0x8000) || c > (short)0x7fff)
- Com_Error (ERR_FATAL, "MSG_WriteShort: range error");
-#endif
-
- MSG_WriteBits( sb, c, 16 );
-}
-
-void MSG_WriteLong( msg_t *sb, int c ) {
- MSG_WriteBits( sb, c, 32 );
-}
-
-void MSG_WriteFloat( msg_t *sb, float f ) {
- union {
- float f;
- int l;
- } dat;
-
- dat.f = f;
- MSG_WriteBits( sb, dat.l, 32 );
-}
-
-void MSG_WriteString( msg_t *sb, const char *s ) {
- if ( !s ) {
- MSG_WriteData (sb, "", 1);
- } else {
- int l,i;
- char string[MAX_STRING_CHARS];
-
- l = strlen( s );
- if ( l >= MAX_STRING_CHARS ) {
- Com_Printf( "MSG_WriteString: MAX_STRING_CHARS" );
- MSG_WriteData (sb, "", 1);
- return;
- }
- Q_strncpyz( string, s, sizeof( string ) );
-
- // get rid of 0xff chars, because old clients don't like them
- for ( i = 0 ; i < l ; i++ ) {
- if ( ((byte *)string)[i] > 127 ) {
- string[i] = '.';
- }
- }
-
- MSG_WriteData (sb, string, l+1);
- }
-}
-
-void MSG_WriteBigString( msg_t *sb, const char *s ) {
- if ( !s ) {
- MSG_WriteData (sb, "", 1);
- } else {
- int l,i;
- char string[BIG_INFO_STRING];
-
- l = strlen( s );
- if ( l >= BIG_INFO_STRING ) {
- Com_Printf( "MSG_WriteString: BIG_INFO_STRING" );
- MSG_WriteData (sb, "", 1);
- return;
- }
- Q_strncpyz( string, s, sizeof( string ) );
-
- // get rid of 0xff chars, because old clients don't like them
- for ( i = 0 ; i < l ; i++ ) {
- if ( ((byte *)string)[i] > 127 ) {
- string[i] = '.';
- }
- }
-
- MSG_WriteData (sb, string, l+1);
- }
-}
-
-void MSG_WriteAngle( msg_t *sb, float f ) {
- MSG_WriteByte (sb, (int)(f*256/360) & 255);
-}
-
-void MSG_WriteAngle16( msg_t *sb, float f ) {
- MSG_WriteShort (sb, ANGLE2SHORT(f));
-}
-
-
-//============================================================
-
-//
-// reading functions
-//
-
-// returns -1 if no more characters are available
-int MSG_ReadChar (msg_t *msg ) {
- int c;
-
- c = (signed char)MSG_ReadBits( msg, 8 );
- if ( msg->readcount > msg->cursize ) {
- c = -1;
- }
-
- return c;
-}
-
-int MSG_ReadByte( msg_t *msg ) {
- int c;
-
- c = (unsigned char)MSG_ReadBits( msg, 8 );
- if ( msg->readcount > msg->cursize ) {
- c = -1;
- }
- return c;
-}
-
-int MSG_ReadShort( msg_t *msg ) {
- int c;
-
- c = (short)MSG_ReadBits( msg, 16 );
- if ( msg->readcount > msg->cursize ) {
- c = -1;
- }
-
- return c;
-}
-
-int MSG_ReadLong( msg_t *msg ) {
- int c;
-
- c = MSG_ReadBits( msg, 32 );
- if ( msg->readcount > msg->cursize ) {
- c = -1;
- }
-
- return c;
-}
-
-float MSG_ReadFloat( msg_t *msg ) {
- union {
- byte b[4];
- float f;
- int l;
- } dat;
-
- dat.l = MSG_ReadBits( msg, 32 );
- if ( msg->readcount > msg->cursize ) {
- dat.f = -1;
- }
-
- return dat.f;
-}
-
-char *MSG_ReadString( msg_t *msg ) {
- static char string[MAX_STRING_CHARS];
- int l,c;
-
- l = 0;
- do {
- c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds
- if ( c == -1 || c == 0 ) {
- break;
- }
- // translate all fmt spec to avoid crash bugs
- if ( c == '%' ) {
- c = '.';
- }
- // don't allow higher ascii values
- if ( c > 127 ) {
- c = '.';
- }
-
- string[l] = c;
- l++;
- } while (l < sizeof(string)-1);
-
- string[l] = 0;
-
- return string;
-}
-
-char *MSG_ReadBigString( msg_t *msg ) {
- static char string[BIG_INFO_STRING];
- int l,c;
-
- l = 0;
- do {
- c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds
- if ( c == -1 || c == 0 ) {
- break;
- }
- // translate all fmt spec to avoid crash bugs
- if ( c == '%' ) {
- c = '.';
- }
-
- string[l] = c;
- l++;
- } while (l < sizeof(string)-1);
-
- string[l] = 0;
-
- return string;
-}
-
-char *MSG_ReadStringLine( msg_t *msg ) {
- static char string[MAX_STRING_CHARS];
- int l,c;
-
- l = 0;
- do {
- c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds
- if (c == -1 || c == 0 || c == '\n') {
- break;
- }
- // translate all fmt spec to avoid crash bugs
- if ( c == '%' ) {
- c = '.';
- }
- string[l] = c;
- l++;
- } while (l < sizeof(string)-1);
-
- string[l] = 0;
-
- return string;
-}
-
-float MSG_ReadAngle16( msg_t *msg ) {
- return SHORT2ANGLE(MSG_ReadShort(msg));
-}
-
-void MSG_ReadData( msg_t *msg, void *data, int len ) {
- int i;
-
- for (i=0 ; i<len ; i++) {
- ((byte *)data)[i] = MSG_ReadByte (msg);
- }
-}
-
-
-/*
-=============================================================================
-
-delta functions
-
-=============================================================================
-*/
-
-extern cvar_t *cl_shownet;
-
-#define LOG(x) if( cl_shownet->integer == 4 ) { Com_Printf("%s ", x ); };
-
-void MSG_WriteDelta( msg_t *msg, int oldV, int newV, int bits ) {
- if ( oldV == newV ) {
- MSG_WriteBits( msg, 0, 1 );
- return;
- }
- MSG_WriteBits( msg, 1, 1 );
- MSG_WriteBits( msg, newV, bits );
-}
-
-int MSG_ReadDelta( msg_t *msg, int oldV, int bits ) {
- if ( MSG_ReadBits( msg, 1 ) ) {
- return MSG_ReadBits( msg, bits );
- }
- return oldV;
-}
-
-void MSG_WriteDeltaFloat( msg_t *msg, float oldV, float newV ) {
- if ( oldV == newV ) {
- MSG_WriteBits( msg, 0, 1 );
- return;
- }
- MSG_WriteBits( msg, 1, 1 );
- MSG_WriteBits( msg, *(int *)&newV, 32 );
-}
-
-float MSG_ReadDeltaFloat( msg_t *msg, float oldV ) {
- if ( MSG_ReadBits( msg, 1 ) ) {
- float newV;
-
- *(int *)&newV = MSG_ReadBits( msg, 32 );
- return newV;
- }
- return oldV;
-}
-
-/*
-=============================================================================
-
-delta functions with keys
-
-=============================================================================
-*/
-
-int kbitmask[32] = {
- 0x00000001, 0x00000003, 0x00000007, 0x0000000F,
- 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
- 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
- 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
- 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
- 0x001FFFFf, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
- 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
- 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF,
-};
-
-void MSG_WriteDeltaKey( msg_t *msg, int key, int oldV, int newV, int bits ) {
- if ( oldV == newV ) {
- MSG_WriteBits( msg, 0, 1 );
- return;
- }
- MSG_WriteBits( msg, 1, 1 );
- MSG_WriteBits( msg, newV ^ key, bits );
-}
-
-int MSG_ReadDeltaKey( msg_t *msg, int key, int oldV, int bits ) {
- if ( MSG_ReadBits( msg, 1 ) ) {
- return MSG_ReadBits( msg, bits ) ^ (key & kbitmask[bits]);
- }
- return oldV;
-}
-
-void MSG_WriteDeltaKeyFloat( msg_t *msg, int key, float oldV, float newV ) {
- if ( oldV == newV ) {
- MSG_WriteBits( msg, 0, 1 );
- return;
- }
- MSG_WriteBits( msg, 1, 1 );
- MSG_WriteBits( msg, (*(int *)&newV) ^ key, 32 );
-}
-
-float MSG_ReadDeltaKeyFloat( msg_t *msg, int key, float oldV ) {
- if ( MSG_ReadBits( msg, 1 ) ) {
- float newV;
-
- *(int *)&newV = MSG_ReadBits( msg, 32 ) ^ key;
- return newV;
- }
- return oldV;
-}
-
-
-/*
-============================================================================
-
-usercmd_t communication
-
-============================================================================
-*/
-
-// ms is allways sent, the others are optional
-#define CM_ANGLE1 (1<<0)
-#define CM_ANGLE2 (1<<1)
-#define CM_ANGLE3 (1<<2)
-#define CM_FORWARD (1<<3)
-#define CM_SIDE (1<<4)
-#define CM_UP (1<<5)
-#define CM_BUTTONS (1<<6)
-#define CM_WEAPON (1<<7)
-
-/*
-=====================
-MSG_WriteDeltaUsercmd
-=====================
-*/
-void MSG_WriteDeltaUsercmd( msg_t *msg, usercmd_t *from, usercmd_t *to ) {
- if ( to->serverTime - from->serverTime < 256 ) {
- MSG_WriteBits( msg, 1, 1 );
- MSG_WriteBits( msg, to->serverTime - from->serverTime, 8 );
- } else {
- MSG_WriteBits( msg, 0, 1 );
- MSG_WriteBits( msg, to->serverTime, 32 );
- }
- MSG_WriteDelta( msg, from->angles[0], to->angles[0], 16 );
- MSG_WriteDelta( msg, from->angles[1], to->angles[1], 16 );
- MSG_WriteDelta( msg, from->angles[2], to->angles[2], 16 );
- MSG_WriteDelta( msg, from->forwardmove, to->forwardmove, 8 );
- MSG_WriteDelta( msg, from->rightmove, to->rightmove, 8 );
- MSG_WriteDelta( msg, from->upmove, to->upmove, 8 );
- MSG_WriteDelta( msg, from->buttons, to->buttons, 16 );
- MSG_WriteDelta( msg, from->weapon, to->weapon, 8 );
-}
-
-
-/*
-=====================
-MSG_ReadDeltaUsercmd
-=====================
-*/
-void MSG_ReadDeltaUsercmd( msg_t *msg, usercmd_t *from, usercmd_t *to ) {
- if ( MSG_ReadBits( msg, 1 ) ) {
- to->serverTime = from->serverTime + MSG_ReadBits( msg, 8 );
- } else {
- to->serverTime = MSG_ReadBits( msg, 32 );
- }
- to->angles[0] = MSG_ReadDelta( msg, from->angles[0], 16);
- to->angles[1] = MSG_ReadDelta( msg, from->angles[1], 16);
- to->angles[2] = MSG_ReadDelta( msg, from->angles[2], 16);
- to->forwardmove = MSG_ReadDelta( msg, from->forwardmove, 8);
- to->rightmove = MSG_ReadDelta( msg, from->rightmove, 8);
- to->upmove = MSG_ReadDelta( msg, from->upmove, 8);
- to->buttons = MSG_ReadDelta( msg, from->buttons, 16);
- to->weapon = MSG_ReadDelta( msg, from->weapon, 8);
-}
-
-/*
-=====================
-MSG_WriteDeltaUsercmd
-=====================
-*/
-void MSG_WriteDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *to ) {
- if ( to->serverTime - from->serverTime < 256 ) {
- MSG_WriteBits( msg, 1, 1 );
- MSG_WriteBits( msg, to->serverTime - from->serverTime, 8 );
- } else {
- MSG_WriteBits( msg, 0, 1 );
- MSG_WriteBits( msg, to->serverTime, 32 );
- }
- if (from->angles[0] == to->angles[0] &&
- from->angles[1] == to->angles[1] &&
- from->angles[2] == to->angles[2] &&
- from->forwardmove == to->forwardmove &&
- from->rightmove == to->rightmove &&
- from->upmove == to->upmove &&
- from->buttons == to->buttons &&
- from->weapon == to->weapon) {
- MSG_WriteBits( msg, 0, 1 ); // no change
- oldsize += 7;
- return;
- }
- key ^= to->serverTime;
- MSG_WriteBits( msg, 1, 1 );
- MSG_WriteDeltaKey( msg, key, from->angles[0], to->angles[0], 16 );
- MSG_WriteDeltaKey( msg, key, from->angles[1], to->angles[1], 16 );
- MSG_WriteDeltaKey( msg, key, from->angles[2], to->angles[2], 16 );
- MSG_WriteDeltaKey( msg, key, from->forwardmove, to->forwardmove, 8 );
- MSG_WriteDeltaKey( msg, key, from->rightmove, to->rightmove, 8 );
- MSG_WriteDeltaKey( msg, key, from->upmove, to->upmove, 8 );
- MSG_WriteDeltaKey( msg, key, from->buttons, to->buttons, 16 );
- MSG_WriteDeltaKey( msg, key, from->weapon, to->weapon, 8 );
-}
-
-
-/*
-=====================
-MSG_ReadDeltaUsercmd
-=====================
-*/
-void MSG_ReadDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *to ) {
- if ( MSG_ReadBits( msg, 1 ) ) {
- to->serverTime = from->serverTime + MSG_ReadBits( msg, 8 );
- } else {
- to->serverTime = MSG_ReadBits( msg, 32 );
- }
- if ( MSG_ReadBits( msg, 1 ) ) {
- key ^= to->serverTime;
- to->angles[0] = MSG_ReadDeltaKey( msg, key, from->angles[0], 16);
- to->angles[1] = MSG_ReadDeltaKey( msg, key, from->angles[1], 16);
- to->angles[2] = MSG_ReadDeltaKey( msg, key, from->angles[2], 16);
- to->forwardmove = MSG_ReadDeltaKey( msg, key, from->forwardmove, 8);
- to->rightmove = MSG_ReadDeltaKey( msg, key, from->rightmove, 8);
- to->upmove = MSG_ReadDeltaKey( msg, key, from->upmove, 8);
- to->buttons = MSG_ReadDeltaKey( msg, key, from->buttons, 16);
- to->weapon = MSG_ReadDeltaKey( msg, key, from->weapon, 8);
- } else {
- to->angles[0] = from->angles[0];
- to->angles[1] = from->angles[1];
- to->angles[2] = from->angles[2];
- to->forwardmove = from->forwardmove;
- to->rightmove = from->rightmove;
- to->upmove = from->upmove;
- to->buttons = from->buttons;
- to->weapon = from->weapon;
- }
-}
-
-/*
-=============================================================================
-
-entityState_t communication
-
-=============================================================================
-*/
-
-/*
-=================
-MSG_ReportChangeVectors_f
-
-Prints out a table from the current statistics for copying to code
-=================
-*/
-void MSG_ReportChangeVectors_f( void ) {
- int i;
- for(i=0;i<256;i++) {
- if (pcount[i]) {
- Com_Printf("%d used %d\n", i, pcount[i]);
- }
- }
-}
-
-typedef struct {
- char *name;
- int offset;
- int bits; // 0 = float
-} netField_t;
-
-// using the stringizing operator to save typing...
-#define NETF(x) #x,(int)&((entityState_t*)0)->x
-
-netField_t entityStateFields[] =
-{
-{ NETF(pos.trTime), 32 },
-{ NETF(pos.trBase[0]), 0 },
-{ NETF(pos.trBase[1]), 0 },
-{ NETF(pos.trDelta[0]), 0 },
-{ NETF(pos.trDelta[1]), 0 },
-{ NETF(pos.trBase[2]), 0 },
-{ NETF(apos.trBase[1]), 0 },
-{ NETF(pos.trDelta[2]), 0 },
-{ NETF(apos.trBase[0]), 0 },
-{ NETF(event), 10 },
-{ NETF(angles2[1]), 0 },
-{ NETF(eType), 8 },
-{ NETF(torsoAnim), 8 },
-{ NETF(eventParm), 8 },
-{ NETF(legsAnim), 8 },
-{ NETF(groundEntityNum), GENTITYNUM_BITS },
-{ NETF(pos.trType), 8 },
-{ NETF(eFlags), 19 },
-{ NETF(otherEntityNum), GENTITYNUM_BITS },
-{ NETF(weapon), 8 },
-{ NETF(clientNum), 8 },
-{ NETF(angles[1]), 0 },
-{ NETF(pos.trDuration), 32 },
-{ NETF(apos.trType), 8 },
-{ NETF(origin[0]), 0 },
-{ NETF(origin[1]), 0 },
-{ NETF(origin[2]), 0 },
-{ NETF(solid), 24 },
-{ NETF(powerups), 16 },
-{ NETF(modelindex), 8 },
-{ NETF(otherEntityNum2), GENTITYNUM_BITS },
-{ NETF(loopSound), 8 },
-{ NETF(generic1), 8 },
-{ NETF(origin2[2]), 0 },
-{ NETF(origin2[0]), 0 },
-{ NETF(origin2[1]), 0 },
-{ NETF(modelindex2), 8 },
-{ NETF(angles[0]), 0 },
-{ NETF(time), 32 },
-{ NETF(apos.trTime), 32 },
-{ NETF(apos.trDuration), 32 },
-{ NETF(apos.trBase[2]), 0 },
-{ NETF(apos.trDelta[0]), 0 },
-{ NETF(apos.trDelta[1]), 0 },
-{ NETF(apos.trDelta[2]), 0 },
-{ NETF(time2), 32 },
-{ NETF(angles[2]), 0 },
-{ NETF(angles2[0]), 0 },
-{ NETF(angles2[2]), 0 },
-{ NETF(constantLight), 32 },
-{ NETF(frame), 16 }
-};
-
-
-// if (int)f == f and (int)f + ( 1<<(FLOAT_INT_BITS-1) ) < ( 1 << FLOAT_INT_BITS )
-// the float will be sent with FLOAT_INT_BITS, otherwise all 32 bits will be sent
-#define FLOAT_INT_BITS 13
-#define FLOAT_INT_BIAS (1<<(FLOAT_INT_BITS-1))
-
-/*
-==================
-MSG_WriteDeltaEntity
-
-Writes part of a packetentities message, including the entity number.
-Can delta from either a baseline or a previous packet_entity
-If to is NULL, a remove entity update will be sent
-If force is not set, then nothing at all will be generated if the entity is
-identical, under the assumption that the in-order delta code will catch it.
-==================
-*/
-void MSG_WriteDeltaEntity( msg_t *msg, struct entityState_s *from, struct entityState_s *to,
- qboolean force ) {
- int i, lc;
- int numFields;
- netField_t *field;
- int trunc;
- float fullFloat;
- int *fromF, *toF;
-
- numFields = sizeof(entityStateFields)/sizeof(entityStateFields[0]);
-
- // all fields should be 32 bits to avoid any compiler packing issues
- // the "number" field is not part of the field list
- // if this assert fails, someone added a field to the entityState_t
- // struct without updating the message fields
- assert( numFields + 1 == sizeof( *from )/4 );
-
- // a NULL to is a delta remove message
- if ( to == NULL ) {
- if ( from == NULL ) {
- return;
- }
- MSG_WriteBits( msg, from->number, GENTITYNUM_BITS );
- MSG_WriteBits( msg, 1, 1 );
- return;
- }
-
- if ( to->number < 0 || to->number >= MAX_GENTITIES ) {
- Com_Error (ERR_FATAL, "MSG_WriteDeltaEntity: Bad entity number: %i", to->number );
- }
-
- lc = 0;
- // build the change vector as bytes so it is endien independent
- for ( i = 0, field = entityStateFields ; i < numFields ; i++, field++ ) {
- fromF = (int *)( (byte *)from + field->offset );
- toF = (int *)( (byte *)to + field->offset );
- if ( *fromF != *toF ) {
- lc = i+1;
- }
- }
-
- if ( lc == 0 ) {
- // nothing at all changed
- if ( !force ) {
- return; // nothing at all
- }
- // write two bits for no change
- MSG_WriteBits( msg, to->number, GENTITYNUM_BITS );
- MSG_WriteBits( msg, 0, 1 ); // not removed
- MSG_WriteBits( msg, 0, 1 ); // no delta
- return;
- }
-
- MSG_WriteBits( msg, to->number, GENTITYNUM_BITS );
- MSG_WriteBits( msg, 0, 1 ); // not removed
- MSG_WriteBits( msg, 1, 1 ); // we have a delta
-
- MSG_WriteByte( msg, lc ); // # of changes
-
- oldsize += numFields;
-
- for ( i = 0, field = entityStateFields ; i < lc ; i++, field++ ) {
- fromF = (int *)( (byte *)from + field->offset );
- toF = (int *)( (byte *)to + field->offset );
-
- if ( *fromF == *toF ) {
- MSG_WriteBits( msg, 0, 1 ); // no change
- continue;
- }
-
- MSG_WriteBits( msg, 1, 1 ); // changed
-
- if ( field->bits == 0 ) {
- // float
- fullFloat = *(float *)toF;
- trunc = (int)fullFloat;
-
- if (fullFloat == 0.0f) {
- MSG_WriteBits( msg, 0, 1 );
- oldsize += FLOAT_INT_BITS;
- } else {
- MSG_WriteBits( msg, 1, 1 );
- if ( trunc == fullFloat && trunc + FLOAT_INT_BIAS >= 0 &&
- trunc + FLOAT_INT_BIAS < ( 1 << FLOAT_INT_BITS ) ) {
- // send as small integer
- MSG_WriteBits( msg, 0, 1 );
- MSG_WriteBits( msg, trunc + FLOAT_INT_BIAS, FLOAT_INT_BITS );
- } else {
- // send as full floating point value
- MSG_WriteBits( msg, 1, 1 );
- MSG_WriteBits( msg, *toF, 32 );
- }
- }
- } else {
- if (*toF == 0) {
- MSG_WriteBits( msg, 0, 1 );
- } else {
- MSG_WriteBits( msg, 1, 1 );
- // integer
- MSG_WriteBits( msg, *toF, field->bits );
- }
- }
- }
-}
-
-/*
-==================
-MSG_ReadDeltaEntity
-
-The entity number has already been read from the message, which
-is how the from state is identified.
-
-If the delta removes the entity, entityState_t->number will be set to MAX_GENTITIES-1
-
-Can go from either a baseline or a previous packet_entity
-==================
-*/
-extern cvar_t *cl_shownet;
-
-void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to,
- int number) {
- int i, lc;
- int numFields;
- netField_t *field;
- int *fromF, *toF;
- int print;
- int trunc;
- int startBit, endBit;
-
- if ( number < 0 || number >= MAX_GENTITIES) {
- Com_Error( ERR_DROP, "Bad delta entity number: %i", number );
- }
-
- if ( msg->bit == 0 ) {
- startBit = msg->readcount * 8 - GENTITYNUM_BITS;
- } else {
- startBit = ( msg->readcount - 1 ) * 8 + msg->bit - GENTITYNUM_BITS;
- }
-
- // check for a remove
- if ( MSG_ReadBits( msg, 1 ) == 1 ) {
- Com_Memset( to, 0, sizeof( *to ) );
- to->number = MAX_GENTITIES - 1;
- if ( cl_shownet->integer >= 2 || cl_shownet->integer == -1 ) {
- Com_Printf( "%3i: #%-3i remove\n", msg->readcount, number );
- }
- return;
- }
-
- // check for no delta
- if ( MSG_ReadBits( msg, 1 ) == 0 ) {
- *to = *from;
- to->number = number;
- return;
- }
-
- numFields = sizeof(entityStateFields)/sizeof(entityStateFields[0]);
- lc = MSG_ReadByte(msg);
-
- // shownet 2/3 will interleave with other printed info, -1 will
- // just print the delta records`
- if ( cl_shownet->integer >= 2 || cl_shownet->integer == -1 ) {
- print = 1;
- Com_Printf( "%3i: #%-3i ", msg->readcount, to->number );
- } else {
- print = 0;
- }
-
- to->number = number;
-
- for ( i = 0, field = entityStateFields ; i < lc ; i++, field++ ) {
- fromF = (int *)( (byte *)from + field->offset );
- toF = (int *)( (byte *)to + field->offset );
-
- if ( ! MSG_ReadBits( msg, 1 ) ) {
- // no change
- *toF = *fromF;
- } else {
- if ( field->bits == 0 ) {
- // float
- if ( MSG_ReadBits( msg, 1 ) == 0 ) {
- *(float *)toF = 0.0f;
- } else {
- if ( MSG_ReadBits( msg, 1 ) == 0 ) {
- // integral float
- trunc = MSG_ReadBits( msg, FLOAT_INT_BITS );
- // bias to allow equal parts positive and negative
- trunc -= FLOAT_INT_BIAS;
- *(float *)toF = trunc;
- if ( print ) {
- Com_Printf( "%s:%i ", field->name, trunc );
- }
- } else {
- // full floating point value
- *toF = MSG_ReadBits( msg, 32 );
- if ( print ) {
- Com_Printf( "%s:%f ", field->name, *(float *)toF );
- }
- }
- }
- } else {
- if ( MSG_ReadBits( msg, 1 ) == 0 ) {
- *toF = 0;
- } else {
- // integer
- *toF = MSG_ReadBits( msg, field->bits );
- if ( print ) {
- Com_Printf( "%s:%i ", field->name, *toF );
- }
- }
- }
-// pcount[i]++;
- }
- }
- for ( i = lc, field = &entityStateFields[lc] ; i < numFields ; i++, field++ ) {
- fromF = (int *)( (byte *)from + field->offset );
- toF = (int *)( (byte *)to + field->offset );
- // no change
- *toF = *fromF;
- }
-
- if ( print ) {
- if ( msg->bit == 0 ) {
- endBit = msg->readcount * 8 - GENTITYNUM_BITS;
- } else {
- endBit = ( msg->readcount - 1 ) * 8 + msg->bit - GENTITYNUM_BITS;
- }
- Com_Printf( " (%i bits)\n", endBit - startBit );
- }
-}
-
-
-/*
-============================================================================
-
-plyer_state_t communication
-
-============================================================================
-*/
-
-// using the stringizing operator to save typing...
-#define PSF(x) #x,(int)&((playerState_t*)0)->x
-
-netField_t playerStateFields[] =
-{
-{ PSF(commandTime), 32 },
-{ PSF(origin[0]), 0 },
-{ PSF(origin[1]), 0 },
-{ PSF(bobCycle), 8 },
-{ PSF(velocity[0]), 0 },
-{ PSF(velocity[1]), 0 },
-{ PSF(viewangles[1]), 0 },
-{ PSF(viewangles[0]), 0 },
-{ PSF(weaponTime), -16 },
-{ PSF(origin[2]), 0 },
-{ PSF(velocity[2]), 0 },
-{ PSF(legsTimer), 8 },
-{ PSF(pm_time), -16 },
-{ PSF(eventSequence), 16 },
-{ PSF(torsoAnim), 8 },
-{ PSF(movementDir), 4 },
-{ PSF(events[0]), 8 },
-{ PSF(legsAnim), 8 },
-{ PSF(events[1]), 8 },
-{ PSF(pm_flags), 16 },
-{ PSF(groundEntityNum), GENTITYNUM_BITS },
-{ PSF(weaponstate), 4 },
-{ PSF(eFlags), 16 },
-{ PSF(externalEvent), 10 },
-{ PSF(gravity), 16 },
-{ PSF(speed), 16 },
-{ PSF(delta_angles[1]), 16 },
-{ PSF(externalEventParm), 8 },
-{ PSF(viewheight), -8 },
-{ PSF(damageEvent), 8 },
-{ PSF(damageYaw), 8 },
-{ PSF(damagePitch), 8 },
-{ PSF(damageCount), 8 },
-{ PSF(generic1), 8 },
-{ PSF(pm_type), 8 },
-{ PSF(delta_angles[0]), 16 },
-{ PSF(delta_angles[2]), 16 },
-{ PSF(torsoTimer), 12 },
-{ PSF(eventParms[0]), 8 },
-{ PSF(eventParms[1]), 8 },
-{ PSF(clientNum), 8 },
-{ PSF(weapon), 5 },
-{ PSF(viewangles[2]), 0 },
-{ PSF(grapplePoint[0]), 0 },
-{ PSF(grapplePoint[1]), 0 },
-{ PSF(grapplePoint[2]), 0 },
-{ PSF(jumppad_ent), 10 },
-{ PSF(loopSound), 16 }
-};
-
-/*
-=============
-MSG_WriteDeltaPlayerstate
-
-=============
-*/
-void MSG_WriteDeltaPlayerstate( msg_t *msg, struct playerState_s *from, struct playerState_s *to ) {
- int i;
- playerState_t dummy;
- int statsbits;
- int persistantbits;
- int ammobits;
- int powerupbits;
- int numFields;
- int c;
- netField_t *field;
- int *fromF, *toF;
- float fullFloat;
- int trunc, lc;
-
- if (!from) {
- from = &dummy;
- Com_Memset (&dummy, 0, sizeof(dummy));
- }
-
- c = msg->cursize;
-
- numFields = sizeof( playerStateFields ) / sizeof( playerStateFields[0] );
-
- lc = 0;
- for ( i = 0, field = playerStateFields ; i < numFields ; i++, field++ ) {
- fromF = (int *)( (byte *)from + field->offset );
- toF = (int *)( (byte *)to + field->offset );
- if ( *fromF != *toF ) {
- lc = i+1;
- }
- }
-
- MSG_WriteByte( msg, lc ); // # of changes
-
- oldsize += numFields - lc;
-
- for ( i = 0, field = playerStateFields ; i < lc ; i++, field++ ) {
- fromF = (int *)( (byte *)from + field->offset );
- toF = (int *)( (byte *)to + field->offset );
-
- if ( *fromF == *toF ) {
- MSG_WriteBits( msg, 0, 1 ); // no change
- continue;
- }
-
- MSG_WriteBits( msg, 1, 1 ); // changed
-// pcount[i]++;
-
- if ( field->bits == 0 ) {
- // float
- fullFloat = *(float *)toF;
- trunc = (int)fullFloat;
-
- if ( trunc == fullFloat && trunc + FLOAT_INT_BIAS >= 0 &&
- trunc + FLOAT_INT_BIAS < ( 1 << FLOAT_INT_BITS ) ) {
- // send as small integer
- MSG_WriteBits( msg, 0, 1 );
- MSG_WriteBits( msg, trunc + FLOAT_INT_BIAS, FLOAT_INT_BITS );
- } else {
- // send as full floating point value
- MSG_WriteBits( msg, 1, 1 );
- MSG_WriteBits( msg, *toF, 32 );
- }
- } else {
- // integer
- MSG_WriteBits( msg, *toF, field->bits );
- }
- }
- c = msg->cursize - c;
-
-
- //
- // send the arrays
- //
- statsbits = 0;
- for (i=0 ; i<16 ; i++) {
- if (to->stats[i] != from->stats[i]) {
- statsbits |= 1<<i;
- }
- }
- persistantbits = 0;
- for (i=0 ; i<16 ; i++) {
- if (to->persistant[i] != from->persistant[i]) {
- persistantbits |= 1<<i;
- }
- }
- ammobits = 0;
- for (i=0 ; i<16 ; i++) {
- if (to->ammo[i] != from->ammo[i]) {
- ammobits |= 1<<i;
- }
- }
- powerupbits = 0;
- for (i=0 ; i<16 ; i++) {
- if (to->powerups[i] != from->powerups[i]) {
- powerupbits |= 1<<i;
- }
- }
-
- if (!statsbits && !persistantbits && !ammobits && !powerupbits) {
- MSG_WriteBits( msg, 0, 1 ); // no change
- oldsize += 4;
- return;
- }
- MSG_WriteBits( msg, 1, 1 ); // changed
-
- if ( statsbits ) {
- MSG_WriteBits( msg, 1, 1 ); // changed
- MSG_WriteShort( msg, statsbits );
- for (i=0 ; i<16 ; i++)
- if (statsbits & (1<<i) )
- MSG_WriteShort (msg, to->stats[i]);
- } else {
- MSG_WriteBits( msg, 0, 1 ); // no change
- }
-
-
- if ( persistantbits ) {
- MSG_WriteBits( msg, 1, 1 ); // changed
- MSG_WriteShort( msg, persistantbits );
- for (i=0 ; i<16 ; i++)
- if (persistantbits & (1<<i) )
- MSG_WriteShort (msg, to->persistant[i]);
- } else {
- MSG_WriteBits( msg, 0, 1 ); // no change
- }
-
-
- if ( ammobits ) {
- MSG_WriteBits( msg, 1, 1 ); // changed
- MSG_WriteShort( msg, ammobits );
- for (i=0 ; i<16 ; i++)
- if (ammobits & (1<<i) )
- MSG_WriteShort (msg, to->ammo[i]);
- } else {
- MSG_WriteBits( msg, 0, 1 ); // no change
- }
-
-
- if ( powerupbits ) {
- MSG_WriteBits( msg, 1, 1 ); // changed
- MSG_WriteShort( msg, powerupbits );
- for (i=0 ; i<16 ; i++)
- if (powerupbits & (1<<i) )
- MSG_WriteLong( msg, to->powerups[i] );
- } else {
- MSG_WriteBits( msg, 0, 1 ); // no change
- }
-}
-
-
-/*
-===================
-MSG_ReadDeltaPlayerstate
-===================
-*/
-void MSG_ReadDeltaPlayerstate (msg_t *msg, playerState_t *from, playerState_t *to ) {
- int i, lc;
- int bits;
- netField_t *field;
- int numFields;
- int startBit, endBit;
- int print;
- int *fromF, *toF;
- int trunc;
- playerState_t dummy;
-
- if ( !from ) {
- from = &dummy;
- Com_Memset( &dummy, 0, sizeof( dummy ) );
- }
- *to = *from;
-
- if ( msg->bit == 0 ) {
- startBit = msg->readcount * 8 - GENTITYNUM_BITS;
- } else {
- startBit = ( msg->readcount - 1 ) * 8 + msg->bit - GENTITYNUM_BITS;
- }
-
- // shownet 2/3 will interleave with other printed info, -2 will
- // just print the delta records
- if ( cl_shownet->integer >= 2 || cl_shownet->integer == -2 ) {
- print = 1;
- Com_Printf( "%3i: playerstate ", msg->readcount );
- } else {
- print = 0;
- }
-
- numFields = sizeof( playerStateFields ) / sizeof( playerStateFields[0] );
- lc = MSG_ReadByte(msg);
-
- for ( i = 0, field = playerStateFields ; i < lc ; i++, field++ ) {
- fromF = (int *)( (byte *)from + field->offset );
- toF = (int *)( (byte *)to + field->offset );
-
- if ( ! MSG_ReadBits( msg, 1 ) ) {
- // no change
- *toF = *fromF;
- } else {
- if ( field->bits == 0 ) {
- // float
- if ( MSG_ReadBits( msg, 1 ) == 0 ) {
- // integral float
- trunc = MSG_ReadBits( msg, FLOAT_INT_BITS );
- // bias to allow equal parts positive and negative
- trunc -= FLOAT_INT_BIAS;
- *(float *)toF = trunc;
- if ( print ) {
- Com_Printf( "%s:%i ", field->name, trunc );
- }
- } else {
- // full floating point value
- *toF = MSG_ReadBits( msg, 32 );
- if ( print ) {
- Com_Printf( "%s:%f ", field->name, *(float *)toF );
- }
- }
- } else {
- // integer
- *toF = MSG_ReadBits( msg, field->bits );
- if ( print ) {
- Com_Printf( "%s:%i ", field->name, *toF );
- }
- }
- }
- }
- for ( i=lc,field = &playerStateFields[lc];i<numFields; i++, field++) {
- fromF = (int *)( (byte *)from + field->offset );
- toF = (int *)( (byte *)to + field->offset );
- // no change
- *toF = *fromF;
- }
-
-
- // read the arrays
- if (MSG_ReadBits( msg, 1 ) ) {
- // parse stats
- if ( MSG_ReadBits( msg, 1 ) ) {
- LOG("PS_STATS");
- bits = MSG_ReadShort (msg);
- for (i=0 ; i<16 ; i++) {
- if (bits & (1<<i) ) {
- to->stats[i] = MSG_ReadShort(msg);
- }
- }
- }
-
- // parse persistant stats
- if ( MSG_ReadBits( msg, 1 ) ) {
- LOG("PS_PERSISTANT");
- bits = MSG_ReadShort (msg);
- for (i=0 ; i<16 ; i++) {
- if (bits & (1<<i) ) {
- to->persistant[i] = MSG_ReadShort(msg);
- }
- }
- }
-
- // parse ammo
- if ( MSG_ReadBits( msg, 1 ) ) {
- LOG("PS_AMMO");
- bits = MSG_ReadShort (msg);
- for (i=0 ; i<16 ; i++) {
- if (bits & (1<<i) ) {
- to->ammo[i] = MSG_ReadShort(msg);
- }
- }
- }
-
- // parse powerups
- if ( MSG_ReadBits( msg, 1 ) ) {
- LOG("PS_POWERUPS");
- bits = MSG_ReadShort (msg);
- for (i=0 ; i<16 ; i++) {
- if (bits & (1<<i) ) {
- to->powerups[i] = MSG_ReadLong(msg);
- }
- }
- }
- }
-
- if ( print ) {
- if ( msg->bit == 0 ) {
- endBit = msg->readcount * 8 - GENTITYNUM_BITS;
- } else {
- endBit = ( msg->readcount - 1 ) * 8 + msg->bit - GENTITYNUM_BITS;
- }
- Com_Printf( " (%i bits)\n", endBit - startBit );
- }
-}
-
-int msg_hData[256] = {
-250315, // 0
-41193, // 1
-6292, // 2
-7106, // 3
-3730, // 4
-3750, // 5
-6110, // 6
-23283, // 7
-33317, // 8
-6950, // 9
-7838, // 10
-9714, // 11
-9257, // 12
-17259, // 13
-3949, // 14
-1778, // 15
-8288, // 16
-1604, // 17
-1590, // 18
-1663, // 19
-1100, // 20
-1213, // 21
-1238, // 22
-1134, // 23
-1749, // 24
-1059, // 25
-1246, // 26
-1149, // 27
-1273, // 28
-4486, // 29
-2805, // 30
-3472, // 31
-21819, // 32
-1159, // 33
-1670, // 34
-1066, // 35
-1043, // 36
-1012, // 37
-1053, // 38
-1070, // 39
-1726, // 40
-888, // 41
-1180, // 42
-850, // 43
-960, // 44
-780, // 45
-1752, // 46
-3296, // 47
-10630, // 48
-4514, // 49
-5881, // 50
-2685, // 51
-4650, // 52
-3837, // 53
-2093, // 54
-1867, // 55
-2584, // 56
-1949, // 57
-1972, // 58
-940, // 59
-1134, // 60
-1788, // 61
-1670, // 62
-1206, // 63
-5719, // 64
-6128, // 65
-7222, // 66
-6654, // 67
-3710, // 68
-3795, // 69
-1492, // 70
-1524, // 71
-2215, // 72
-1140, // 73
-1355, // 74
-971, // 75
-2180, // 76
-1248, // 77
-1328, // 78
-1195, // 79
-1770, // 80
-1078, // 81
-1264, // 82
-1266, // 83
-1168, // 84
-965, // 85
-1155, // 86
-1186, // 87
-1347, // 88
-1228, // 89
-1529, // 90
-1600, // 91
-2617, // 92
-2048, // 93
-2546, // 94
-3275, // 95
-2410, // 96
-3585, // 97
-2504, // 98
-2800, // 99
-2675, // 100
-6146, // 101
-3663, // 102
-2840, // 103
-14253, // 104
-3164, // 105
-2221, // 106
-1687, // 107
-3208, // 108
-2739, // 109
-3512, // 110
-4796, // 111
-4091, // 112
-3515, // 113
-5288, // 114
-4016, // 115
-7937, // 116
-6031, // 117
-5360, // 118
-3924, // 119
-4892, // 120
-3743, // 121
-4566, // 122
-4807, // 123
-5852, // 124
-6400, // 125
-6225, // 126
-8291, // 127
-23243, // 128
-7838, // 129
-7073, // 130
-8935, // 131
-5437, // 132
-4483, // 133
-3641, // 134
-5256, // 135
-5312, // 136
-5328, // 137
-5370, // 138
-3492, // 139
-2458, // 140
-1694, // 141
-1821, // 142
-2121, // 143
-1916, // 144
-1149, // 145
-1516, // 146
-1367, // 147
-1236, // 148
-1029, // 149
-1258, // 150
-1104, // 151
-1245, // 152
-1006, // 153
-1149, // 154
-1025, // 155
-1241, // 156
-952, // 157
-1287, // 158
-997, // 159
-1713, // 160
-1009, // 161
-1187, // 162
-879, // 163
-1099, // 164
-929, // 165
-1078, // 166
-951, // 167
-1656, // 168
-930, // 169
-1153, // 170
-1030, // 171
-1262, // 172
-1062, // 173
-1214, // 174
-1060, // 175
-1621, // 176
-930, // 177
-1106, // 178
-912, // 179
-1034, // 180
-892, // 181
-1158, // 182
-990, // 183
-1175, // 184
-850, // 185
-1121, // 186
-903, // 187
-1087, // 188
-920, // 189
-1144, // 190
-1056, // 191
-3462, // 192
-2240, // 193
-4397, // 194
-12136, // 195
-7758, // 196
-1345, // 197
-1307, // 198
-3278, // 199
-1950, // 200
-886, // 201
-1023, // 202
-1112, // 203
-1077, // 204
-1042, // 205
-1061, // 206
-1071, // 207
-1484, // 208
-1001, // 209
-1096, // 210
-915, // 211
-1052, // 212
-995, // 213
-1070, // 214
-876, // 215
-1111, // 216
-851, // 217
-1059, // 218
-805, // 219
-1112, // 220
-923, // 221
-1103, // 222
-817, // 223
-1899, // 224
-1872, // 225
-976, // 226
-841, // 227
-1127, // 228
-956, // 229
-1159, // 230
-950, // 231
-7791, // 232
-954, // 233
-1289, // 234
-933, // 235
-1127, // 236
-3207, // 237
-1020, // 238
-927, // 239
-1355, // 240
-768, // 241
-1040, // 242
-745, // 243
-952, // 244
-805, // 245
-1073, // 246
-740, // 247
-1013, // 248
-805, // 249
-1008, // 250
-796, // 251
-996, // 252
-1057, // 253
-11457, // 254
-13504, // 255
-};
-
-void MSG_initHuffman() {
- int i,j;
-
- msgInit = qtrue;
- Huff_Init(&msgHuff);
- for(i=0;i<256;i++) {
- for (j=0;j<msg_hData[i];j++) {
- Huff_addRef(&msgHuff.compressor, (byte)i); // Do update
- Huff_addRef(&msgHuff.decompressor, (byte)i); // Do update
- }
- }
-}
-
-/*
-void MSG_NUinitHuffman() {
- byte *data;
- int size, i, ch;
- int array[256];
-
- msgInit = qtrue;
-
- Huff_Init(&msgHuff);
- // load it in
- size = FS_ReadFile( "netchan/netchan.bin", (void **)&data );
-
- for(i=0;i<256;i++) {
- array[i] = 0;
- }
- for(i=0;i<size;i++) {
- ch = data[i];
- Huff_addRef(&msgHuff.compressor, ch); // Do update
- Huff_addRef(&msgHuff.decompressor, ch); // Do update
- array[ch]++;
- }
- Com_Printf("msg_hData {\n");
- for(i=0;i<256;i++) {
- if (array[i] == 0) {
- Huff_addRef(&msgHuff.compressor, i); // Do update
- Huff_addRef(&msgHuff.decompressor, i); // Do update
- }
- Com_Printf("%d, // %d\n", array[i], i);
- }
- Com_Printf("};\n");
- FS_FreeFile( data );
- Cbuf_AddText( "condump dump.txt\n" );
-}
-*/
-
-//===========================================================================
+/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +#include "../game/q_shared.h" +#include "qcommon.h" + +static huffman_t msgHuff; + +static qboolean msgInit = qfalse; + +int pcount[256]; + +/* +============================================================================== + + MESSAGE IO FUNCTIONS + +Handles byte ordering and avoids alignment errors +============================================================================== +*/ + +int oldsize = 0; + +void MSG_initHuffman(); + +void MSG_Init( msg_t *buf, byte *data, int length ) { + if (!msgInit) { + MSG_initHuffman(); + } + Com_Memset (buf, 0, sizeof(*buf)); + buf->data = data; + buf->maxsize = length; +} + +void MSG_InitOOB( msg_t *buf, byte *data, int length ) { + if (!msgInit) { + MSG_initHuffman(); + } + Com_Memset (buf, 0, sizeof(*buf)); + buf->data = data; + buf->maxsize = length; + buf->oob = qtrue; +} + +void MSG_Clear( msg_t *buf ) { + buf->cursize = 0; + buf->overflowed = qfalse; + buf->bit = 0; //<- in bits +} + + +void MSG_Bitstream( msg_t *buf ) { + buf->oob = qfalse; +} + +void MSG_BeginReading( msg_t *msg ) { + msg->readcount = 0; + msg->bit = 0; + msg->oob = qfalse; +} + +void MSG_BeginReadingOOB( msg_t *msg ) { + msg->readcount = 0; + msg->bit = 0; + msg->oob = qtrue; +} + +void MSG_Copy(msg_t *buf, byte *data, int length, msg_t *src) +{ + if (length<src->cursize) { + Com_Error( ERR_DROP, "MSG_Copy: can't copy into a smaller msg_t buffer"); + } + Com_Memcpy(buf, src, sizeof(msg_t)); + buf->data = data; + Com_Memcpy(buf->data, src->data, src->cursize); +} + +/* +============================================================================= + +bit functions + +============================================================================= +*/ + +int overflows; + +// negative bit values include signs +void MSG_WriteBits( msg_t *msg, int value, int bits ) { + int i; +// FILE* fp; + + oldsize += bits; + + // this isn't an exact overflow check, but close enough + if ( msg->maxsize - msg->cursize < 4 ) { + msg->overflowed = qtrue; + return; + } + + if ( bits == 0 || bits < -31 || bits > 32 ) { + Com_Error( ERR_DROP, "MSG_WriteBits: bad bits %i", bits ); + } + + // check for overflows + if ( bits != 32 ) { + if ( bits > 0 ) { + if ( value > ( ( 1 << bits ) - 1 ) || value < 0 ) { + overflows++; + } + } else { + int r; + + r = 1 << (bits-1); + + if ( value > r - 1 || value < -r ) { + overflows++; + } + } + } + if ( bits < 0 ) { + bits = -bits; + } + if (msg->oob) { + if (bits==8) { + msg->data[msg->cursize] = value; + msg->cursize += 1; + msg->bit += 8; + } else if (bits==16) { + unsigned short *sp = (unsigned short *)&msg->data[msg->cursize]; + *sp = LittleShort(value); + msg->cursize += 2; + msg->bit += 16; + } else if (bits==32) { + unsigned int *ip = (unsigned int *)&msg->data[msg->cursize]; + *ip = LittleLong(value); + msg->cursize += 4; + msg->bit += 8; + } else { + Com_Error(ERR_DROP, "can't read %d bits\n", bits); + } + } else { +// fp = fopen("c:\\netchan.bin", "a"); + value &= (0xffffffff>>(32-bits)); + if (bits&7) { + int nbits; + nbits = bits&7; + for(i=0;i<nbits;i++) { + Huff_putBit((value&1), msg->data, &msg->bit); + value = (value>>1); + } + bits = bits - nbits; + } + if (bits) { + for(i=0;i<bits;i+=8) { +// fwrite(bp, 1, 1, fp); + Huff_offsetTransmit (&msgHuff.compressor, (value&0xff), msg->data, &msg->bit); + value = (value>>8); + } + } + msg->cursize = (msg->bit>>3)+1; +// fclose(fp); + } +} + +int MSG_ReadBits( msg_t *msg, int bits ) { + int value; + int get; + qboolean sgn; + int i, nbits; +// FILE* fp; + + value = 0; + + if ( bits < 0 ) { + bits = -bits; + sgn = qtrue; + } else { + sgn = qfalse; + } + + if (msg->oob) { + if (bits==8) { + value = msg->data[msg->readcount]; + msg->readcount += 1; + msg->bit += 8; + } else if (bits==16) { + unsigned short *sp = (unsigned short *)&msg->data[msg->readcount]; + value = LittleShort(*sp); + msg->readcount += 2; + msg->bit += 16; + } else if (bits==32) { + unsigned int *ip = (unsigned int *)&msg->data[msg->readcount]; + value = LittleLong(*ip); + msg->readcount += 4; + msg->bit += 32; + } else { + Com_Error(ERR_DROP, "can't read %d bits\n", bits); + } + } else { + nbits = 0; + if (bits&7) { + nbits = bits&7; + for(i=0;i<nbits;i++) { + value |= (Huff_getBit(msg->data, &msg->bit)<<i); + } + bits = bits - nbits; + } + if (bits) { +// fp = fopen("c:\\netchan.bin", "a"); + for(i=0;i<bits;i+=8) { + Huff_offsetReceive (msgHuff.decompressor.tree, &get, msg->data, &msg->bit); +// fwrite(&get, 1, 1, fp); + value |= (get<<(i+nbits)); + } +// fclose(fp); + } + msg->readcount = (msg->bit>>3)+1; + } + if ( sgn ) { + if ( value & ( 1 << ( bits - 1 ) ) ) { + value |= -1 ^ ( ( 1 << bits ) - 1 ); + } + } + + return value; +} + + + +//================================================================================ + +// +// writing functions +// + +void MSG_WriteChar( msg_t *sb, int c ) { +#ifdef PARANOID + if (c < -128 || c > 127) + Com_Error (ERR_FATAL, "MSG_WriteChar: range error"); +#endif + + MSG_WriteBits( sb, c, 8 ); +} + +void MSG_WriteByte( msg_t *sb, int c ) { +#ifdef PARANOID + if (c < 0 || c > 255) + Com_Error (ERR_FATAL, "MSG_WriteByte: range error"); +#endif + + MSG_WriteBits( sb, c, 8 ); +} + +void MSG_WriteData( msg_t *buf, const void *data, int length ) { + int i; + for(i=0;i<length;i++) { + MSG_WriteByte(buf, ((byte *)data)[i]); + } +} + +void MSG_WriteShort( msg_t *sb, int c ) { +#ifdef PARANOID + if (c < ((short)0x8000) || c > (short)0x7fff) + Com_Error (ERR_FATAL, "MSG_WriteShort: range error"); +#endif + + MSG_WriteBits( sb, c, 16 ); +} + +void MSG_WriteLong( msg_t *sb, int c ) { + MSG_WriteBits( sb, c, 32 ); +} + +void MSG_WriteFloat( msg_t *sb, float f ) { + union { + float f; + int l; + } dat; + + dat.f = f; + MSG_WriteBits( sb, dat.l, 32 ); +} + +void MSG_WriteString( msg_t *sb, const char *s ) { + if ( !s ) { + MSG_WriteData (sb, "", 1); + } else { + int l,i; + char string[MAX_STRING_CHARS]; + + l = strlen( s ); + if ( l >= MAX_STRING_CHARS ) { + Com_Printf( "MSG_WriteString: MAX_STRING_CHARS" ); + MSG_WriteData (sb, "", 1); + return; + } + Q_strncpyz( string, s, sizeof( string ) ); + + // get rid of 0xff chars, because old clients don't like them + for ( i = 0 ; i < l ; i++ ) { + if ( ((byte *)string)[i] > 127 ) { + string[i] = '.'; + } + } + + MSG_WriteData (sb, string, l+1); + } +} + +void MSG_WriteBigString( msg_t *sb, const char *s ) { + if ( !s ) { + MSG_WriteData (sb, "", 1); + } else { + int l,i; + char string[BIG_INFO_STRING]; + + l = strlen( s ); + if ( l >= BIG_INFO_STRING ) { + Com_Printf( "MSG_WriteString: BIG_INFO_STRING" ); + MSG_WriteData (sb, "", 1); + return; + } + Q_strncpyz( string, s, sizeof( string ) ); + + // get rid of 0xff chars, because old clients don't like them + for ( i = 0 ; i < l ; i++ ) { + if ( ((byte *)string)[i] > 127 ) { + string[i] = '.'; + } + } + + MSG_WriteData (sb, string, l+1); + } +} + +void MSG_WriteAngle( msg_t *sb, float f ) { + MSG_WriteByte (sb, (int)(f*256/360) & 255); +} + +void MSG_WriteAngle16( msg_t *sb, float f ) { + MSG_WriteShort (sb, ANGLE2SHORT(f)); +} + + +//============================================================ + +// +// reading functions +// + +// returns -1 if no more characters are available +int MSG_ReadChar (msg_t *msg ) { + int c; + + c = (signed char)MSG_ReadBits( msg, 8 ); + if ( msg->readcount > msg->cursize ) { + c = -1; + } + + return c; +} + +int MSG_ReadByte( msg_t *msg ) { + int c; + + c = (unsigned char)MSG_ReadBits( msg, 8 ); + if ( msg->readcount > msg->cursize ) { + c = -1; + } + return c; +} + +int MSG_ReadShort( msg_t *msg ) { + int c; + + c = (short)MSG_ReadBits( msg, 16 ); + if ( msg->readcount > msg->cursize ) { + c = -1; + } + + return c; +} + +int MSG_ReadLong( msg_t *msg ) { + int c; + + c = MSG_ReadBits( msg, 32 ); + if ( msg->readcount > msg->cursize ) { + c = -1; + } + + return c; +} + +float MSG_ReadFloat( msg_t *msg ) { + union { + byte b[4]; + float f; + int l; + } dat; + + dat.l = MSG_ReadBits( msg, 32 ); + if ( msg->readcount > msg->cursize ) { + dat.f = -1; + } + + return dat.f; +} + +char *MSG_ReadString( msg_t *msg ) { + static char string[MAX_STRING_CHARS]; + int l,c; + + l = 0; + do { + c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds + if ( c == -1 || c == 0 ) { + break; + } + // translate all fmt spec to avoid crash bugs + if ( c == '%' ) { + c = '.'; + } + // don't allow higher ascii values + if ( c > 127 ) { + c = '.'; + } + + string[l] = c; + l++; + } while (l < sizeof(string)-1); + + string[l] = 0; + + return string; +} + +char *MSG_ReadBigString( msg_t *msg ) { + static char string[BIG_INFO_STRING]; + int l,c; + + l = 0; + do { + c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds + if ( c == -1 || c == 0 ) { + break; + } + // translate all fmt spec to avoid crash bugs + if ( c == '%' ) { + c = '.'; + } + + string[l] = c; + l++; + } while (l < sizeof(string)-1); + + string[l] = 0; + + return string; +} + +char *MSG_ReadStringLine( msg_t *msg ) { + static char string[MAX_STRING_CHARS]; + int l,c; + + l = 0; + do { + c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds + if (c == -1 || c == 0 || c == '\n') { + break; + } + // translate all fmt spec to avoid crash bugs + if ( c == '%' ) { + c = '.'; + } + string[l] = c; + l++; + } while (l < sizeof(string)-1); + + string[l] = 0; + + return string; +} + +float MSG_ReadAngle16( msg_t *msg ) { + return SHORT2ANGLE(MSG_ReadShort(msg)); +} + +void MSG_ReadData( msg_t *msg, void *data, int len ) { + int i; + + for (i=0 ; i<len ; i++) { + ((byte *)data)[i] = MSG_ReadByte (msg); + } +} + + +/* +============================================================================= + +delta functions + +============================================================================= +*/ + +extern cvar_t *cl_shownet; + +#define LOG(x) if( cl_shownet->integer == 4 ) { Com_Printf("%s ", x ); }; + +void MSG_WriteDelta( msg_t *msg, int oldV, int newV, int bits ) { + if ( oldV == newV ) { + MSG_WriteBits( msg, 0, 1 ); + return; + } + MSG_WriteBits( msg, 1, 1 ); + MSG_WriteBits( msg, newV, bits ); +} + +int MSG_ReadDelta( msg_t *msg, int oldV, int bits ) { + if ( MSG_ReadBits( msg, 1 ) ) { + return MSG_ReadBits( msg, bits ); + } + return oldV; +} + +void MSG_WriteDeltaFloat( msg_t *msg, float oldV, float newV ) { + if ( oldV == newV ) { + MSG_WriteBits( msg, 0, 1 ); + return; + } + MSG_WriteBits( msg, 1, 1 ); + MSG_WriteBits( msg, *(int *)&newV, 32 ); +} + +float MSG_ReadDeltaFloat( msg_t *msg, float oldV ) { + if ( MSG_ReadBits( msg, 1 ) ) { + float newV; + + *(int *)&newV = MSG_ReadBits( msg, 32 ); + return newV; + } + return oldV; +} + +/* +============================================================================= + +delta functions with keys + +============================================================================= +*/ + +int kbitmask[32] = { + 0x00000001, 0x00000003, 0x00000007, 0x0000000F, + 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, + 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, + 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, + 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, + 0x001FFFFf, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF, + 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, + 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF, +}; + +void MSG_WriteDeltaKey( msg_t *msg, int key, int oldV, int newV, int bits ) { + if ( oldV == newV ) { + MSG_WriteBits( msg, 0, 1 ); + return; + } + MSG_WriteBits( msg, 1, 1 ); + MSG_WriteBits( msg, newV ^ key, bits ); +} + +int MSG_ReadDeltaKey( msg_t *msg, int key, int oldV, int bits ) { + if ( MSG_ReadBits( msg, 1 ) ) { + return MSG_ReadBits( msg, bits ) ^ (key & kbitmask[bits]); + } + return oldV; +} + +void MSG_WriteDeltaKeyFloat( msg_t *msg, int key, float oldV, float newV ) { + if ( oldV == newV ) { + MSG_WriteBits( msg, 0, 1 ); + return; + } + MSG_WriteBits( msg, 1, 1 ); + MSG_WriteBits( msg, (*(int *)&newV) ^ key, 32 ); +} + +float MSG_ReadDeltaKeyFloat( msg_t *msg, int key, float oldV ) { + if ( MSG_ReadBits( msg, 1 ) ) { + float newV; + + *(int *)&newV = MSG_ReadBits( msg, 32 ) ^ key; + return newV; + } + return oldV; +} + + +/* +============================================================================ + +usercmd_t communication + +============================================================================ +*/ + +// ms is allways sent, the others are optional +#define CM_ANGLE1 (1<<0) +#define CM_ANGLE2 (1<<1) +#define CM_ANGLE3 (1<<2) +#define CM_FORWARD (1<<3) +#define CM_SIDE (1<<4) +#define CM_UP (1<<5) +#define CM_BUTTONS (1<<6) +#define CM_WEAPON (1<<7) + +/* +===================== +MSG_WriteDeltaUsercmd +===================== +*/ +void MSG_WriteDeltaUsercmd( msg_t *msg, usercmd_t *from, usercmd_t *to ) { + if ( to->serverTime - from->serverTime < 256 ) { + MSG_WriteBits( msg, 1, 1 ); + MSG_WriteBits( msg, to->serverTime - from->serverTime, 8 ); + } else { + MSG_WriteBits( msg, 0, 1 ); + MSG_WriteBits( msg, to->serverTime, 32 ); + } + MSG_WriteDelta( msg, from->angles[0], to->angles[0], 16 ); + MSG_WriteDelta( msg, from->angles[1], to->angles[1], 16 ); + MSG_WriteDelta( msg, from->angles[2], to->angles[2], 16 ); + MSG_WriteDelta( msg, from->forwardmove, to->forwardmove, 8 ); + MSG_WriteDelta( msg, from->rightmove, to->rightmove, 8 ); + MSG_WriteDelta( msg, from->upmove, to->upmove, 8 ); + MSG_WriteDelta( msg, from->buttons, to->buttons, 16 ); + MSG_WriteDelta( msg, from->weapon, to->weapon, 8 ); +} + + +/* +===================== +MSG_ReadDeltaUsercmd +===================== +*/ +void MSG_ReadDeltaUsercmd( msg_t *msg, usercmd_t *from, usercmd_t *to ) { + if ( MSG_ReadBits( msg, 1 ) ) { + to->serverTime = from->serverTime + MSG_ReadBits( msg, 8 ); + } else { + to->serverTime = MSG_ReadBits( msg, 32 ); + } + to->angles[0] = MSG_ReadDelta( msg, from->angles[0], 16); + to->angles[1] = MSG_ReadDelta( msg, from->angles[1], 16); + to->angles[2] = MSG_ReadDelta( msg, from->angles[2], 16); + to->forwardmove = MSG_ReadDelta( msg, from->forwardmove, 8); + to->rightmove = MSG_ReadDelta( msg, from->rightmove, 8); + to->upmove = MSG_ReadDelta( msg, from->upmove, 8); + to->buttons = MSG_ReadDelta( msg, from->buttons, 16); + to->weapon = MSG_ReadDelta( msg, from->weapon, 8); +} + +/* +===================== +MSG_WriteDeltaUsercmd +===================== +*/ +void MSG_WriteDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *to ) { + if ( to->serverTime - from->serverTime < 256 ) { + MSG_WriteBits( msg, 1, 1 ); + MSG_WriteBits( msg, to->serverTime - from->serverTime, 8 ); + } else { + MSG_WriteBits( msg, 0, 1 ); + MSG_WriteBits( msg, to->serverTime, 32 ); + } + if (from->angles[0] == to->angles[0] && + from->angles[1] == to->angles[1] && + from->angles[2] == to->angles[2] && + from->forwardmove == to->forwardmove && + from->rightmove == to->rightmove && + from->upmove == to->upmove && + from->buttons == to->buttons && + from->weapon == to->weapon) { + MSG_WriteBits( msg, 0, 1 ); // no change + oldsize += 7; + return; + } + key ^= to->serverTime; + MSG_WriteBits( msg, 1, 1 ); + MSG_WriteDeltaKey( msg, key, from->angles[0], to->angles[0], 16 ); + MSG_WriteDeltaKey( msg, key, from->angles[1], to->angles[1], 16 ); + MSG_WriteDeltaKey( msg, key, from->angles[2], to->angles[2], 16 ); + MSG_WriteDeltaKey( msg, key, from->forwardmove, to->forwardmove, 8 ); + MSG_WriteDeltaKey( msg, key, from->rightmove, to->rightmove, 8 ); + MSG_WriteDeltaKey( msg, key, from->upmove, to->upmove, 8 ); + MSG_WriteDeltaKey( msg, key, from->buttons, to->buttons, 16 ); + MSG_WriteDeltaKey( msg, key, from->weapon, to->weapon, 8 ); +} + + +/* +===================== +MSG_ReadDeltaUsercmd +===================== +*/ +void MSG_ReadDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *to ) { + if ( MSG_ReadBits( msg, 1 ) ) { + to->serverTime = from->serverTime + MSG_ReadBits( msg, 8 ); + } else { + to->serverTime = MSG_ReadBits( msg, 32 ); + } + if ( MSG_ReadBits( msg, 1 ) ) { + key ^= to->serverTime; + to->angles[0] = MSG_ReadDeltaKey( msg, key, from->angles[0], 16); + to->angles[1] = MSG_ReadDeltaKey( msg, key, from->angles[1], 16); + to->angles[2] = MSG_ReadDeltaKey( msg, key, from->angles[2], 16); + to->forwardmove = MSG_ReadDeltaKey( msg, key, from->forwardmove, 8); + to->rightmove = MSG_ReadDeltaKey( msg, key, from->rightmove, 8); + to->upmove = MSG_ReadDeltaKey( msg, key, from->upmove, 8); + to->buttons = MSG_ReadDeltaKey( msg, key, from->buttons, 16); + to->weapon = MSG_ReadDeltaKey( msg, key, from->weapon, 8); + } else { + to->angles[0] = from->angles[0]; + to->angles[1] = from->angles[1]; + to->angles[2] = from->angles[2]; + to->forwardmove = from->forwardmove; + to->rightmove = from->rightmove; + to->upmove = from->upmove; + to->buttons = from->buttons; + to->weapon = from->weapon; + } +} + +/* +============================================================================= + +entityState_t communication + +============================================================================= +*/ + +/* +================= +MSG_ReportChangeVectors_f + +Prints out a table from the current statistics for copying to code +================= +*/ +void MSG_ReportChangeVectors_f( void ) { + int i; + for(i=0;i<256;i++) { + if (pcount[i]) { + Com_Printf("%d used %d\n", i, pcount[i]); + } + } +} + +typedef struct { + char *name; + int offset; + int bits; // 0 = float +} netField_t; + +// using the stringizing operator to save typing... +#define NETF(x) #x,(int)&((entityState_t*)0)->x + +netField_t entityStateFields[] = +{ +{ NETF(pos.trTime), 32 }, +{ NETF(pos.trBase[0]), 0 }, +{ NETF(pos.trBase[1]), 0 }, +{ NETF(pos.trDelta[0]), 0 }, +{ NETF(pos.trDelta[1]), 0 }, +{ NETF(pos.trBase[2]), 0 }, +{ NETF(apos.trBase[1]), 0 }, +{ NETF(pos.trDelta[2]), 0 }, +{ NETF(apos.trBase[0]), 0 }, +{ NETF(event), 10 }, +{ NETF(angles2[1]), 0 }, +{ NETF(eType), 8 }, +{ NETF(torsoAnim), 8 }, +{ NETF(eventParm), 8 }, +{ NETF(legsAnim), 8 }, +{ NETF(groundEntityNum), GENTITYNUM_BITS }, +{ NETF(pos.trType), 8 }, +{ NETF(eFlags), 19 }, +{ NETF(otherEntityNum), GENTITYNUM_BITS }, +{ NETF(weapon), 8 }, +{ NETF(clientNum), 8 }, +{ NETF(angles[1]), 0 }, +{ NETF(pos.trDuration), 32 }, +{ NETF(apos.trType), 8 }, +{ NETF(origin[0]), 0 }, +{ NETF(origin[1]), 0 }, +{ NETF(origin[2]), 0 }, +{ NETF(solid), 24 }, +{ NETF(powerups), 16 }, +{ NETF(modelindex), 8 }, +{ NETF(otherEntityNum2), GENTITYNUM_BITS }, +{ NETF(loopSound), 8 }, +{ NETF(generic1), 8 }, +{ NETF(origin2[2]), 0 }, +{ NETF(origin2[0]), 0 }, +{ NETF(origin2[1]), 0 }, +{ NETF(modelindex2), 8 }, +{ NETF(angles[0]), 0 }, +{ NETF(time), 32 }, +{ NETF(apos.trTime), 32 }, +{ NETF(apos.trDuration), 32 }, +{ NETF(apos.trBase[2]), 0 }, +{ NETF(apos.trDelta[0]), 0 }, +{ NETF(apos.trDelta[1]), 0 }, +{ NETF(apos.trDelta[2]), 0 }, +{ NETF(time2), 32 }, +{ NETF(angles[2]), 0 }, +{ NETF(angles2[0]), 0 }, +{ NETF(angles2[2]), 0 }, +{ NETF(constantLight), 32 }, +{ NETF(frame), 16 } +}; + + +// if (int)f == f and (int)f + ( 1<<(FLOAT_INT_BITS-1) ) < ( 1 << FLOAT_INT_BITS ) +// the float will be sent with FLOAT_INT_BITS, otherwise all 32 bits will be sent +#define FLOAT_INT_BITS 13 +#define FLOAT_INT_BIAS (1<<(FLOAT_INT_BITS-1)) + +/* +================== +MSG_WriteDeltaEntity + +Writes part of a packetentities message, including the entity number. +Can delta from either a baseline or a previous packet_entity +If to is NULL, a remove entity update will be sent +If force is not set, then nothing at all will be generated if the entity is +identical, under the assumption that the in-order delta code will catch it. +================== +*/ +void MSG_WriteDeltaEntity( msg_t *msg, struct entityState_s *from, struct entityState_s *to, + qboolean force ) { + int i, lc; + int numFields; + netField_t *field; + int trunc; + float fullFloat; + int *fromF, *toF; + + numFields = sizeof(entityStateFields)/sizeof(entityStateFields[0]); + + // all fields should be 32 bits to avoid any compiler packing issues + // the "number" field is not part of the field list + // if this assert fails, someone added a field to the entityState_t + // struct without updating the message fields + assert( numFields + 1 == sizeof( *from )/4 ); + + // a NULL to is a delta remove message + if ( to == NULL ) { + if ( from == NULL ) { + return; + } + MSG_WriteBits( msg, from->number, GENTITYNUM_BITS ); + MSG_WriteBits( msg, 1, 1 ); + return; + } + + if ( to->number < 0 || to->number >= MAX_GENTITIES ) { + Com_Error (ERR_FATAL, "MSG_WriteDeltaEntity: Bad entity number: %i", to->number ); + } + + lc = 0; + // build the change vector as bytes so it is endien independent + for ( i = 0, field = entityStateFields ; i < numFields ; i++, field++ ) { + fromF = (int *)( (byte *)from + field->offset ); + toF = (int *)( (byte *)to + field->offset ); + if ( *fromF != *toF ) { + lc = i+1; + } + } + + if ( lc == 0 ) { + // nothing at all changed + if ( !force ) { + return; // nothing at all + } + // write two bits for no change + MSG_WriteBits( msg, to->number, GENTITYNUM_BITS ); + MSG_WriteBits( msg, 0, 1 ); // not removed + MSG_WriteBits( msg, 0, 1 ); // no delta + return; + } + + MSG_WriteBits( msg, to->number, GENTITYNUM_BITS ); + MSG_WriteBits( msg, 0, 1 ); // not removed + MSG_WriteBits( msg, 1, 1 ); // we have a delta + + MSG_WriteByte( msg, lc ); // # of changes + + oldsize += numFields; + + for ( i = 0, field = entityStateFields ; i < lc ; i++, field++ ) { + fromF = (int *)( (byte *)from + field->offset ); + toF = (int *)( (byte *)to + field->offset ); + + if ( *fromF == *toF ) { + MSG_WriteBits( msg, 0, 1 ); // no change + continue; + } + + MSG_WriteBits( msg, 1, 1 ); // changed + + if ( field->bits == 0 ) { + // float + fullFloat = *(float *)toF; + trunc = (int)fullFloat; + + if (fullFloat == 0.0f) { + MSG_WriteBits( msg, 0, 1 ); + oldsize += FLOAT_INT_BITS; + } else { + MSG_WriteBits( msg, 1, 1 ); + if ( trunc == fullFloat && trunc + FLOAT_INT_BIAS >= 0 && + trunc + FLOAT_INT_BIAS < ( 1 << FLOAT_INT_BITS ) ) { + // send as small integer + MSG_WriteBits( msg, 0, 1 ); + MSG_WriteBits( msg, trunc + FLOAT_INT_BIAS, FLOAT_INT_BITS ); + } else { + // send as full floating point value + MSG_WriteBits( msg, 1, 1 ); + MSG_WriteBits( msg, *toF, 32 ); + } + } + } else { + if (*toF == 0) { + MSG_WriteBits( msg, 0, 1 ); + } else { + MSG_WriteBits( msg, 1, 1 ); + // integer + MSG_WriteBits( msg, *toF, field->bits ); + } + } + } +} + +/* +================== +MSG_ReadDeltaEntity + +The entity number has already been read from the message, which +is how the from state is identified. + +If the delta removes the entity, entityState_t->number will be set to MAX_GENTITIES-1 + +Can go from either a baseline or a previous packet_entity +================== +*/ +extern cvar_t *cl_shownet; + +void MSG_ReadDeltaEntity( msg_t *msg, entityState_t *from, entityState_t *to, + int number) { + int i, lc; + int numFields; + netField_t *field; + int *fromF, *toF; + int print; + int trunc; + int startBit, endBit; + + if ( number < 0 || number >= MAX_GENTITIES) { + Com_Error( ERR_DROP, "Bad delta entity number: %i", number ); + } + + if ( msg->bit == 0 ) { + startBit = msg->readcount * 8 - GENTITYNUM_BITS; + } else { + startBit = ( msg->readcount - 1 ) * 8 + msg->bit - GENTITYNUM_BITS; + } + + // check for a remove + if ( MSG_ReadBits( msg, 1 ) == 1 ) { + Com_Memset( to, 0, sizeof( *to ) ); + to->number = MAX_GENTITIES - 1; + if ( cl_shownet->integer >= 2 || cl_shownet->integer == -1 ) { + Com_Printf( "%3i: #%-3i remove\n", msg->readcount, number ); + } + return; + } + + // check for no delta + if ( MSG_ReadBits( msg, 1 ) == 0 ) { + *to = *from; + to->number = number; + return; + } + + numFields = sizeof(entityStateFields)/sizeof(entityStateFields[0]); + lc = MSG_ReadByte(msg); + + // shownet 2/3 will interleave with other printed info, -1 will + // just print the delta records` + if ( cl_shownet->integer >= 2 || cl_shownet->integer == -1 ) { + print = 1; + Com_Printf( "%3i: #%-3i ", msg->readcount, to->number ); + } else { + print = 0; + } + + to->number = number; + + for ( i = 0, field = entityStateFields ; i < lc ; i++, field++ ) { + fromF = (int *)( (byte *)from + field->offset ); + toF = (int *)( (byte *)to + field->offset ); + + if ( ! MSG_ReadBits( msg, 1 ) ) { + // no change + *toF = *fromF; + } else { + if ( field->bits == 0 ) { + // float + if ( MSG_ReadBits( msg, 1 ) == 0 ) { + *(float *)toF = 0.0f; + } else { + if ( MSG_ReadBits( msg, 1 ) == 0 ) { + // integral float + trunc = MSG_ReadBits( msg, FLOAT_INT_BITS ); + // bias to allow equal parts positive and negative + trunc -= FLOAT_INT_BIAS; + *(float *)toF = trunc; + if ( print ) { + Com_Printf( "%s:%i ", field->name, trunc ); + } + } else { + // full floating point value + *toF = MSG_ReadBits( msg, 32 ); + if ( print ) { + Com_Printf( "%s:%f ", field->name, *(float *)toF ); + } + } + } + } else { + if ( MSG_ReadBits( msg, 1 ) == 0 ) { + *toF = 0; + } else { + // integer + *toF = MSG_ReadBits( msg, field->bits ); + if ( print ) { + Com_Printf( "%s:%i ", field->name, *toF ); + } + } + } +// pcount[i]++; + } + } + for ( i = lc, field = &entityStateFields[lc] ; i < numFields ; i++, field++ ) { + fromF = (int *)( (byte *)from + field->offset ); + toF = (int *)( (byte *)to + field->offset ); + // no change + *toF = *fromF; + } + + if ( print ) { + if ( msg->bit == 0 ) { + endBit = msg->readcount * 8 - GENTITYNUM_BITS; + } else { + endBit = ( msg->readcount - 1 ) * 8 + msg->bit - GENTITYNUM_BITS; + } + Com_Printf( " (%i bits)\n", endBit - startBit ); + } +} + + +/* +============================================================================ + +plyer_state_t communication + +============================================================================ +*/ + +// using the stringizing operator to save typing... +#define PSF(x) #x,(int)&((playerState_t*)0)->x + +netField_t playerStateFields[] = +{ +{ PSF(commandTime), 32 }, +{ PSF(origin[0]), 0 }, +{ PSF(origin[1]), 0 }, +{ PSF(bobCycle), 8 }, +{ PSF(velocity[0]), 0 }, +{ PSF(velocity[1]), 0 }, +{ PSF(viewangles[1]), 0 }, +{ PSF(viewangles[0]), 0 }, +{ PSF(weaponTime), -16 }, +{ PSF(origin[2]), 0 }, +{ PSF(velocity[2]), 0 }, +{ PSF(legsTimer), 8 }, +{ PSF(pm_time), -16 }, +{ PSF(eventSequence), 16 }, +{ PSF(torsoAnim), 8 }, +{ PSF(movementDir), 4 }, +{ PSF(events[0]), 8 }, +{ PSF(legsAnim), 8 }, +{ PSF(events[1]), 8 }, +{ PSF(pm_flags), 16 }, +{ PSF(groundEntityNum), GENTITYNUM_BITS }, +{ PSF(weaponstate), 4 }, +{ PSF(eFlags), 16 }, +{ PSF(externalEvent), 10 }, +{ PSF(gravity), 16 }, +{ PSF(speed), 16 }, +{ PSF(delta_angles[1]), 16 }, +{ PSF(externalEventParm), 8 }, +{ PSF(viewheight), -8 }, +{ PSF(damageEvent), 8 }, +{ PSF(damageYaw), 8 }, +{ PSF(damagePitch), 8 }, +{ PSF(damageCount), 8 }, +{ PSF(generic1), 8 }, +{ PSF(pm_type), 8 }, +{ PSF(delta_angles[0]), 16 }, +{ PSF(delta_angles[2]), 16 }, +{ PSF(torsoTimer), 12 }, +{ PSF(eventParms[0]), 8 }, +{ PSF(eventParms[1]), 8 }, +{ PSF(clientNum), 8 }, +{ PSF(weapon), 5 }, +{ PSF(viewangles[2]), 0 }, +{ PSF(grapplePoint[0]), 0 }, +{ PSF(grapplePoint[1]), 0 }, +{ PSF(grapplePoint[2]), 0 }, +{ PSF(jumppad_ent), 10 }, +{ PSF(loopSound), 16 } +}; + +/* +============= +MSG_WriteDeltaPlayerstate + +============= +*/ +void MSG_WriteDeltaPlayerstate( msg_t *msg, struct playerState_s *from, struct playerState_s *to ) { + int i; + playerState_t dummy; + int statsbits; + int persistantbits; + int ammobits; + int powerupbits; + int numFields; + int c; + netField_t *field; + int *fromF, *toF; + float fullFloat; + int trunc, lc; + + if (!from) { + from = &dummy; + Com_Memset (&dummy, 0, sizeof(dummy)); + } + + c = msg->cursize; + + numFields = sizeof( playerStateFields ) / sizeof( playerStateFields[0] ); + + lc = 0; + for ( i = 0, field = playerStateFields ; i < numFields ; i++, field++ ) { + fromF = (int *)( (byte *)from + field->offset ); + toF = (int *)( (byte *)to + field->offset ); + if ( *fromF != *toF ) { + lc = i+1; + } + } + + MSG_WriteByte( msg, lc ); // # of changes + + oldsize += numFields - lc; + + for ( i = 0, field = playerStateFields ; i < lc ; i++, field++ ) { + fromF = (int *)( (byte *)from + field->offset ); + toF = (int *)( (byte *)to + field->offset ); + + if ( *fromF == *toF ) { + MSG_WriteBits( msg, 0, 1 ); // no change + continue; + } + + MSG_WriteBits( msg, 1, 1 ); // changed +// pcount[i]++; + + if ( field->bits == 0 ) { + // float + fullFloat = *(float *)toF; + trunc = (int)fullFloat; + + if ( trunc == fullFloat && trunc + FLOAT_INT_BIAS >= 0 && + trunc + FLOAT_INT_BIAS < ( 1 << FLOAT_INT_BITS ) ) { + // send as small integer + MSG_WriteBits( msg, 0, 1 ); + MSG_WriteBits( msg, trunc + FLOAT_INT_BIAS, FLOAT_INT_BITS ); + } else { + // send as full floating point value + MSG_WriteBits( msg, 1, 1 ); + MSG_WriteBits( msg, *toF, 32 ); + } + } else { + // integer + MSG_WriteBits( msg, *toF, field->bits ); + } + } + c = msg->cursize - c; + + + // + // send the arrays + // + statsbits = 0; + for (i=0 ; i<16 ; i++) { + if (to->stats[i] != from->stats[i]) { + statsbits |= 1<<i; + } + } + persistantbits = 0; + for (i=0 ; i<16 ; i++) { + if (to->persistant[i] != from->persistant[i]) { + persistantbits |= 1<<i; + } + } + ammobits = 0; + for (i=0 ; i<16 ; i++) { + if (to->ammo[i] != from->ammo[i]) { + ammobits |= 1<<i; + } + } + powerupbits = 0; + for (i=0 ; i<16 ; i++) { + if (to->powerups[i] != from->powerups[i]) { + powerupbits |= 1<<i; + } + } + + if (!statsbits && !persistantbits && !ammobits && !powerupbits) { + MSG_WriteBits( msg, 0, 1 ); // no change + oldsize += 4; + return; + } + MSG_WriteBits( msg, 1, 1 ); // changed + + if ( statsbits ) { + MSG_WriteBits( msg, 1, 1 ); // changed + MSG_WriteShort( msg, statsbits ); + for (i=0 ; i<16 ; i++) + if (statsbits & (1<<i) ) + MSG_WriteShort (msg, to->stats[i]); + } else { + MSG_WriteBits( msg, 0, 1 ); // no change + } + + + if ( persistantbits ) { + MSG_WriteBits( msg, 1, 1 ); // changed + MSG_WriteShort( msg, persistantbits ); + for (i=0 ; i<16 ; i++) + if (persistantbits & (1<<i) ) + MSG_WriteShort (msg, to->persistant[i]); + } else { + MSG_WriteBits( msg, 0, 1 ); // no change + } + + + if ( ammobits ) { + MSG_WriteBits( msg, 1, 1 ); // changed + MSG_WriteShort( msg, ammobits ); + for (i=0 ; i<16 ; i++) + if (ammobits & (1<<i) ) + MSG_WriteShort (msg, to->ammo[i]); + } else { + MSG_WriteBits( msg, 0, 1 ); // no change + } + + + if ( powerupbits ) { + MSG_WriteBits( msg, 1, 1 ); // changed + MSG_WriteShort( msg, powerupbits ); + for (i=0 ; i<16 ; i++) + if (powerupbits & (1<<i) ) + MSG_WriteLong( msg, to->powerups[i] ); + } else { + MSG_WriteBits( msg, 0, 1 ); // no change + } +} + + +/* +=================== +MSG_ReadDeltaPlayerstate +=================== +*/ +void MSG_ReadDeltaPlayerstate (msg_t *msg, playerState_t *from, playerState_t *to ) { + int i, lc; + int bits; + netField_t *field; + int numFields; + int startBit, endBit; + int print; + int *fromF, *toF; + int trunc; + playerState_t dummy; + + if ( !from ) { + from = &dummy; + Com_Memset( &dummy, 0, sizeof( dummy ) ); + } + *to = *from; + + if ( msg->bit == 0 ) { + startBit = msg->readcount * 8 - GENTITYNUM_BITS; + } else { + startBit = ( msg->readcount - 1 ) * 8 + msg->bit - GENTITYNUM_BITS; + } + + // shownet 2/3 will interleave with other printed info, -2 will + // just print the delta records + if ( cl_shownet->integer >= 2 || cl_shownet->integer == -2 ) { + print = 1; + Com_Printf( "%3i: playerstate ", msg->readcount ); + } else { + print = 0; + } + + numFields = sizeof( playerStateFields ) / sizeof( playerStateFields[0] ); + lc = MSG_ReadByte(msg); + + for ( i = 0, field = playerStateFields ; i < lc ; i++, field++ ) { + fromF = (int *)( (byte *)from + field->offset ); + toF = (int *)( (byte *)to + field->offset ); + + if ( ! MSG_ReadBits( msg, 1 ) ) { + // no change + *toF = *fromF; + } else { + if ( field->bits == 0 ) { + // float + if ( MSG_ReadBits( msg, 1 ) == 0 ) { + // integral float + trunc = MSG_ReadBits( msg, FLOAT_INT_BITS ); + // bias to allow equal parts positive and negative + trunc -= FLOAT_INT_BIAS; + *(float *)toF = trunc; + if ( print ) { + Com_Printf( "%s:%i ", field->name, trunc ); + } + } else { + // full floating point value + *toF = MSG_ReadBits( msg, 32 ); + if ( print ) { + Com_Printf( "%s:%f ", field->name, *(float *)toF ); + } + } + } else { + // integer + *toF = MSG_ReadBits( msg, field->bits ); + if ( print ) { + Com_Printf( "%s:%i ", field->name, *toF ); + } + } + } + } + for ( i=lc,field = &playerStateFields[lc];i<numFields; i++, field++) { + fromF = (int *)( (byte *)from + field->offset ); + toF = (int *)( (byte *)to + field->offset ); + // no change + *toF = *fromF; + } + + + // read the arrays + if (MSG_ReadBits( msg, 1 ) ) { + // parse stats + if ( MSG_ReadBits( msg, 1 ) ) { + LOG("PS_STATS"); + bits = MSG_ReadShort (msg); + for (i=0 ; i<16 ; i++) { + if (bits & (1<<i) ) { + to->stats[i] = MSG_ReadShort(msg); + } + } + } + + // parse persistant stats + if ( MSG_ReadBits( msg, 1 ) ) { + LOG("PS_PERSISTANT"); + bits = MSG_ReadShort (msg); + for (i=0 ; i<16 ; i++) { + if (bits & (1<<i) ) { + to->persistant[i] = MSG_ReadShort(msg); + } + } + } + + // parse ammo + if ( MSG_ReadBits( msg, 1 ) ) { + LOG("PS_AMMO"); + bits = MSG_ReadShort (msg); + for (i=0 ; i<16 ; i++) { + if (bits & (1<<i) ) { + to->ammo[i] = MSG_ReadShort(msg); + } + } + } + + // parse powerups + if ( MSG_ReadBits( msg, 1 ) ) { + LOG("PS_POWERUPS"); + bits = MSG_ReadShort (msg); + for (i=0 ; i<16 ; i++) { + if (bits & (1<<i) ) { + to->powerups[i] = MSG_ReadLong(msg); + } + } + } + } + + if ( print ) { + if ( msg->bit == 0 ) { + endBit = msg->readcount * 8 - GENTITYNUM_BITS; + } else { + endBit = ( msg->readcount - 1 ) * 8 + msg->bit - GENTITYNUM_BITS; + } + Com_Printf( " (%i bits)\n", endBit - startBit ); + } +} + +int msg_hData[256] = { +250315, // 0 +41193, // 1 +6292, // 2 +7106, // 3 +3730, // 4 +3750, // 5 +6110, // 6 +23283, // 7 +33317, // 8 +6950, // 9 +7838, // 10 +9714, // 11 +9257, // 12 +17259, // 13 +3949, // 14 +1778, // 15 +8288, // 16 +1604, // 17 +1590, // 18 +1663, // 19 +1100, // 20 +1213, // 21 +1238, // 22 +1134, // 23 +1749, // 24 +1059, // 25 +1246, // 26 +1149, // 27 +1273, // 28 +4486, // 29 +2805, // 30 +3472, // 31 +21819, // 32 +1159, // 33 +1670, // 34 +1066, // 35 +1043, // 36 +1012, // 37 +1053, // 38 +1070, // 39 +1726, // 40 +888, // 41 +1180, // 42 +850, // 43 +960, // 44 +780, // 45 +1752, // 46 +3296, // 47 +10630, // 48 +4514, // 49 +5881, // 50 +2685, // 51 +4650, // 52 +3837, // 53 +2093, // 54 +1867, // 55 +2584, // 56 +1949, // 57 +1972, // 58 +940, // 59 +1134, // 60 +1788, // 61 +1670, // 62 +1206, // 63 +5719, // 64 +6128, // 65 +7222, // 66 +6654, // 67 +3710, // 68 +3795, // 69 +1492, // 70 +1524, // 71 +2215, // 72 +1140, // 73 +1355, // 74 +971, // 75 +2180, // 76 +1248, // 77 +1328, // 78 +1195, // 79 +1770, // 80 +1078, // 81 +1264, // 82 +1266, // 83 +1168, // 84 +965, // 85 +1155, // 86 +1186, // 87 +1347, // 88 +1228, // 89 +1529, // 90 +1600, // 91 +2617, // 92 +2048, // 93 +2546, // 94 +3275, // 95 +2410, // 96 +3585, // 97 +2504, // 98 +2800, // 99 +2675, // 100 +6146, // 101 +3663, // 102 +2840, // 103 +14253, // 104 +3164, // 105 +2221, // 106 +1687, // 107 +3208, // 108 +2739, // 109 +3512, // 110 +4796, // 111 +4091, // 112 +3515, // 113 +5288, // 114 +4016, // 115 +7937, // 116 +6031, // 117 +5360, // 118 +3924, // 119 +4892, // 120 +3743, // 121 +4566, // 122 +4807, // 123 +5852, // 124 +6400, // 125 +6225, // 126 +8291, // 127 +23243, // 128 +7838, // 129 +7073, // 130 +8935, // 131 +5437, // 132 +4483, // 133 +3641, // 134 +5256, // 135 +5312, // 136 +5328, // 137 +5370, // 138 +3492, // 139 +2458, // 140 +1694, // 141 +1821, // 142 +2121, // 143 +1916, // 144 +1149, // 145 +1516, // 146 +1367, // 147 +1236, // 148 +1029, // 149 +1258, // 150 +1104, // 151 +1245, // 152 +1006, // 153 +1149, // 154 +1025, // 155 +1241, // 156 +952, // 157 +1287, // 158 +997, // 159 +1713, // 160 +1009, // 161 +1187, // 162 +879, // 163 +1099, // 164 +929, // 165 +1078, // 166 +951, // 167 +1656, // 168 +930, // 169 +1153, // 170 +1030, // 171 +1262, // 172 +1062, // 173 +1214, // 174 +1060, // 175 +1621, // 176 +930, // 177 +1106, // 178 +912, // 179 +1034, // 180 +892, // 181 +1158, // 182 +990, // 183 +1175, // 184 +850, // 185 +1121, // 186 +903, // 187 +1087, // 188 +920, // 189 +1144, // 190 +1056, // 191 +3462, // 192 +2240, // 193 +4397, // 194 +12136, // 195 +7758, // 196 +1345, // 197 +1307, // 198 +3278, // 199 +1950, // 200 +886, // 201 +1023, // 202 +1112, // 203 +1077, // 204 +1042, // 205 +1061, // 206 +1071, // 207 +1484, // 208 +1001, // 209 +1096, // 210 +915, // 211 +1052, // 212 +995, // 213 +1070, // 214 +876, // 215 +1111, // 216 +851, // 217 +1059, // 218 +805, // 219 +1112, // 220 +923, // 221 +1103, // 222 +817, // 223 +1899, // 224 +1872, // 225 +976, // 226 +841, // 227 +1127, // 228 +956, // 229 +1159, // 230 +950, // 231 +7791, // 232 +954, // 233 +1289, // 234 +933, // 235 +1127, // 236 +3207, // 237 +1020, // 238 +927, // 239 +1355, // 240 +768, // 241 +1040, // 242 +745, // 243 +952, // 244 +805, // 245 +1073, // 246 +740, // 247 +1013, // 248 +805, // 249 +1008, // 250 +796, // 251 +996, // 252 +1057, // 253 +11457, // 254 +13504, // 255 +}; + +void MSG_initHuffman() { + int i,j; + + msgInit = qtrue; + Huff_Init(&msgHuff); + for(i=0;i<256;i++) { + for (j=0;j<msg_hData[i];j++) { + Huff_addRef(&msgHuff.compressor, (byte)i); // Do update + Huff_addRef(&msgHuff.decompressor, (byte)i); // Do update + } + } +} + +/* +void MSG_NUinitHuffman() { + byte *data; + int size, i, ch; + int array[256]; + + msgInit = qtrue; + + Huff_Init(&msgHuff); + // load it in + size = FS_ReadFile( "netchan/netchan.bin", (void **)&data ); + + for(i=0;i<256;i++) { + array[i] = 0; + } + for(i=0;i<size;i++) { + ch = data[i]; + Huff_addRef(&msgHuff.compressor, ch); // Do update + Huff_addRef(&msgHuff.decompressor, ch); // Do update + array[ch]++; + } + Com_Printf("msg_hData {\n"); + for(i=0;i<256;i++) { + if (array[i] == 0) { + Huff_addRef(&msgHuff.compressor, i); // Do update + Huff_addRef(&msgHuff.decompressor, i); // Do update + } + Com_Printf("%d, // %d\n", array[i], i); + } + Com_Printf("};\n"); + FS_FreeFile( data ); + Cbuf_AddText( "condump dump.txt\n" ); +} +*/ + +//=========================================================================== |