diff --git a/engine/common/net_buffer.c b/engine/common/net_buffer.c index 96b9daef..8c7798a9 100644 --- a/engine/common/net_buffer.c +++ b/engine/common/net_buffer.c @@ -213,17 +213,25 @@ void MSG_WriteSBitLong( sizebuf_t *sb, int data, int numbits ) // do we have a valid # of bits to encode with? Assert( numbits >= 1 && numbits <= 32 ); - // NOTE: it does this wierdness here so it's bit-compatible with regular integer data in the buffer. - // (Some old code writes direct integers right into the buffer). if( data < 0 ) { + if( sb->iAlternateSign ) + MSG_WriteOneBit( sb, 1 ); + MSG_WriteUBitLong( sb, (uint)( 0x80000000 + data ), numbits - 1 ); - MSG_WriteOneBit( sb, 1 ); + + if( !sb->iAlternateSign ) + MSG_WriteOneBit( sb, 1 ); } else { + if( sb->iAlternateSign ) + MSG_WriteOneBit( sb, 0 ); + MSG_WriteUBitLong( sb, (uint)data, numbits - 1 ); - MSG_WriteOneBit( sb, 0 ); + + if( !sb->iAlternateSign ) + MSG_WriteOneBit( sb, 0 ); } } @@ -533,12 +541,22 @@ int MSG_ReadSBitLong( sizebuf_t *sb, int numbits ) { int r, sign; - r = MSG_ReadUBitLong( sb, numbits - 1 ); + if( sb->iAlternateSign ) + { + sign = MSG_ReadOneBit( sb ); + r = MSG_ReadUBitLong( sb, numbits - 1 ); - // NOTE: it does this wierdness here so it's bit-compatible with regular integer data in the buffer. - // (Some old code writes direct integers right into the buffer). - sign = MSG_ReadOneBit( sb ); - if( sign ) r = -( BIT( numbits - 1 ) - r ); + if( sign ) + r = -r; + } + else + { + r = MSG_ReadUBitLong( sb, numbits - 1 ); + sign = MSG_ReadOneBit( sb ); + + if( sign ) + r = -( BIT( numbits - 1 ) - r ); + } return r; } @@ -569,7 +587,13 @@ int MSG_ReadCmd( sizebuf_t *sb, netsrc_t type ) int MSG_ReadChar( sizebuf_t *sb ) { - return MSG_ReadSBitLong( sb, sizeof( int8_t ) << 3 ); + int alt = sb->iAlternateSign, ret; + + sb->iAlternateSign = 0; + ret = MSG_ReadSBitLong( sb, sizeof( int8_t ) << 3 ); + sb->iAlternateSign = alt; + + return ret; } int MSG_ReadByte( sizebuf_t *sb ) @@ -579,7 +603,13 @@ int MSG_ReadByte( sizebuf_t *sb ) int MSG_ReadShort( sizebuf_t *sb ) { - return MSG_ReadSBitLong( sb, sizeof( int16_t ) << 3 ); + int alt = sb->iAlternateSign, ret; + + sb->iAlternateSign = 0; + ret = MSG_ReadSBitLong( sb, sizeof( int16_t ) << 3 ); + sb->iAlternateSign = alt; + + return ret; } int MSG_ReadWord( sizebuf_t *sb ) @@ -611,7 +641,13 @@ void MSG_ReadVec3Angles( sizebuf_t *sb, vec3_t fa ) int MSG_ReadLong( sizebuf_t *sb ) { - return MSG_ReadSBitLong( sb, sizeof( int32_t ) << 3 ); + int alt = sb->iAlternateSign, ret; + + sb->iAlternateSign = 0; + ret = MSG_ReadSBitLong( sb, sizeof( int32_t ) << 3 ); + sb->iAlternateSign = alt; + + return ret; } uint MSG_ReadDword( sizebuf_t *sb ) diff --git a/engine/common/net_buffer.h b/engine/common/net_buffer.h index e278f737..46470d02 100644 --- a/engine/common/net_buffer.h +++ b/engine/common/net_buffer.h @@ -42,6 +42,9 @@ struct sizebuf_s int iCurBit; int nDataBits; const char *pDebugName; // buffer name (pointer to const name) + + // to support GoldSrc broken signed integers + int iAlternateSign; }; #define MSG_StartReading MSG_StartWriting @@ -71,6 +74,7 @@ static inline void MSG_InitExt( sizebuf_t *sb, const char *pDebugName, void *pDa sb->nDataBits = nBits; sb->pDebugName = pDebugName; + sb->iAlternateSign = 0; } static inline void MSG_StartWriting( sizebuf_t *sb, void *pData, int nBytes, int iStartBit, int nBits ) @@ -169,6 +173,25 @@ static inline qboolean MSG_Overflow( sizebuf_t *sb, int nBits ) return sb->bOverflow; } +static inline void MSG_EndBitWriting( sizebuf_t *sb ) +{ + sb->iAlternateSign--; + + if( sb->iAlternateSign < 0 ) + { + Con_Printf( "%s: non-even MSG_Start/EndBitWriting\n", __func__ ); + sb->iAlternateSign = 0; + } + + // we have native bit ops here, just pad to closest byte + MSG_SeekToBit( sb, MSG_GetNumBytesWritten( sb ) << 3, SEEK_SET ); +} + +static inline void MSG_StartBitWriting( sizebuf_t *sb ) +{ + sb->iAlternateSign++; +} + void MSG_InitMasks( void ); // called once at startup engine void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove );