mirror of
https://github.com/FWGS/xash3d-fwgs
synced 2024-11-23 02:15:55 +01:00
engine: common: simplify bit buffer operations
Yields a small performance boost
This commit is contained in:
parent
2f2780cb1b
commit
1677835b45
@ -118,7 +118,7 @@ static void NET_AnnounceToMaster( master_t *m )
|
||||
MSG_WriteBytes( &msg, "q\xFF", 2 );
|
||||
MSG_WriteDword( &msg, m->heartbeat_challenge );
|
||||
|
||||
NET_SendPacket( NS_SERVER, MSG_GetNumBytesWritten( &msg ), MSG_GetBuf( &msg ), m->adr );
|
||||
NET_SendPacket( NS_SERVER, MSG_GetNumBytesWritten( &msg ), MSG_GetData( &msg ), m->adr );
|
||||
|
||||
if( sv_verbose_heartbeats.value )
|
||||
{
|
||||
|
@ -109,85 +109,6 @@ void MSG_InitMasks( void )
|
||||
ExtraMasks[maskBit] = (uint)BIT( maskBit ) - 1;
|
||||
}
|
||||
|
||||
void MSG_InitExt( sizebuf_t *sb, const char *pDebugName, void *pData, int nBytes, int nMaxBits )
|
||||
{
|
||||
MSG_StartWriting( sb, pData, nBytes, 0, nMaxBits );
|
||||
|
||||
sb->pDebugName = pDebugName;
|
||||
}
|
||||
|
||||
void MSG_StartWriting( sizebuf_t *sb, void *pData, int nBytes, int iStartBit, int nBits )
|
||||
{
|
||||
// make sure it's dword aligned and padded.
|
||||
Assert(((uint32_t)pData & 3 ) == 0 );
|
||||
|
||||
sb->pDebugName = "Unnamed";
|
||||
sb->pData = (byte *)pData;
|
||||
|
||||
if( nBits == -1 )
|
||||
{
|
||||
sb->nDataBits = nBytes << 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( nBits <= nBytes * 8 );
|
||||
sb->nDataBits = nBits;
|
||||
}
|
||||
|
||||
sb->iCurBit = iStartBit;
|
||||
sb->bOverflow = false;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
MSG_Clear
|
||||
|
||||
for clearing overflowed buffer
|
||||
=======================
|
||||
*/
|
||||
void MSG_Clear( sizebuf_t *sb )
|
||||
{
|
||||
sb->iCurBit = 0;
|
||||
sb->bOverflow = false;
|
||||
}
|
||||
|
||||
static qboolean MSG_Overflow( sizebuf_t *sb, int nBits )
|
||||
{
|
||||
if( sb->iCurBit + nBits > sb->nDataBits )
|
||||
sb->bOverflow = true;
|
||||
return sb->bOverflow;
|
||||
}
|
||||
|
||||
qboolean MSG_CheckOverflow( sizebuf_t *sb )
|
||||
{
|
||||
return MSG_Overflow( sb, 0 );
|
||||
}
|
||||
|
||||
int MSG_SeekToBit( sizebuf_t *sb, int bitPos, int whence )
|
||||
{
|
||||
// compute the file offset
|
||||
switch( whence )
|
||||
{
|
||||
case SEEK_CUR:
|
||||
bitPos += sb->iCurBit;
|
||||
break;
|
||||
case SEEK_SET:
|
||||
break;
|
||||
case SEEK_END:
|
||||
bitPos += sb->nDataBits;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( bitPos < 0 || bitPos > sb->nDataBits )
|
||||
return -1;
|
||||
|
||||
sb->iCurBit = bitPos;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MSG_WriteOneBit( sizebuf_t *sb, int nValue )
|
||||
{
|
||||
if( !MSG_Overflow( sb, 1 ))
|
||||
@ -669,7 +590,7 @@ qboolean MSG_ReadBytes( sizebuf_t *sb, void *pOut, int nBytes )
|
||||
return MSG_ReadBits( sb, pOut, nBytes << 3 );
|
||||
}
|
||||
|
||||
char *MSG_ReadStringExt( sizebuf_t *sb, qboolean bLine )
|
||||
static char *MSG_ReadStringExt( sizebuf_t *sb, qboolean bLine )
|
||||
{
|
||||
static char string[4096];
|
||||
int l = 0, c;
|
||||
@ -695,6 +616,16 @@ char *MSG_ReadStringExt( sizebuf_t *sb, qboolean bLine )
|
||||
return string;
|
||||
}
|
||||
|
||||
char *MSG_ReadString( sizebuf_t *sb )
|
||||
{
|
||||
return MSG_ReadStringExt( sb, false );
|
||||
}
|
||||
|
||||
char *MSG_ReadStringLine( sizebuf_t *sb )
|
||||
{
|
||||
return MSG_ReadStringExt( sb, true );
|
||||
}
|
||||
|
||||
void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove )
|
||||
{
|
||||
int i, endbit = startbit + bitstoremove;
|
||||
|
@ -30,39 +30,128 @@ GNU General Public License for more details.
|
||||
// So PAD_NUMBER(0,4) is 0 and PAD_NUMBER(1,4) is 4
|
||||
#define PAD_NUMBER( num, boundary ) ((( num ) + (( boundary ) - 1 )) / ( boundary )) * ( boundary )
|
||||
|
||||
_inline int BitByte( int bits )
|
||||
static inline int BitByte( int bits )
|
||||
{
|
||||
return PAD_NUMBER( bits, 8 ) >> 3;
|
||||
}
|
||||
|
||||
struct sizebuf_s
|
||||
{
|
||||
qboolean bOverflow; // overflow reading or writing
|
||||
const char *pDebugName; // buffer name (pointer to const name)
|
||||
|
||||
byte *pData;
|
||||
int iCurBit;
|
||||
int nDataBits;
|
||||
byte *pData;
|
||||
qboolean bOverflow; // overflow reading or writing
|
||||
int iCurBit;
|
||||
int nDataBits;
|
||||
const char *pDebugName; // buffer name (pointer to const name)
|
||||
};
|
||||
|
||||
#define MSG_StartReading MSG_StartWriting
|
||||
#define MSG_GetNumBytesRead MSG_GetNumBytesWritten
|
||||
#define MSG_GetRealBytesRead MSG_GetRealBytesWritten
|
||||
#define MSG_GetNumBitsRead MSG_GetNumBitsWritten
|
||||
#define MSG_ReadBitAngles MSG_ReadBitVec3Coord
|
||||
#define MSG_ReadString( sb ) MSG_ReadStringExt( sb, false )
|
||||
#define MSG_ReadStringLine( sb ) MSG_ReadStringExt( sb, true )
|
||||
#define MSG_ReadAngle( sb ) (float)(MSG_ReadChar( sb ) * ( 360.0f / 256.0f ))
|
||||
#define MSG_Init( sb, name, data, bytes ) MSG_InitExt( sb, name, data, bytes, -1 )
|
||||
#define MSG_StartReading MSG_StartWriting
|
||||
#define MSG_GetNumBytesRead MSG_GetNumBytesWritten
|
||||
#define MSG_GetRealBytesRead MSG_GetRealBytesWritten
|
||||
#define MSG_GetNumBitsRead MSG_GetNumBitsWritten
|
||||
#define MSG_ReadBitAngles MSG_ReadBitVec3Coord
|
||||
#define MSG_ReadAngle( sb ) (float)( MSG_ReadChar( sb ) * ( 360.0f / 256.0f ))
|
||||
#define MSG_Init( sb, name, data, bytes ) MSG_InitExt( sb, name, data, bytes, -1 )
|
||||
#define MSG_CheckOverflow( sb ) MSG_Overflow( sb, 0 )
|
||||
|
||||
// common functions
|
||||
void MSG_InitExt( sizebuf_t *sb, const char *pDebugName, void *pData, int nBytes, int nMaxBits );
|
||||
void MSG_InitMasks( void ); // called once at startup engine
|
||||
int MSG_SeekToBit( sizebuf_t *sb, int bitPos, int whence );
|
||||
void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove );
|
||||
_inline int MSG_TellBit( sizebuf_t *sb ) { return sb->iCurBit; }
|
||||
_inline const char *MSG_GetName( sizebuf_t *sb ) { return sb->pDebugName; }
|
||||
qboolean MSG_CheckOverflow( sizebuf_t *sb );
|
||||
static inline void MSG_Clear( sizebuf_t *sb )
|
||||
{
|
||||
sb->bOverflow = false;
|
||||
sb->iCurBit = 0;
|
||||
}
|
||||
|
||||
static inline void MSG_InitExt( sizebuf_t *sb, const char *pDebugName, void *pData, int nBytes, int nBits )
|
||||
{
|
||||
sb->pData = pData;
|
||||
MSG_Clear( sb );
|
||||
|
||||
if( nBits < 0 )
|
||||
sb->nDataBits = nBytes << 3;
|
||||
else
|
||||
sb->nDataBits = nBits;
|
||||
|
||||
sb->pDebugName = pDebugName;
|
||||
}
|
||||
|
||||
static inline void MSG_StartWriting( sizebuf_t *sb, void *pData, int nBytes, int iStartBit, int nBits )
|
||||
{
|
||||
MSG_InitExt( sb, "Unnamed", pData, nBytes, nBits );
|
||||
sb->iCurBit = iStartBit;
|
||||
}
|
||||
|
||||
static inline int MSG_SeekToBit( sizebuf_t *sb, int bitPos, int whence )
|
||||
{
|
||||
// compute the file offset
|
||||
switch( whence )
|
||||
{
|
||||
case SEEK_CUR:
|
||||
bitPos += sb->iCurBit;
|
||||
break;
|
||||
case SEEK_SET:
|
||||
break;
|
||||
case SEEK_END:
|
||||
bitPos += sb->nDataBits;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( unlikely( bitPos < 0 || bitPos > sb->nDataBits ))
|
||||
return -1;
|
||||
|
||||
sb->iCurBit = bitPos;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int MSG_TellBit( sizebuf_t *sb )
|
||||
{
|
||||
return sb->iCurBit;
|
||||
}
|
||||
|
||||
static inline const char *MSG_GetName( sizebuf_t *sb )
|
||||
{
|
||||
return sb->pDebugName;
|
||||
}
|
||||
|
||||
static inline int MSG_GetNumBytesWritten( sizebuf_t *sb )
|
||||
{
|
||||
return BitByte( sb->iCurBit );
|
||||
}
|
||||
|
||||
static inline int MSG_GetRealBytesWritten( sizebuf_t *sb )
|
||||
{
|
||||
return sb->iCurBit >> 3; // unpadded
|
||||
}
|
||||
static inline int MSG_GetNumBitsWritten( sizebuf_t *sb )
|
||||
{
|
||||
return sb->iCurBit;
|
||||
}
|
||||
|
||||
static inline int MSG_GetMaxBits( sizebuf_t *sb )
|
||||
{
|
||||
return sb->nDataBits;
|
||||
}
|
||||
|
||||
static inline int MSG_GetMaxBytes( sizebuf_t *sb )
|
||||
{
|
||||
return sb->nDataBits >> 3;
|
||||
}
|
||||
|
||||
static inline int MSG_GetNumBitsLeft( sizebuf_t *sb )
|
||||
{
|
||||
return sb->nDataBits - sb->iCurBit;
|
||||
}
|
||||
|
||||
static inline int MSG_GetNumBytesLeft( sizebuf_t *sb )
|
||||
{
|
||||
return MSG_GetNumBitsLeft( sb ) >> 3;
|
||||
}
|
||||
|
||||
static inline byte *MSG_GetData( sizebuf_t *sb )
|
||||
{
|
||||
return sb->pData;
|
||||
}
|
||||
|
||||
#if XASH_BIG_ENDIAN
|
||||
#define MSG_BigShort( x ) ( x )
|
||||
@ -73,9 +162,15 @@ static inline uint16_t MSG_BigShort( const uint16_t x )
|
||||
}
|
||||
#endif
|
||||
|
||||
// init writing
|
||||
void MSG_StartWriting( sizebuf_t *sb, void *pData, int nBytes, int iStartBit, int nBits );
|
||||
void MSG_Clear( sizebuf_t *sb );
|
||||
static inline qboolean MSG_Overflow( sizebuf_t *sb, int nBits )
|
||||
{
|
||||
if( sb->iCurBit + nBits > sb->nDataBits )
|
||||
sb->bOverflow = true;
|
||||
return sb->bOverflow;
|
||||
}
|
||||
|
||||
void MSG_InitMasks( void ); // called once at startup engine
|
||||
void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove );
|
||||
|
||||
// Bit-write functions
|
||||
void MSG_WriteOneBit( sizebuf_t *sb, int nValue );
|
||||
@ -99,20 +194,11 @@ void MSG_WriteCoord( sizebuf_t *sb, float val );
|
||||
void MSG_WriteFloat( sizebuf_t *sb, float val );
|
||||
void MSG_WriteVec3Coord( sizebuf_t *sb, const float *fa );
|
||||
void MSG_WriteVec3Angles( sizebuf_t *sb, const float *fa );
|
||||
qboolean MSG_WriteBytes( sizebuf_t *sb, const void *pBuf, int nBytes ); // same as MSG_WriteData
|
||||
qboolean MSG_WriteString( sizebuf_t *sb, const char *pStr ); // returns false if it overflows the buffer.
|
||||
qboolean MSG_WriteStringf( sizebuf_t *sb, const char *format, ... ) _format( 2 );
|
||||
qboolean MSG_WriteBytes( sizebuf_t *sb, const void *pBuf, int nBytes );
|
||||
|
||||
// helper functions
|
||||
_inline int MSG_GetNumBytesWritten( sizebuf_t *sb ) { return BitByte( sb->iCurBit ); }
|
||||
_inline int MSG_GetRealBytesWritten( sizebuf_t *sb ) { return sb->iCurBit >> 3; } // unpadded
|
||||
_inline int MSG_GetNumBitsWritten( sizebuf_t *sb ) { return sb->iCurBit; }
|
||||
_inline int MSG_GetMaxBits( sizebuf_t *sb ) { return sb->nDataBits; }
|
||||
_inline int MSG_GetMaxBytes( sizebuf_t *sb ) { return sb->nDataBits >> 3; }
|
||||
_inline int MSG_GetNumBitsLeft( sizebuf_t *sb ) { return sb->nDataBits - sb->iCurBit; }
|
||||
_inline int MSG_GetNumBytesLeft( sizebuf_t *sb ) { return MSG_GetNumBitsLeft( sb ) >> 3; }
|
||||
_inline byte *MSG_GetData( sizebuf_t *sb ) { return sb->pData; }
|
||||
_inline byte *MSG_GetBuf( sizebuf_t *sb ) { return sb->pData; } // just an alias
|
||||
|
||||
// Bit-read functions
|
||||
int MSG_ReadOneBit( sizebuf_t *sb );
|
||||
@ -136,7 +222,8 @@ float MSG_ReadCoord( sizebuf_t *sb );
|
||||
float MSG_ReadFloat( sizebuf_t *sb );
|
||||
void MSG_ReadVec3Coord( sizebuf_t *sb, vec3_t fa );
|
||||
void MSG_ReadVec3Angles( sizebuf_t *sb, vec3_t fa );
|
||||
char *MSG_ReadString( sizebuf_t *sb );
|
||||
char *MSG_ReadStringLine( sizebuf_t *sb );
|
||||
qboolean MSG_ReadBytes( sizebuf_t *sb, void *pOut, int nBytes );
|
||||
char *MSG_ReadStringExt( sizebuf_t *sb, qboolean bLine );
|
||||
|
||||
#endif//NET_BUFFER_H
|
||||
|
@ -811,17 +811,17 @@ static void SV_UpdateToReliableMessages( void )
|
||||
continue; // reliables go to all connected or spawned
|
||||
|
||||
if( MSG_GetNumBytesWritten( &sv.reliable_datagram ) < MSG_GetNumBytesLeft( &cl->netchan.message ))
|
||||
MSG_WriteBits( &cl->netchan.message, MSG_GetBuf( &sv.reliable_datagram ), MSG_GetNumBitsWritten( &sv.reliable_datagram ));
|
||||
MSG_WriteBits( &cl->netchan.message, MSG_GetData( &sv.reliable_datagram ), MSG_GetNumBitsWritten( &sv.reliable_datagram ));
|
||||
else Netchan_CreateFragments( &cl->netchan, &sv.reliable_datagram );
|
||||
|
||||
if( MSG_GetNumBytesWritten( &sv.datagram ) < MSG_GetNumBytesLeft( &cl->datagram ))
|
||||
MSG_WriteBits( &cl->datagram, MSG_GetBuf( &sv.datagram ), MSG_GetNumBitsWritten( &sv.datagram ));
|
||||
MSG_WriteBits( &cl->datagram, MSG_GetData( &sv.datagram ), MSG_GetNumBitsWritten( &sv.datagram ));
|
||||
else Con_DPrintf( S_WARN "Ignoring unreliable datagram for %s, would overflow\n", cl->name );
|
||||
|
||||
if( FBitSet( cl->flags, FCL_HLTV_PROXY ))
|
||||
{
|
||||
if( MSG_GetNumBytesWritten( &sv.spec_datagram ) < MSG_GetNumBytesLeft( &cl->datagram ))
|
||||
MSG_WriteBits( &cl->datagram, MSG_GetBuf( &sv.spec_datagram ), MSG_GetNumBitsWritten( &sv.spec_datagram ));
|
||||
MSG_WriteBits( &cl->datagram, MSG_GetData( &sv.spec_datagram ), MSG_GetNumBitsWritten( &sv.spec_datagram ));
|
||||
else Con_DPrintf( S_WARN "Ignoring spectator datagram for %s, would overflow\n", cl->name );
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user