engine: common: add GoldSrc bitbuf operations, add support for GoldSrc signed integers
This commit is contained in:
parent
61342547ce
commit
d128997d40
2 changed files with 71 additions and 12 deletions
|
@ -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 )
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue