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__ */