DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

BitMsg.h (25328B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 #ifndef __BITMSG_H__
     29 #define __BITMSG_H__
     30 
     31 /*
     32 ================================================
     33 idBitMsg operates on a sequence of individual bits. It handles byte ordering and 
     34 avoids alignment errors. It allows concurrent writing and reading. The data set with Init 
     35 is never free-d.
     36 ================================================
     37 */
     38 class idBitMsg {
     39 public:
     40 					idBitMsg() { InitWrite( NULL, 0 ); }
     41 					idBitMsg( byte * data, int length ) { InitWrite( data, length ); }
     42 					idBitMsg( const byte * data, int length ) { InitRead( data, length ); }
     43 
     44 	// both read & write
     45 	void			InitWrite( byte *data, int length );
     46 
     47 	// read only
     48 	void			InitRead( const byte *data, int length );
     49 
     50 	// get data for writing
     51 	byte *			GetWriteData();
     52 
     53 	// get data for reading
     54 	const byte *	GetReadData() const;
     55 
     56 	// get the maximum message size
     57 	int				GetMaxSize() const;
     58 
     59 	// generate error if not set and message is overflowed
     60 	void			SetAllowOverflow( bool set );
     61 
     62 	// returns true if the message was overflowed
     63 	bool			IsOverflowed() const;
     64 
     65 	// size of the message in bytes
     66 	int				GetSize() const;
     67 
     68 	// set the message size
     69 	void			SetSize( int size );
     70 
     71 	// get current write bit
     72 	int				GetWriteBit() const;
     73 
     74 	// set current write bit
     75 	void			SetWriteBit( int bit );
     76 
     77 	// returns number of bits written
     78 	int				GetNumBitsWritten() const;
     79 
     80 	// space left in bytes for writing
     81 	int				GetRemainingSpace() const;
     82 
     83 	// space left in bits for writing
     84 	int				GetRemainingWriteBits() const;
     85 
     86 	//------------------------
     87 	// Write State
     88 	//------------------------
     89 
     90 	// save the write state
     91 	void			SaveWriteState( int &s, int &b, uint64 &t ) const;
     92 
     93 	// restore the write state
     94 	void			RestoreWriteState( int s, int b, uint64 t );
     95 
     96 	//------------------------
     97 	// Reading
     98 	//------------------------
     99 
    100 	// bytes read so far
    101 	int				GetReadCount() const;
    102 
    103 	// set the number of bytes and bits read
    104 	void			SetReadCount( int bytes );
    105 
    106 	// get current read bit
    107 	int				GetReadBit() const;
    108 
    109 	// set current read bit
    110 	void			SetReadBit( int bit );
    111 
    112 	// returns number of bits read
    113 	int				GetNumBitsRead() const;
    114 
    115 	// number of bytes left to read
    116 	int				GetRemainingData() const;
    117 
    118 	// number of bits left to read
    119 	int				GetRemainingReadBits() const;
    120 
    121 	// save the read state
    122 	void			SaveReadState( int &c, int &b ) const;
    123 
    124 	// restore the read state
    125 	void			RestoreReadState( int c, int b );
    126 
    127 	//------------------------
    128 	// Writing
    129 	//------------------------
    130 
    131 	// begin writing
    132 	void			BeginWriting();
    133 
    134 	// write up to the next byte boundary
    135 	void			WriteByteAlign();
    136 
    137 	// write the specified number of bits
    138 	void			WriteBits( int value, int numBits );
    139 
    140 	void			WriteBool( bool c );
    141 	void			WriteChar( int8 c );
    142 	void			WriteByte( uint8 c );
    143 	void			WriteShort( int16 c );
    144 	void			WriteUShort( uint16 c );
    145 	void			WriteLong( int32 c );
    146 	void			WriteLongLong( int64 c );
    147 	void			WriteFloat( float f );
    148 	void			WriteFloat( float f, int exponentBits, int mantissaBits );
    149 	void			WriteAngle8( float f );
    150 	void			WriteAngle16( float f );
    151 	void			WriteDir( const idVec3 &dir, int numBits );
    152 	void			WriteString( const char *s, int maxLength = -1, bool make7Bit = true );
    153 	void			WriteData( const void *data, int length );
    154 	void			WriteNetadr( const netadr_t adr );
    155 
    156 	void			WriteUNorm8( float f ) { WriteByte( idMath::Ftob( f * 255.0f ) ); }
    157 	void			WriteUNorm16( float f ) { WriteUShort( idMath::Ftoi( f * 65535.0f ) ); }
    158 	void			WriteNorm16( float f ) { WriteShort( idMath::Ftoi( f * 32767.0f ) ); }
    159 
    160 	void			WriteDeltaChar( int8 oldValue, int8 newValue ) { WriteByte( newValue - oldValue ); }
    161 	void			WriteDeltaByte( uint8 oldValue, uint8 newValue ) { WriteByte( newValue - oldValue ); }
    162 	void			WriteDeltaShort( int16 oldValue, int16 newValue ) { WriteUShort( newValue - oldValue ); }
    163 	void			WriteDeltaUShort( uint16 oldValue, uint16 newValue ) { WriteUShort( newValue - oldValue ); }
    164 	void			WriteDeltaLong( int32 oldValue, int32 newValue ) { WriteLong( newValue - oldValue ); }
    165 	void			WriteDeltaFloat( float oldValue, float newValue ) { WriteFloat( newValue - oldValue ); }
    166 	void			WriteDeltaFloat( float oldValue, float newValue, int exponentBits, int mantissaBits ) { WriteFloat( newValue - oldValue, exponentBits, mantissaBits ); }
    167 
    168 	bool			WriteDeltaDict( const idDict &dict, const idDict *base );
    169 
    170 	template< int _max_, int _numBits_ >
    171 	void			WriteQuantizedFloat( float value );
    172 	template< int _max_, int _numBits_ >
    173 	void			WriteQuantizedUFloat( float value );		// Quantize a float to a variable number of bits (assumes unsigned, uses simple quantization)
    174 
    175 	template< typename T >
    176 	void			WriteVectorFloat( const T & v ) { for ( int i = 0; i < v.GetDimension(); i++ ) { WriteFloat( v[i] ); } }
    177 	template< typename T >
    178 	void			WriteVectorUNorm8( const T & v ) { for ( int i = 0; i < v.GetDimension(); i++ ) { WriteUNorm8( v[i] ); } }
    179 	template< typename T >
    180 	void			WriteVectorUNorm16( const T & v ) { for ( int i = 0; i < v.GetDimension(); i++ ) { WriteUNorm16( v[i] ); } }
    181 	template< typename T >
    182 	void			WriteVectorNorm16( const T & v ) { for ( int i = 0; i < v.GetDimension(); i++ ) { WriteNorm16( v[i] ); } }
    183 
    184 	// Compress a vector to a variable number of bits (assumes signed, uses simple quantization)
    185 	template< typename T, int _max_, int _numBits_  >
    186 	void			WriteQuantizedVector( const T & v ) { for ( int i = 0; i < v.GetDimension(); i++ ) { WriteQuantizedFloat< _max_, _numBits_ >( v[i] ); } }
    187 
    188 	// begin reading.
    189 	void			BeginReading() const;
    190 
    191 	// read up to the next byte boundary
    192 	void			ReadByteAlign() const;
    193 
    194 	// read the specified number of bits
    195 	int				ReadBits( int numBits ) const;
    196 
    197 	bool			ReadBool() const;
    198 	int				ReadChar() const;
    199 	int				ReadByte() const;
    200 	int				ReadShort() const;
    201 	int				ReadUShort() const;
    202 	int				ReadLong() const;
    203 	int64			ReadLongLong() const;
    204 	float			ReadFloat() const;
    205 	float			ReadFloat( int exponentBits, int mantissaBits ) const;
    206 	float			ReadAngle8() const;
    207 	float			ReadAngle16() const;
    208 	idVec3			ReadDir( int numBits ) const;
    209 	int				ReadString( char *buffer, int bufferSize ) const;
    210 	int				ReadString( idStr & str ) const;
    211 	int				ReadData( void *data, int length ) const;
    212 	void			ReadNetadr( netadr_t *adr ) const;
    213 
    214 	float			ReadUNorm8() const { return ReadByte() / 255.0f; }
    215 	float			ReadUNorm16() const { return ReadUShort() / 65535.0f; }
    216 	float			ReadNorm16() const { return ReadShort() / 32767.0f; }
    217 
    218 	int8			ReadDeltaChar( int8 oldValue ) const { return oldValue + ReadByte(); }
    219 	uint8			ReadDeltaByte( uint8 oldValue ) const { return oldValue + ReadByte(); }
    220 	int16			ReadDeltaShort( int16 oldValue ) const { return oldValue + ReadUShort(); }
    221 	uint16			ReadDeltaUShort( uint16 oldValue ) const { return oldValue + ReadUShort(); }
    222 	int32			ReadDeltaLong( int32 oldValue ) const { return oldValue + ReadLong(); }
    223 	float			ReadDeltaFloat( float oldValue ) const { return oldValue + ReadFloat(); }
    224 	float			ReadDeltaFloat( float oldValue, int exponentBits, int mantissaBits ) const { return oldValue + ReadFloat( exponentBits, mantissaBits ); }
    225 	bool			ReadDeltaDict( idDict &dict, const idDict *base ) const;
    226 
    227 	template< int _max_, int _numBits_ >
    228 	float			ReadQuantizedFloat() const;
    229 	template< int _max_, int _numBits_ >
    230 	float			ReadQuantizedUFloat() const;
    231 
    232 	template< typename T >
    233 	void			ReadVectorFloat( T & v ) const { for ( int i = 0; i < v.GetDimension(); i++ ) { v[i] = ReadFloat(); } }
    234 	template< typename T >
    235 	void			ReadVectorUNorm8( T & v ) const { for ( int i = 0; i < v.GetDimension(); i++ ) { v[i] = ReadUNorm8(); } }
    236 	template< typename T >
    237 	void			ReadVectorUNorm16( T & v ) const { for ( int i = 0; i < v.GetDimension(); i++ ) { v[i] = ReadUNorm16(); } }
    238 	template< typename T >
    239 	void			ReadVectorNorm16( T & v ) const { for ( int i = 0; i < v.GetDimension(); i++ ) { v[i] = ReadNorm16(); } }
    240 	template< typename T, int _max_, int _numBits_ >
    241 	void			ReadQuantizedVector( T & v ) const { for ( int i = 0; i < v.GetDimension(); i++ ) { v[i] = ReadQuantizedFloat< _max_, _numBits_ >(); } }
    242 
    243 	static int		DirToBits( const idVec3 &dir, int numBits );
    244 	static idVec3	BitsToDir( int bits, int numBits );
    245 
    246 	void			SetHasChanged( bool b ) { hasChanged = b; }
    247 	bool			HasChanged() const { return hasChanged; }
    248 
    249 private:
    250 	byte *			writeData;		// pointer to data for writing
    251 	const byte *	readData;		// pointer to data for reading
    252 	int				maxSize;		// maximum size of message in bytes
    253 	int				curSize;		// current size of message in bytes
    254 	mutable int		writeBit;		// number of bits written to the last written byte
    255 	mutable int		readCount;		// number of bytes read so far
    256 	mutable int		readBit;		// number of bits read from the last read byte
    257 	bool			allowOverflow;	// if false, generate error when the message is overflowed
    258 	bool			overflowed;		// set true if buffer size failed (with allowOverflow set)
    259 	bool			hasChanged;		// Hack
    260 
    261 	mutable uint64	tempValue;
    262 
    263 private:
    264 	bool			CheckOverflow( int numBits );
    265 	byte *			GetByteSpace( int length );
    266 };
    267 
    268 /*
    269 ========================
    270 idBitMsg::InitWrite
    271 ========================
    272 */
    273 ID_INLINE void idBitMsg::InitWrite( byte *data, int length ) {
    274 	writeData = data;
    275 	readData = data;
    276 	maxSize = length;
    277 	curSize = 0;
    278 
    279 	writeBit = 0;
    280 	readCount = 0;
    281 	readBit = 0;
    282 	allowOverflow = false;
    283 	overflowed = false;
    284 	
    285 	tempValue = 0;
    286 }
    287 
    288 /*
    289 ========================
    290 idBitMsg::InitRead
    291 ========================
    292 */
    293 ID_INLINE void idBitMsg::InitRead( const byte *data, int length ) {
    294 	writeData = NULL;
    295 	readData = data;
    296 	maxSize = length;
    297 	curSize = length;
    298 
    299 	writeBit = 0;
    300 	readCount = 0;
    301 	readBit = 0;
    302 	allowOverflow = false;
    303 	overflowed = false;
    304 
    305 	tempValue = 0;
    306 }
    307 
    308 /*
    309 ========================
    310 idBitMsg::GetWriteData
    311 ========================
    312 */
    313 ID_INLINE byte *idBitMsg::GetWriteData() {
    314 	return writeData;
    315 }
    316 
    317 /*
    318 ========================
    319 idBitMsg::GetReadData
    320 ========================
    321 */
    322 ID_INLINE const byte *idBitMsg::GetReadData() const {
    323 	return readData;
    324 }
    325 
    326 /*
    327 ========================
    328 idBitMsg::GetMaxSize
    329 ========================
    330 */
    331 ID_INLINE int idBitMsg::GetMaxSize() const {
    332 	return maxSize;
    333 }
    334 
    335 /*
    336 ========================
    337 idBitMsg::SetAllowOverflow
    338 ========================
    339 */
    340 ID_INLINE void idBitMsg::SetAllowOverflow( bool set ) {
    341 	allowOverflow = set;
    342 }
    343 
    344 /*
    345 ========================
    346 idBitMsg::IsOverflowed
    347 ========================
    348 */
    349 ID_INLINE bool idBitMsg::IsOverflowed() const {
    350 	return overflowed;
    351 }
    352 
    353 /*
    354 ========================
    355 idBitMsg::GetSize
    356 ========================
    357 */
    358 ID_INLINE int idBitMsg::GetSize() const {
    359 	return curSize + ( writeBit != 0 );
    360 }
    361 
    362 /*
    363 ========================
    364 idBitMsg::SetSize
    365 ========================
    366 */
    367 ID_INLINE void idBitMsg::SetSize( int size ) {
    368 	assert( writeBit == 0 );
    369 	
    370 	if ( size > maxSize ) {
    371 		curSize = maxSize;
    372 	} else {
    373 		curSize = size;
    374 	}
    375 }
    376 
    377 /*
    378 ========================
    379 idBitMsg::GetWriteBit
    380 ========================
    381 */
    382 ID_INLINE int idBitMsg::GetWriteBit() const {
    383 	return writeBit;
    384 }
    385 
    386 /*
    387 ========================
    388 idBitMsg::SetWriteBit
    389 ========================
    390 */
    391 ID_INLINE void idBitMsg::SetWriteBit( int bit ) {
    392 	// see idBitMsg::WriteByteAlign
    393 	assert( false );
    394 	writeBit = bit & 7;
    395 	if ( writeBit ) {
    396 		writeData[curSize - 1] &= ( 1 << writeBit ) - 1;
    397 	}
    398 }
    399 
    400 /*
    401 ========================
    402 idBitMsg::GetNumBitsWritten
    403 ========================
    404 */
    405 ID_INLINE int idBitMsg::GetNumBitsWritten() const {
    406 	return ( curSize << 3 ) + writeBit;
    407 }
    408 
    409 /*
    410 ========================
    411 idBitMsg::GetRemainingSpace
    412 ========================
    413 */
    414 ID_INLINE int idBitMsg::GetRemainingSpace() const {
    415 	return maxSize - GetSize();
    416 }
    417 
    418 /*
    419 ========================
    420 idBitMsg::GetRemainingWriteBits
    421 ========================
    422 */
    423 ID_INLINE int idBitMsg::GetRemainingWriteBits() const {
    424 	return ( maxSize << 3 ) - GetNumBitsWritten();
    425 }
    426 
    427 /*
    428 ========================
    429 idBitMsg::SaveWriteState
    430 ========================
    431 */
    432 ID_INLINE void idBitMsg::SaveWriteState( int &s, int &b, uint64 &t ) const {
    433 	s = curSize;
    434 	b = writeBit;
    435 	t = tempValue;
    436 }
    437 
    438 /*
    439 ========================
    440 idBitMsg::RestoreWriteState
    441 ========================
    442 */
    443 ID_INLINE void idBitMsg::RestoreWriteState( int s, int b, uint64 t ) {
    444 	curSize = s;
    445 	writeBit = b & 7;
    446 	if ( writeBit ) {
    447 		writeData[curSize] &= ( 1 << writeBit ) - 1;
    448 	}
    449 	tempValue = t;
    450 }
    451 
    452 /*
    453 ========================
    454 idBitMsg::GetReadCount
    455 ========================
    456 */
    457 ID_INLINE int idBitMsg::GetReadCount() const {
    458 	return readCount;
    459 }
    460 
    461 /*
    462 ========================
    463 idBitMsg::SetReadCount
    464 ========================
    465 */
    466 ID_INLINE void idBitMsg::SetReadCount( int bytes ) {
    467 	readCount = bytes;
    468 }
    469 
    470 /*
    471 ========================
    472 idBitMsg::GetReadBit
    473 ========================
    474 */
    475 ID_INLINE int idBitMsg::GetReadBit() const {
    476 	return readBit;
    477 }
    478 
    479 /*
    480 ========================
    481 idBitMsg::SetReadBit
    482 ========================
    483 */
    484 ID_INLINE void idBitMsg::SetReadBit( int bit ) {
    485 	readBit = bit & 7;
    486 }
    487 
    488 /*
    489 ========================
    490 idBitMsg::GetNumBitsRead
    491 ========================
    492 */
    493 ID_INLINE int idBitMsg::GetNumBitsRead() const {
    494 	return ( ( readCount << 3 ) - ( ( 8 - readBit ) & 7 ) );
    495 }
    496 
    497 /*
    498 ========================
    499 idBitMsg::GetRemainingData
    500 ========================
    501 */
    502 ID_INLINE int idBitMsg::GetRemainingData() const {
    503 	assert( writeBit == 0 );
    504 	return curSize - readCount;
    505 }
    506 
    507 /*
    508 ========================
    509 idBitMsg::GetRemainingReadBits
    510 ========================
    511 */
    512 ID_INLINE int idBitMsg::GetRemainingReadBits() const {
    513 	assert( writeBit == 0 );
    514 	return ( curSize << 3 ) - GetNumBitsRead();
    515 }
    516 
    517 /*
    518 ========================
    519 idBitMsg::SaveReadState
    520 ========================
    521 */
    522 ID_INLINE void idBitMsg::SaveReadState( int &c, int &b ) const {
    523 	assert( writeBit == 0 );
    524 	c = readCount;
    525 	b = readBit;
    526 }
    527 
    528 /*
    529 ========================
    530 idBitMsg::RestoreReadState
    531 ========================
    532 */
    533 ID_INLINE void idBitMsg::RestoreReadState( int c, int b ) {
    534 	assert( writeBit == 0 );
    535 	readCount = c;
    536 	readBit = b & 7;
    537 }
    538 
    539 /*
    540 ========================
    541 idBitMsg::BeginWriting
    542 ========================
    543 */
    544 ID_INLINE void idBitMsg::BeginWriting() {
    545 	curSize = 0;
    546 	overflowed = false;
    547 	writeBit = 0;
    548 	tempValue = 0;
    549 }
    550 
    551 /*
    552 ========================
    553 idBitMsg::WriteByteAlign
    554 ========================
    555 */
    556 ID_INLINE void idBitMsg::WriteByteAlign() {
    557 	// it is important that no uninitialized data slips in the msg stream,
    558 	// because we use memcmp to decide if entities have changed and wether we should transmit them
    559 	// this function has the potential to leave uninitialized bits into the stream,
    560 	// however idBitMsg::WriteBits is properly initializing the byte to 0 so hopefully we are still safe
    561 	// adding this extra check just in case
    562 	curSize += writeBit != 0;
    563 	assert( writeBit == 0 || ( ( writeData[curSize - 1] >> writeBit ) == 0 ) ); // had to early out writeBit == 0 because when writeBit == 0 writeData[curSize - 1] may be the previous byte written and trigger false positives
    564 	writeBit = 0;
    565 	tempValue = 0;
    566 }
    567 
    568 /*
    569 ========================
    570 idBitMsg::WriteBool
    571 ========================
    572 */
    573 ID_INLINE void idBitMsg::WriteBool( bool c ) {
    574 	WriteBits( c, 1 );
    575 }
    576 
    577 /*
    578 ========================
    579 idBitMsg::WriteChar
    580 ========================
    581 */
    582 ID_INLINE void idBitMsg::WriteChar( int8 c ) {
    583 	WriteBits( c, -8 );
    584 }
    585 
    586 /*
    587 ========================
    588 idBitMsg::WriteByte
    589 ========================
    590 */
    591 ID_INLINE void idBitMsg::WriteByte( uint8 c ) {
    592 	WriteBits( c, 8 );
    593 }
    594 
    595 /*
    596 ========================
    597 idBitMsg::WriteShort
    598 ========================
    599 */
    600 ID_INLINE void idBitMsg::WriteShort( int16 c ) {
    601 	WriteBits( c, -16 );
    602 }
    603 
    604 /*
    605 ========================
    606 idBitMsg::WriteUShort
    607 ========================
    608 */
    609 ID_INLINE void idBitMsg::WriteUShort( uint16 c ) {
    610 	WriteBits( c, 16 );
    611 }
    612 
    613 /*
    614 ========================
    615 idBitMsg::WriteLong
    616 ========================
    617 */
    618 ID_INLINE void idBitMsg::WriteLong( int32 c ) {
    619 	WriteBits( c, 32 );
    620 }
    621 
    622 /*
    623 ========================
    624 idBitMsg::WriteLongLong
    625 ========================
    626 */
    627 ID_INLINE void idBitMsg::WriteLongLong( int64 c ) {
    628 	int a = c;
    629 	int b = c >> 32;
    630 	WriteBits( a, 32 );
    631 	WriteBits( b, 32 );
    632 }
    633 
    634 /*
    635 ========================
    636 idBitMsg::WriteFloat
    637 ========================
    638 */
    639 ID_INLINE void idBitMsg::WriteFloat( float f ) {
    640 	WriteBits( *reinterpret_cast<int *>(&f), 32 );
    641 }
    642 
    643 /*
    644 ========================
    645 idBitMsg::WriteFloat
    646 ========================
    647 */
    648 ID_INLINE void idBitMsg::WriteFloat( float f, int exponentBits, int mantissaBits ) {
    649 	int bits = idMath::FloatToBits( f, exponentBits, mantissaBits );
    650 	WriteBits( bits, 1 + exponentBits + mantissaBits );
    651 }
    652 
    653 /*
    654 ========================
    655 idBitMsg::WriteAngle8
    656 ========================
    657 */
    658 ID_INLINE void idBitMsg::WriteAngle8( float f ) {
    659 	WriteByte( ANGLE2BYTE( f ) );
    660 }
    661 
    662 /*
    663 ========================
    664 idBitMsg::WriteAngle16
    665 ========================
    666 */
    667 ID_INLINE void idBitMsg::WriteAngle16( float f ) {
    668 	WriteShort( ANGLE2SHORT(f) );
    669 }
    670 
    671 /*
    672 ========================
    673 idBitMsg::WriteDir
    674 ========================
    675 */
    676 ID_INLINE void idBitMsg::WriteDir( const idVec3 &dir, int numBits ) {
    677 	WriteBits( DirToBits( dir, numBits ), numBits );
    678 }
    679 
    680 /*
    681 ========================
    682 idBitMsg::BeginReading
    683 ========================
    684 */
    685 ID_INLINE void idBitMsg::BeginReading() const {
    686 	readCount = 0;
    687 	readBit = 0;
    688 	
    689 	writeBit = 0;
    690 	tempValue = 0;
    691 }
    692 
    693 /*
    694 ========================
    695 idBitMsg::ReadByteAlign
    696 ========================
    697 */
    698 ID_INLINE void idBitMsg::ReadByteAlign() const {
    699 	readBit = 0;
    700 }
    701 
    702 /*
    703 ========================
    704 idBitMsg::ReadBool
    705 ========================
    706 */
    707 ID_INLINE bool idBitMsg::ReadBool() const {
    708 	return ( ReadBits( 1 ) == 1 ) ? true : false;
    709 }
    710 
    711 /*
    712 ========================
    713 idBitMsg::ReadChar
    714 ========================
    715 */
    716 ID_INLINE int idBitMsg::ReadChar() const {
    717 	return (signed char)ReadBits( -8 );
    718 }
    719 
    720 /*
    721 ========================
    722 idBitMsg::ReadByte
    723 ========================
    724 */
    725 ID_INLINE int idBitMsg::ReadByte() const {
    726 	return (unsigned char)ReadBits( 8 );
    727 }
    728 
    729 /*
    730 ========================
    731 idBitMsg::ReadShort
    732 ========================
    733 */
    734 ID_INLINE int idBitMsg::ReadShort() const {
    735 	return (short)ReadBits( -16 );
    736 }
    737 
    738 /*
    739 ========================
    740 idBitMsg::ReadUShort
    741 ========================
    742 */
    743 ID_INLINE int idBitMsg::ReadUShort() const {
    744 	return (unsigned short)ReadBits( 16 );
    745 }
    746 
    747 /*
    748 ========================
    749 idBitMsg::ReadLong
    750 ========================
    751 */
    752 ID_INLINE int idBitMsg::ReadLong() const {
    753 	return ReadBits( 32 );
    754 }
    755 
    756 /*
    757 ========================
    758 idBitMsg::ReadLongLong
    759 ========================
    760 */
    761 ID_INLINE int64 idBitMsg::ReadLongLong() const {
    762 	int64 a = ReadBits( 32 );
    763 	int64 b = ReadBits( 32 );
    764 	int64 c = ( 0x00000000ffffffff & a ) | ( b << 32 );
    765 	return c;
    766 }
    767 
    768 /*
    769 ========================
    770 idBitMsg::ReadFloat
    771 ========================
    772 */
    773 ID_INLINE float idBitMsg::ReadFloat() const {
    774 	float value;
    775 	*reinterpret_cast<int *>(&value) = ReadBits( 32 );
    776 	return value;
    777 }
    778 
    779 /*
    780 ========================
    781 idBitMsg::ReadFloat
    782 ========================
    783 */
    784 ID_INLINE float idBitMsg::ReadFloat( int exponentBits, int mantissaBits ) const {
    785 	int bits = ReadBits( 1 + exponentBits + mantissaBits );
    786 	return idMath::BitsToFloat( bits, exponentBits, mantissaBits );
    787 }
    788 
    789 /*
    790 ========================
    791 idBitMsg::ReadAngle8
    792 ========================
    793 */
    794 ID_INLINE float idBitMsg::ReadAngle8() const {
    795 	return BYTE2ANGLE( ReadByte() );
    796 }
    797 
    798 /*
    799 ========================
    800 idBitMsg::ReadAngle16
    801 ========================
    802 */
    803 ID_INLINE float idBitMsg::ReadAngle16() const {
    804 	return SHORT2ANGLE( ReadShort() );
    805 }
    806 
    807 /*
    808 ========================
    809 idBitMsg::ReadDir
    810 ========================
    811 */
    812 ID_INLINE idVec3 idBitMsg::ReadDir( int numBits ) const {
    813 	return BitsToDir( ReadBits( numBits ), numBits );
    814 }
    815 
    816 /*
    817 ========================
    818 idBitMsg::WriteQuantizedFloat
    819 ========================
    820 */
    821 template< int _max_, int _numBits_ >
    822 ID_INLINE void idBitMsg::WriteQuantizedFloat( float value ) {
    823 	enum { storeMax = ( 1 << ( _numBits_ - 1 ) ) - 1 };
    824 	if ( _max_ > storeMax ) {
    825 		// Scaling down (scale should be < 1)
    826 		const float scale = (float)storeMax / (float)_max_;
    827 		WriteBits( idMath::ClampInt( -storeMax, storeMax, idMath::Ftoi( value * scale ) ), -_numBits_ );	
    828 	} else {
    829 		// Scaling up (scale should be >= 1) (Preserve whole numbers when possible)
    830 		enum { scale = storeMax / _max_ };
    831 		WriteBits( idMath::ClampInt( -storeMax, storeMax, idMath::Ftoi( value * scale ) ), -_numBits_ );	
    832 	}
    833 }
    834 
    835 /*
    836 ========================
    837 idBitMsg::WriteQuantizedUFloat
    838 ========================
    839 */
    840 template< int _max_, int _numBits_ >
    841 ID_INLINE void idBitMsg::WriteQuantizedUFloat( float value ) {
    842 	enum { storeMax = ( 1 << _numBits_ ) - 1 };
    843 	if ( _max_ > storeMax ) {
    844 		// Scaling down (scale should be < 1)
    845 		const float scale = (float)storeMax / (float)_max_;
    846 		WriteBits( idMath::ClampInt( 0, storeMax, idMath::Ftoi( value * scale ) ), _numBits_ );	
    847 	} else {
    848 		// Scaling up (scale should be >= 1) (Preserve whole numbers when possible)
    849 		enum { scale = storeMax / _max_ };
    850 		WriteBits( idMath::ClampInt( 0, storeMax, idMath::Ftoi( value * scale ) ), _numBits_ );	
    851 	}
    852 }
    853 
    854 /*
    855 ========================
    856 idBitMsg::ReadQuantizedFloat
    857 ========================
    858 */
    859 template< int _max_, int _numBits_ >
    860 ID_INLINE float idBitMsg::ReadQuantizedFloat() const {
    861 	enum { storeMax = ( 1 << ( _numBits_ - 1 ) ) - 1 };
    862 	if ( _max_ > storeMax ) {
    863 		// Scaling down (scale should be < 1)
    864 		const float invScale = (float)_max_ / (float)storeMax;
    865 		return (float)ReadBits( -_numBits_ ) * invScale;
    866 	} else {
    867 		// Scaling up (scale should be >= 1) (Preserve whole numbers when possible)
    868 		// Scale will be a whole number.  
    869 		// We use a float to get rid of (potential divide by zero) which is handled above, but the compiler is dumb
    870 		const float scale = storeMax / _max_;
    871 		const float invScale = 1.0f / scale;
    872 		return (float)ReadBits( -_numBits_ ) * invScale;
    873 	}
    874 }
    875 
    876 /*
    877 ========================
    878 idBitMsg::ReadQuantizedUFloat
    879 ========================
    880 */
    881 template< int _max_, int _numBits_ >
    882 float idBitMsg::ReadQuantizedUFloat() const {
    883 	enum { storeMax = ( 1 << _numBits_ ) - 1 };
    884 	if ( _max_ > storeMax ) {
    885 		// Scaling down (scale should be < 1)
    886 		const float invScale = (float)_max_ / (float)storeMax;
    887 		return (float)ReadBits( _numBits_ ) * invScale;
    888 	} else {
    889 		// Scaling up (scale should be >= 1) (Preserve whole numbers when possible)
    890 		// Scale will be a whole number.  
    891 		// We use a float to get rid of (potential divide by zero) which is handled above, but the compiler is dumb
    892 		const float scale = storeMax / _max_;	
    893 		const float invScale = 1.0f / scale;
    894 		return (float)ReadBits( _numBits_ ) * invScale;
    895 	}
    896 }
    897 
    898 /*
    899 ================
    900 WriteFloatArray
    901 Writes all the values from the array to the bit message.
    902 ================
    903 */
    904 template< class _arrayType_ >
    905 void WriteFloatArray( idBitMsg & message, const _arrayType_ & sourceArray ) {
    906 	for( int i = 0; i < idTupleSize< _arrayType_ >::value; ++i ) {
    907 		message.WriteFloat( sourceArray[i] );
    908 	}
    909 }
    910 
    911 /*
    912 ================
    913 WriteFloatArrayDelta
    914 Writes _num_ values from the array to the bit message.
    915 ================
    916 */
    917 template< class _arrayType_ >
    918 void WriteDeltaFloatArray( idBitMsg & message, const _arrayType_ & oldArray, const _arrayType_ & newArray ) {
    919 	for( int i = 0; i < idTupleSize< _arrayType_ >::value; ++i ) {
    920 		message.WriteDeltaFloat( oldArray[i], newArray[i] );
    921 	}
    922 }
    923 
    924 /*
    925 ================
    926 ReadFloatArray
    927 Reads _num_ values from the array to the bit message.
    928 ================
    929 */
    930 template< class _arrayType_ >
    931 _arrayType_ ReadFloatArray( const idBitMsg & message ) {
    932 	_arrayType_ result;
    933 
    934 	for( int i = 0; i < idTupleSize< _arrayType_ >::value; ++i ) {
    935 		result[i] = message.ReadFloat();
    936 	}
    937 
    938 	return result;
    939 }
    940 
    941 /*
    942 ================
    943 ReadDeltaFloatArray
    944 Reads _num_ values from the array to the bit message.
    945 ================
    946 */
    947 template< class _arrayType_ >
    948 _arrayType_ ReadDeltaFloatArray( const idBitMsg & message, const _arrayType_ & oldArray ) {
    949 	_arrayType_ result;
    950 
    951 	for( int i = 0; i < idTupleSize< _arrayType_ >::value; ++i ) {
    952 		result[i] = message.ReadDeltaFloat( oldArray[i] );
    953 	}
    954 
    955 	return result;
    956 }
    957 
    958 #endif /* !__BITMSG_H__ */