![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 #if defined(_MSC_VER) && _MSC_VER < 1299 // VC6 doesn't support template specialization 00011 #include "BitStream_NoTemplate.h" 00012 #else 00013 00014 #ifndef __BITSTREAM_H 00015 #define __BITSTREAM_H 00016 00017 #include "RakMemoryOverride.h" 00018 #include "RakNetDefines.h" 00019 #include "Export.h" 00020 #include "RakNetTypes.h" 00021 #include "RakString.h" 00022 #include "RakWString.h" 00023 #include "RakAssert.h" 00024 #include <math.h> 00025 #include <float.h> 00026 00027 #ifdef _MSC_VER 00028 #pragma warning( push ) 00029 #endif 00030 00031 // MSWin uses _copysign, others use copysign... 00032 #ifndef _WIN32 00033 #define _copysign copysign 00034 #endif 00035 00036 namespace RakNet 00037 { 00040 class RAK_DLL_EXPORT BitStream 00041 { 00042 00043 public: 00044 // GetInstance() and DestroyInstance(instance*) 00045 STATIC_FACTORY_DECLARATIONS(BitStream) 00046 00047 00048 BitStream(); 00049 00054 BitStream( const unsigned int initialBytesToAllocate ); 00055 00066 BitStream( unsigned char* _data, const unsigned int lengthInBytes, bool _copyData ); 00067 00068 // Destructor 00069 ~BitStream(); 00070 00072 void Reset( void ); 00073 00079 template <class templateType> 00080 bool Serialize(bool writeToBitstream, templateType &inOutTemplateVar); 00081 00089 template <class templateType> 00090 bool SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue); 00091 00096 template <class templateType> 00097 bool SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue); 00098 00107 template <class templateType> 00108 bool SerializeCompressed(bool writeToBitstream, templateType &inOutTemplateVar); 00109 00120 template <class templateType> 00121 bool SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue); 00122 00125 template <class templateType> 00126 bool SerializeCompressedDelta(bool writeToBitstream, templateType &inOutTemplateVar); 00127 00133 bool Serialize(bool writeToBitstream, char* inOutByteArray, const unsigned int numberOfBytes ); 00134 00140 bool SerializeFloat16(bool writeToBitstream, float &inOutFloat, float floatMin, float floatMax); 00141 00147 template <class serializationType, class sourceType > 00148 bool SerializeCasted( bool writeToBitstream, sourceType &value ); 00149 00158 template <class templateType, class rangeType> 00159 bool SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange=false ); 00161 template <class templateType, class rangeType> 00162 bool SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange=false ); 00163 00172 template <class templateType> // templateType for this function must be a float or double 00173 bool SerializeNormVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z ); 00174 00182 template <class templateType> // templateType for this function must be a float or double 00183 bool SerializeVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z ); 00184 00192 template <class templateType> // templateType for this function must be a float or double 00193 bool SerializeNormQuat(bool writeToBitstream, templateType &w, templateType &x, templateType &y, templateType &z); 00194 00199 template <class templateType> // templateType for this function must be a float or double 00200 bool SerializeOrthMatrix( 00201 bool writeToBitstream, 00202 templateType &m00, templateType &m01, templateType &m02, 00203 templateType &m10, templateType &m11, templateType &m12, 00204 templateType &m20, templateType &m21, templateType &m22 ); 00205 00217 bool SerializeBits(bool writeToBitstream, unsigned char* inOutByteArray, const BitSize_t numberOfBitsToSerialize, const bool rightAlignedBits = true ); 00218 00222 template <class templateType> 00223 void Write(const templateType &inTemplateVar); 00224 00228 template <class templateType> 00229 void WritePtr(templateType *inTemplateVar); 00230 00236 template <class templateType> 00237 void WriteDelta(const templateType ¤tValue, const templateType &lastValue); 00238 00241 template <class templateType> 00242 void WriteDelta(const templateType ¤tValue); 00243 00250 template <class templateType> 00251 void WriteCompressed(const templateType &inTemplateVar); 00252 00261 template <class templateType> 00262 void WriteCompressedDelta(const templateType ¤tValue, const templateType &lastValue); 00263 00265 template <class templateType> 00266 void WriteCompressedDelta(const templateType ¤tValue); 00267 00272 template <class templateType> 00273 bool Read(templateType &outTemplateVar); 00274 00281 template <class templateType> 00282 bool ReadDelta(templateType &outTemplateVar); 00283 00291 template <class templateType> 00292 bool ReadCompressed(templateType &outTemplateVar); 00293 00304 template <class templateType> 00305 bool ReadCompressedDelta(templateType &outTemplateVar); 00306 00311 bool Read( BitStream *bitStream, BitSize_t numberOfBits ); 00312 bool Read( BitStream *bitStream ); 00313 bool Read( BitStream &bitStream, BitSize_t numberOfBits ); 00314 bool Read( BitStream &bitStream ); 00315 00319 void Write( const char* inputByteArray, const unsigned int numberOfBytes ); 00320 00324 void Write( BitStream *bitStream, BitSize_t numberOfBits ); 00325 void Write( BitStream *bitStream ); 00326 void Write( BitStream &bitStream, BitSize_t numberOfBits ); 00327 void Write( BitStream &bitStream );\ 00328 00333 void WriteFloat16( float x, float floatMin, float floatMax ); 00334 00339 template <class serializationType, class sourceType > 00340 void WriteCasted( const sourceType &value ); 00341 00349 template <class templateType, class rangeType> 00350 void WriteBitsFromIntegerRange( const templateType value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange=false ); 00352 template <class templateType, class rangeType> 00353 void WriteBitsFromIntegerRange( const templateType value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange=false ); 00354 00361 template <class templateType> // templateType for this function must be a float or double 00362 void WriteNormVector( templateType x, templateType y, templateType z ); 00363 00370 template <class templateType> // templateType for this function must be a float or double 00371 void WriteVector( templateType x, templateType y, templateType z ); 00372 00378 template <class templateType> // templateType for this function must be a float or double 00379 void WriteNormQuat( templateType w, templateType x, templateType y, templateType z); 00380 00384 template <class templateType> // templateType for this function must be a float or double 00385 void WriteOrthMatrix( 00386 templateType m00, templateType m01, templateType m02, 00387 templateType m10, templateType m11, templateType m12, 00388 templateType m20, templateType m21, templateType m22 ); 00389 00395 bool Read( char* output, const unsigned int numberOfBytes ); 00396 00401 bool ReadFloat16( float &outFloat, float floatMin, float floatMax ); 00402 00407 template <class serializationType, class sourceType > 00408 bool ReadCasted( sourceType &value ); 00409 00417 template <class templateType, class rangeType> 00418 bool ReadBitsFromIntegerRange( templateType &value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange=false ); 00420 template <class templateType, class rangeType> 00421 bool ReadBitsFromIntegerRange( templateType &value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange=false ); 00422 00430 template <class templateType> // templateType for this function must be a float or double 00431 bool ReadNormVector( templateType &x, templateType &y, templateType &z ); 00432 00440 template <class templateType> // templateType for this function must be a float or double 00441 bool ReadVector( templateType &x, templateType &y, templateType &z ); 00442 00449 template <class templateType> // templateType for this function must be a float or double 00450 bool ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z); 00451 00456 template <class templateType> // templateType for this function must be a float or double 00457 bool ReadOrthMatrix( 00458 templateType &m00, templateType &m01, templateType &m02, 00459 templateType &m10, templateType &m11, templateType &m12, 00460 templateType &m20, templateType &m21, templateType &m22 ); 00461 00463 void ResetReadPointer( void ); 00464 00466 void ResetWritePointer( void ); 00467 00470 void AssertStreamEmpty( void ); 00471 00473 void PrintBits( char *out ) const; 00474 void PrintBits( void ) const; 00475 void PrintHex( char *out ) const; 00476 void PrintHex( void ) const; 00477 00480 void IgnoreBits( const BitSize_t numberOfBits ); 00481 00484 void IgnoreBytes( const unsigned int numberOfBytes ); 00485 00491 void SetWriteOffset( const BitSize_t offset ); 00492 00494 inline BitSize_t GetNumberOfBitsUsed( void ) const {return GetWriteOffset();} 00495 inline BitSize_t GetWriteOffset( void ) const {return numberOfBitsUsed;} 00496 00498 inline BitSize_t GetNumberOfBytesUsed( void ) const {return BITS_TO_BYTES( numberOfBitsUsed );} 00499 00501 inline BitSize_t GetReadOffset( void ) const {return readOffset;} 00502 00504 void SetReadOffset( const BitSize_t newReadOffset ) {readOffset=newReadOffset;} 00505 00507 inline BitSize_t GetNumberOfUnreadBits( void ) const {return numberOfBitsUsed - readOffset;} 00508 00513 BitSize_t CopyData( unsigned char** _data ) const; 00514 00517 void SetData( unsigned char *inByteArray ); 00518 00522 inline unsigned char* GetData( void ) const {return data;} 00523 00533 void WriteBits( const unsigned char* inByteArray, BitSize_t numberOfBitsToWrite, const bool rightAlignedBits = true ); 00534 00542 void WriteAlignedBytes( const unsigned char *inByteArray, const unsigned int numberOfBytesToWrite ); 00543 00544 // Endian swap bytes already in the bitstream 00545 void EndianSwapBytes( int byteOffset, int length ); 00546 00551 void WriteAlignedBytesSafe( const char *inByteArray, const unsigned int inputLength, const unsigned int maxBytesToWrite ); 00552 00560 bool ReadAlignedBytes( unsigned char *inOutByteArray, const unsigned int numberOfBytesToRead ); 00561 00566 bool ReadAlignedBytesSafe( char *inOutByteArray, int &inputLength, const int maxBytesToRead ); 00567 bool ReadAlignedBytesSafe( char *inOutByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead ); 00568 00572 bool ReadAlignedBytesSafeAlloc( char **outByteArray, int &inputLength, const unsigned int maxBytesToRead ); 00573 bool ReadAlignedBytesSafeAlloc( char **outByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead ); 00574 00580 inline void AlignWriteToByteBoundary( void ) {numberOfBitsUsed += 8 - ( (( numberOfBitsUsed - 1 ) & 7) + 1 );} 00581 00587 inline void AlignReadToByteBoundary( void ) {readOffset += 8 - ( (( readOffset - 1 ) & 7 ) + 1 );} 00588 00597 bool ReadBits( unsigned char *inOutByteArray, BitSize_t numberOfBitsToRead, const bool alignBitsToRight = true ); 00598 00600 void Write0( void ); 00601 00603 void Write1( void ); 00604 00606 bool ReadBit( void ); 00607 00610 void AssertCopyData( void ); 00611 00615 void SetNumberOfBitsAllocated( const BitSize_t lengthInBits ); 00616 00618 void AddBitsAndReallocate( const BitSize_t numberOfBitsToWrite ); 00619 00622 BitSize_t GetNumberOfBitsAllocated(void) const; 00623 00625 bool Read(char *varString); 00626 bool Read(unsigned char *varString); 00627 00629 void PadWithZeroToByteLength( unsigned int bytes ); 00630 00633 static int NumberOfLeadingZeroes( uint8_t x ); 00634 static int NumberOfLeadingZeroes( uint16_t x ); 00635 static int NumberOfLeadingZeroes( uint32_t x ); 00636 static int NumberOfLeadingZeroes( uint64_t x ); 00637 static int NumberOfLeadingZeroes( int8_t x ); 00638 static int NumberOfLeadingZeroes( int16_t x ); 00639 static int NumberOfLeadingZeroes( int32_t x ); 00640 static int NumberOfLeadingZeroes( int64_t x ); 00641 00643 void WriteAlignedVar8(const char *inByteArray); 00645 bool ReadAlignedVar8(char *inOutByteArray); 00647 void WriteAlignedVar16(const char *inByteArray); 00649 bool ReadAlignedVar16(char *inOutByteArray); 00651 void WriteAlignedVar32(const char *inByteArray); 00653 bool ReadAlignedVar32(char *inOutByteArray); 00654 00655 inline void Write(const char * const inStringVar) 00656 { 00657 RakString::Serialize(inStringVar, this); 00658 } 00659 inline void Write(const wchar_t * const inStringVar) 00660 { 00661 RakWString::Serialize(inStringVar, this); 00662 } 00663 inline void Write(const unsigned char * const inTemplateVar) 00664 { 00665 Write((const char*)inTemplateVar); 00666 } 00667 inline void Write(char * const inTemplateVar) 00668 { 00669 Write((const char*)inTemplateVar); 00670 } 00671 inline void Write(unsigned char * const inTemplateVar) 00672 { 00673 Write((const char*)inTemplateVar); 00674 } 00675 inline void WriteCompressed(const char * const inStringVar) 00676 { 00677 RakString::SerializeCompressed(inStringVar,this,0,false); 00678 } 00679 inline void WriteCompressed(const wchar_t * const inStringVar) 00680 { 00681 RakWString::Serialize(inStringVar,this); 00682 } 00683 inline void WriteCompressed(const unsigned char * const inTemplateVar) 00684 { 00685 WriteCompressed((const char*) inTemplateVar); 00686 } 00687 inline void WriteCompressed(char * const inTemplateVar) 00688 { 00689 WriteCompressed((const char*) inTemplateVar); 00690 } 00691 inline void WriteCompressed(unsigned char * const inTemplateVar) 00692 { 00693 WriteCompressed((const char*) inTemplateVar); 00694 } 00695 00697 // Used for VC7 00698 #if defined(_MSC_VER) && _MSC_VER == 1300 00699 00700 00701 template <> 00702 void Write(const bool &var); 00703 00706 template <> 00707 void Write(const SystemAddress &var); 00708 00711 template <> 00712 void Write(const uint24_t &var); 00713 00716 template <> 00717 void Write(const RakNetGuid &var); 00718 00721 template <> 00722 void Write(const char* const &var); 00723 template <> 00724 void Write(const unsigned char* const &var); 00725 template <> 00726 void Write(char* const &var); 00727 template <> 00728 void Write(unsigned char* const &var); 00729 template <> 00730 void Write(const RakString &var); 00731 template <> 00732 void Write(const RakWString &var); 00733 00739 template <> 00740 void WriteDelta(const SystemAddress ¤tValue, const SystemAddress &lastValue); 00741 00742 template <> 00743 void WriteDelta(const uint24_t ¤tValue, const uint24_t &lastValue); 00744 00745 template <> 00746 void WriteDelta(const RakNetGUID ¤tValue, const RakNetGUID &lastValue); 00747 00752 template <> 00753 void WriteDelta(const bool ¤tValue, const bool &lastValue); 00754 00755 template <> 00756 void WriteCompressed(const SystemAddress &var); 00757 00758 template <> 00759 void WriteCompressed(const uint24_t &var); 00760 00761 template <> 00762 void WriteCompressed(const RakNetGUID &var); 00763 00764 template <> 00765 void WriteCompressed(const bool &var); 00766 00768 template <> 00769 void WriteCompressed(const float &var); 00770 00772 template <> 00773 void WriteCompressed(const double &var); 00774 00776 template <> 00777 void WriteCompressed(const char* var); 00778 template <> 00779 void WriteCompressed(const unsigned char* var); 00780 template <> 00781 void WriteCompressed(char* var); 00782 template <> 00783 void WriteCompressed(unsigned char* var); 00784 template <> 00785 void WriteCompressed(const RakString &var); 00786 template <> 00787 void WriteCompressed(const RakWString &var); 00788 00793 template <> 00794 void WriteCompressedDelta(const bool ¤tValue, const bool &lastValue); 00795 00798 template <> 00799 void WriteCompressedDelta(const bool ¤tValue); 00800 00804 template <> 00805 bool Read(bool &var); 00806 00810 template <> 00811 bool Read(SystemAddress &var); 00812 00813 template <> 00814 bool Read(uint24_t &var); 00815 00816 template <> 00817 bool Read(RakNetGUID &var); 00818 00822 template <> 00823 bool Read(char *&var); 00824 template <> 00825 bool Read(wchar_t *&var); 00826 template <> 00827 bool Read(unsigned char *&var); 00828 template <> 00829 bool Read(RakString &var); 00830 template <> 00831 bool Read(RakWString &var); 00832 00836 template <> 00837 bool ReadDelta(bool &var); 00838 00839 template <> 00840 bool ReadCompressed(SystemAddress &var); 00841 00842 template <> 00843 bool ReadCompressed(uint24_t &var); 00844 00845 template <> 00846 bool ReadCompressed(RakNetGUID &var); 00847 00848 template <> 00849 bool ReadCompressed(bool &var); 00850 00851 template <> 00852 bool ReadCompressed(float &var); 00853 00856 template <> 00857 bool ReadCompressed(double &var); 00858 00859 template <> 00860 bool ReadCompressed(char* &var); 00861 template <> 00862 bool ReadCompressed(wchar_t* &var); 00863 template <> 00864 bool ReadCompressed(unsigned char *&var); 00865 template <> 00866 bool ReadCompressed(RakString &var); 00867 template <> 00868 bool ReadCompressed(RakWString &var); 00869 00873 template <> 00874 bool ReadCompressedDelta(bool &var); 00875 #endif 00876 00877 inline static bool DoEndianSwap(void) { 00878 #ifndef __BITSTREAM_NATIVE_END 00879 return IsNetworkOrder()==false; 00880 #else 00881 return false; 00882 #endif 00883 } 00884 inline static bool IsBigEndian(void) 00885 { 00886 return IsNetworkOrder(); 00887 } 00888 inline static bool IsNetworkOrder(void) {static const bool r = IsNetworkOrderInternal(); return r;} 00889 // Not inline, won't compile on PC due to winsock include errors 00890 static bool IsNetworkOrderInternal(void); 00891 static void ReverseBytes(unsigned char *inByteArray, unsigned char *inOutByteArray, const unsigned int length); 00892 static void ReverseBytesInPlace(unsigned char *inOutData,const unsigned int length); 00893 00894 private: 00895 00896 BitStream( const BitStream &invalid) { 00897 (void) invalid; 00898 RakAssert(0); 00899 } 00900 00902 void WriteCompressed( const unsigned char* inByteArray, const unsigned int size, const bool unsignedData ); 00903 00905 bool ReadCompressed( unsigned char* inOutByteArray, const unsigned int size, const bool unsignedData ); 00906 00907 00908 BitSize_t numberOfBitsUsed; 00909 00910 BitSize_t numberOfBitsAllocated; 00911 00912 BitSize_t readOffset; 00913 00914 unsigned char *data; 00915 00917 bool copyData; 00918 00920 unsigned char stackData[BITSTREAM_STACK_ALLOCATION_SIZE]; 00921 }; 00922 00923 template <class templateType> 00924 inline bool BitStream::Serialize(bool writeToBitstream, templateType &inOutTemplateVar) 00925 { 00926 if (writeToBitstream) 00927 Write(inOutTemplateVar); 00928 else 00929 return Read(inOutTemplateVar); 00930 return true; 00931 } 00932 00933 template <class templateType> 00934 inline bool BitStream::SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue) 00935 { 00936 if (writeToBitstream) 00937 WriteDelta(inOutCurrentValue, lastValue); 00938 else 00939 return ReadDelta(inOutCurrentValue); 00940 return true; 00941 } 00942 00943 template <class templateType> 00944 inline bool BitStream::SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue) 00945 { 00946 if (writeToBitstream) 00947 WriteDelta(inOutCurrentValue); 00948 else 00949 return ReadDelta(inOutCurrentValue); 00950 return true; 00951 } 00952 00953 template <class templateType> 00954 inline bool BitStream::SerializeCompressed(bool writeToBitstream, templateType &inOutTemplateVar) 00955 { 00956 if (writeToBitstream) 00957 WriteCompressed(inOutTemplateVar); 00958 else 00959 return ReadCompressed(inOutTemplateVar); 00960 return true; 00961 } 00962 00963 template <class templateType> 00964 inline bool BitStream::SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue) 00965 { 00966 if (writeToBitstream) 00967 WriteCompressedDelta(inOutCurrentValue,lastValue); 00968 else 00969 return ReadCompressedDelta(inOutCurrentValue); 00970 return true; 00971 } 00972 //Stoppedhere 00973 template <class templateType> 00974 inline bool BitStream::SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue) 00975 { 00976 if (writeToBitstream) 00977 WriteCompressedDelta(inOutCurrentValue); 00978 else 00979 return ReadCompressedDelta(inOutCurrentValue); 00980 return true; 00981 } 00982 00983 inline bool BitStream::Serialize(bool writeToBitstream, char* inOutByteArray, const unsigned int numberOfBytes ) 00984 { 00985 if (writeToBitstream) 00986 Write(inOutByteArray, numberOfBytes); 00987 else 00988 return Read(inOutByteArray, numberOfBytes); 00989 return true; 00990 } 00991 00992 template <class serializationType, class sourceType > 00993 bool BitStream::SerializeCasted( bool writeToBitstream, sourceType &value ) 00994 { 00995 if (writeToBitstream) WriteCasted<serializationType>(value); 00996 else return ReadCasted<serializationType>(value); 00997 return true; 00998 } 00999 01000 template <class templateType, class rangeType> 01001 bool BitStream::SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange ) 01002 { 01003 static int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum)); 01004 return SerializeBitsFromIntegerRange(writeToBitstream,value,minimum,maximum,requiredBits,allowOutsideRange); 01005 } 01006 template <class templateType, class rangeType> 01007 bool BitStream::SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange ) 01008 { 01009 if (writeToBitstream) WriteBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange); 01010 else return ReadBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange); 01011 return true; 01012 } 01013 01014 template <class templateType> 01015 inline bool BitStream::SerializeNormVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z ) 01016 { 01017 if (writeToBitstream) 01018 WriteNormVector(x,y,z); 01019 else 01020 return ReadNormVector(x,y,z); 01021 return true; 01022 } 01023 01024 template <class templateType> 01025 inline bool BitStream::SerializeVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z ) 01026 { 01027 if (writeToBitstream) 01028 WriteVector(x,y,z); 01029 else 01030 return ReadVector(x,y,z); 01031 return true; 01032 } 01033 01034 template <class templateType> 01035 inline bool BitStream::SerializeNormQuat(bool writeToBitstream, templateType &w, templateType &x, templateType &y, templateType &z) 01036 { 01037 if (writeToBitstream) 01038 WriteNormQuat(w,x,y,z); 01039 else 01040 return ReadNormQuat(w,x,y,z); 01041 return true; 01042 } 01043 01044 template <class templateType> 01045 inline bool BitStream::SerializeOrthMatrix( 01046 bool writeToBitstream, 01047 templateType &m00, templateType &m01, templateType &m02, 01048 templateType &m10, templateType &m11, templateType &m12, 01049 templateType &m20, templateType &m21, templateType &m22 ) 01050 { 01051 if (writeToBitstream) 01052 WriteOrthMatrix(m00,m01,m02,m10,m11,m12,m20,m21,m22); 01053 else 01054 return ReadOrthMatrix(m00,m01,m02,m10,m11,m12,m20,m21,m22); 01055 return true; 01056 } 01057 01058 inline bool BitStream::SerializeBits(bool writeToBitstream, unsigned char* inOutByteArray, const BitSize_t numberOfBitsToSerialize, const bool rightAlignedBits ) 01059 { 01060 if (writeToBitstream) 01061 WriteBits(inOutByteArray,numberOfBitsToSerialize,rightAlignedBits); 01062 else 01063 return ReadBits(inOutByteArray,numberOfBitsToSerialize,rightAlignedBits); 01064 return true; 01065 } 01066 01067 template <class templateType> 01068 inline void BitStream::Write(const templateType &inTemplateVar) 01069 { 01070 #ifdef _MSC_VER 01071 #pragma warning(disable:4127) // conditional expression is constant 01072 #endif 01073 if (sizeof(inTemplateVar)==1) 01074 WriteBits( ( unsigned char* ) & inTemplateVar, sizeof( templateType ) * 8, true ); 01075 else 01076 { 01077 #ifndef __BITSTREAM_NATIVE_END 01078 if (DoEndianSwap()) 01079 { 01080 unsigned char output[sizeof(templateType)]; 01081 ReverseBytes((unsigned char*)&inTemplateVar, output, sizeof(templateType)); 01082 WriteBits( ( unsigned char* ) output, sizeof(templateType) * 8, true ); 01083 } 01084 else 01085 #endif 01086 WriteBits( ( unsigned char* ) & inTemplateVar, sizeof(templateType) * 8, true ); 01087 } 01088 } 01089 01090 template <class templateType> 01091 inline void BitStream::WritePtr(templateType *inTemplateVar) 01092 { 01093 #ifdef _MSC_VER 01094 #pragma warning(disable:4127) // conditional expression is constant 01095 #endif 01096 if (sizeof(templateType)==1) 01097 WriteBits( ( unsigned char* ) inTemplateVar, sizeof( templateType ) * 8, true ); 01098 else 01099 { 01100 #ifndef __BITSTREAM_NATIVE_END 01101 if (DoEndianSwap()) 01102 { 01103 unsigned char output[sizeof(templateType)]; 01104 ReverseBytes((unsigned char*) inTemplateVar, output, sizeof(templateType)); 01105 WriteBits( ( unsigned char* ) output, sizeof(templateType) * 8, true ); 01106 } 01107 else 01108 #endif 01109 WriteBits( ( unsigned char* ) inTemplateVar, sizeof(templateType) * 8, true ); 01110 } 01111 } 01112 01115 template <> 01116 inline void BitStream::Write(const bool &inTemplateVar) 01117 { 01118 if ( inTemplateVar ) 01119 Write1(); 01120 else 01121 Write0(); 01122 } 01123 01124 01127 template <> 01128 inline void BitStream::Write(const SystemAddress &inTemplateVar) 01129 { 01130 Write(inTemplateVar.GetIPVersion()); 01131 if (inTemplateVar.GetIPVersion()==4) 01132 { 01133 // Hide the address so routers don't modify it 01134 SystemAddress var2=inTemplateVar; 01135 uint32_t binaryAddress=~inTemplateVar.address.addr4.sin_addr.s_addr; 01136 // Don't endian swap the address or port 01137 WriteBits((unsigned char*)&binaryAddress, sizeof(binaryAddress)*8, true); 01138 unsigned short p = var2.GetPortNetworkOrder(); 01139 WriteBits((unsigned char*)&p, sizeof(unsigned short)*8, true); 01140 } 01141 else 01142 { 01143 #if RAKNET_SUPPORT_IPV6==1 01144 // Don't endian swap 01145 WriteBits((const unsigned char*) &inTemplateVar.address.addr6, sizeof(inTemplateVar.address.addr6)*8, true); 01146 #endif 01147 } 01148 } 01149 01150 template <> 01151 inline void BitStream::Write(const uint24_t &inTemplateVar) 01152 { 01153 AlignWriteToByteBoundary(); 01154 AddBitsAndReallocate(3*8); 01155 01156 if (IsBigEndian()==false) 01157 { 01158 data[( numberOfBitsUsed >> 3 ) + 0] = ((char *)&inTemplateVar.val)[0]; 01159 data[( numberOfBitsUsed >> 3 ) + 1] = ((char *)&inTemplateVar.val)[1]; 01160 data[( numberOfBitsUsed >> 3 ) + 2] = ((char *)&inTemplateVar.val)[2]; 01161 } 01162 else 01163 { 01164 data[( numberOfBitsUsed >> 3 ) + 0] = ((char *)&inTemplateVar.val)[3]; 01165 data[( numberOfBitsUsed >> 3 ) + 1] = ((char *)&inTemplateVar.val)[2]; 01166 data[( numberOfBitsUsed >> 3 ) + 2] = ((char *)&inTemplateVar.val)[1]; 01167 } 01168 01169 numberOfBitsUsed+=3*8; 01170 } 01171 01172 template <> 01173 inline void BitStream::Write(const RakNetGUID &inTemplateVar) 01174 { 01175 Write(inTemplateVar.g); 01176 } 01177 01180 template <> 01181 inline void BitStream::Write(const RakString &inTemplateVar) 01182 { 01183 inTemplateVar.Serialize(this); 01184 } 01185 template <> 01186 inline void BitStream::Write(const RakWString &inTemplateVar) 01187 { 01188 inTemplateVar.Serialize(this); 01189 } 01190 template <> 01191 inline void BitStream::Write(const char * const &inStringVar) 01192 { 01193 RakString::Serialize(inStringVar, this); 01194 } 01195 template <> 01196 inline void BitStream::Write(const wchar_t * const &inStringVar) 01197 { 01198 RakWString::Serialize(inStringVar, this); 01199 } 01200 template <> 01201 inline void BitStream::Write(const unsigned char * const &inTemplateVar) 01202 { 01203 Write((const char*)inTemplateVar); 01204 } 01205 template <> 01206 inline void BitStream::Write(char * const &inTemplateVar) 01207 { 01208 Write((const char*)inTemplateVar); 01209 } 01210 template <> 01211 inline void BitStream::Write(unsigned char * const &inTemplateVar) 01212 { 01213 Write((const char*)inTemplateVar); 01214 } 01215 01221 template <class templateType> 01222 inline void BitStream::WriteDelta(const templateType ¤tValue, const templateType &lastValue) 01223 { 01224 if (currentValue==lastValue) 01225 { 01226 Write(false); 01227 } 01228 else 01229 { 01230 Write(true); 01231 Write(currentValue); 01232 } 01233 } 01234 01238 template <> 01239 inline void BitStream::WriteDelta(const bool ¤tValue, const bool &lastValue) 01240 { 01241 (void) lastValue; 01242 01243 Write(currentValue); 01244 } 01245 01248 template <class templateType> 01249 inline void BitStream::WriteDelta(const templateType ¤tValue) 01250 { 01251 Write(true); 01252 Write(currentValue); 01253 } 01254 01261 template <class templateType> 01262 inline void BitStream::WriteCompressed(const templateType &inTemplateVar) 01263 { 01264 #ifdef _MSC_VER 01265 #pragma warning(disable:4127) // conditional expression is constant 01266 #endif 01267 if (sizeof(inTemplateVar)==1) 01268 WriteCompressed( ( unsigned char* ) & inTemplateVar, sizeof( templateType ) * 8, true ); 01269 else 01270 { 01271 #ifndef __BITSTREAM_NATIVE_END 01272 #ifdef _MSC_VER 01273 #pragma warning(disable:4244) // '=' : conversion from 'unsigned long' to 'unsigned short', possible loss of data 01274 #endif 01275 01276 if (DoEndianSwap()) 01277 { 01278 unsigned char output[sizeof(templateType)]; 01279 ReverseBytes((unsigned char*)&inTemplateVar, output, sizeof(templateType)); 01280 WriteCompressed( ( unsigned char* ) output, sizeof(templateType) * 8, true ); 01281 } 01282 else 01283 #endif 01284 WriteCompressed( ( unsigned char* ) & inTemplateVar, sizeof(templateType) * 8, true ); 01285 } 01286 } 01287 01288 template <> 01289 inline void BitStream::WriteCompressed(const SystemAddress &inTemplateVar) 01290 { 01291 Write(inTemplateVar); 01292 } 01293 01294 template <> 01295 inline void BitStream::WriteCompressed(const RakNetGUID &inTemplateVar) 01296 { 01297 Write(inTemplateVar); 01298 } 01299 01300 template <> 01301 inline void BitStream::WriteCompressed(const uint24_t &var) 01302 { 01303 Write(var); 01304 } 01305 01306 template <> 01307 inline void BitStream::WriteCompressed(const bool &inTemplateVar) 01308 { 01309 Write(inTemplateVar); 01310 } 01311 01313 template <> 01314 inline void BitStream::WriteCompressed(const float &inTemplateVar) 01315 { 01316 RakAssert(inTemplateVar > -1.01f && inTemplateVar < 1.01f); 01317 float varCopy=inTemplateVar; 01318 if (varCopy < -1.0f) 01319 varCopy=-1.0f; 01320 if (varCopy > 1.0f) 01321 varCopy=1.0f; 01322 Write((unsigned short)((varCopy+1.0f)*32767.5f)); 01323 } 01324 01326 template <> 01327 inline void BitStream::WriteCompressed(const double &inTemplateVar) 01328 { 01329 RakAssert(inTemplateVar > -1.01 && inTemplateVar < 1.01); 01330 double varCopy=inTemplateVar; 01331 if (varCopy < -1.0f) 01332 varCopy=-1.0f; 01333 if (varCopy > 1.0f) 01334 varCopy=1.0f; 01335 Write((uint32_t)((varCopy+1.0)*2147483648.0)); 01336 } 01337 01339 template <> 01340 inline void BitStream::WriteCompressed(const RakString &inTemplateVar) 01341 { 01342 inTemplateVar.SerializeCompressed(this,0,false); 01343 } 01344 template <> 01345 inline void BitStream::WriteCompressed(const RakWString &inTemplateVar) 01346 { 01347 inTemplateVar.Serialize(this); 01348 } 01349 template <> 01350 inline void BitStream::WriteCompressed(const char * const &inStringVar) 01351 { 01352 RakString::SerializeCompressed(inStringVar,this,0,false); 01353 } 01354 template <> 01355 inline void BitStream::WriteCompressed(const wchar_t * const &inStringVar) 01356 { 01357 RakWString::Serialize(inStringVar,this); 01358 } 01359 template <> 01360 inline void BitStream::WriteCompressed(const unsigned char * const &inTemplateVar) 01361 { 01362 WriteCompressed((const char*) inTemplateVar); 01363 } 01364 template <> 01365 inline void BitStream::WriteCompressed(char * const &inTemplateVar) 01366 { 01367 WriteCompressed((const char*) inTemplateVar); 01368 } 01369 template <> 01370 inline void BitStream::WriteCompressed(unsigned char * const &inTemplateVar) 01371 { 01372 WriteCompressed((const char*) inTemplateVar); 01373 } 01374 01375 01384 template <class templateType> 01385 inline void BitStream::WriteCompressedDelta(const templateType ¤tValue, const templateType &lastValue) 01386 { 01387 if (currentValue==lastValue) 01388 { 01389 Write(false); 01390 } 01391 else 01392 { 01393 Write(true); 01394 WriteCompressed(currentValue); 01395 } 01396 } 01397 01401 template <> 01402 inline void BitStream::WriteCompressedDelta(const bool ¤tValue, const bool &lastValue) 01403 { 01404 (void) lastValue; 01405 01406 Write(currentValue); 01407 } 01408 01411 template <class templateType> 01412 inline void BitStream::WriteCompressedDelta(const templateType ¤tValue) 01413 { 01414 Write(true); 01415 WriteCompressed(currentValue); 01416 } 01417 01420 template <> 01421 inline void BitStream::WriteCompressedDelta(const bool ¤tValue) 01422 { 01423 Write(currentValue); 01424 } 01425 01428 template <class templateType> 01429 inline bool BitStream::Read(templateType &outTemplateVar) 01430 { 01431 #ifdef _MSC_VER 01432 #pragma warning(disable:4127) // conditional expression is constant 01433 #endif 01434 if (sizeof(outTemplateVar)==1) 01435 return ReadBits( ( unsigned char* ) &outTemplateVar, sizeof(templateType) * 8, true ); 01436 else 01437 { 01438 #ifndef __BITSTREAM_NATIVE_END 01439 #ifdef _MSC_VER 01440 #pragma warning(disable:4244) // '=' : conversion from 'unsigned long' to 'unsigned short', possible loss of data 01441 #endif 01442 if (DoEndianSwap()) 01443 { 01444 unsigned char output[sizeof(templateType)]; 01445 if (ReadBits( ( unsigned char* ) output, sizeof(templateType) * 8, true )) 01446 { 01447 ReverseBytes(output, (unsigned char*)&outTemplateVar, sizeof(templateType)); 01448 return true; 01449 } 01450 return false; 01451 } 01452 else 01453 #endif 01454 return ReadBits( ( unsigned char* ) & outTemplateVar, sizeof(templateType) * 8, true ); 01455 } 01456 } 01457 01460 template <> 01461 inline bool BitStream::Read(bool &outTemplateVar) 01462 { 01463 if ( readOffset + 1 > numberOfBitsUsed ) 01464 return false; 01465 01466 if ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) ) // Is it faster to just write it out here? 01467 outTemplateVar = true; 01468 else 01469 outTemplateVar = false; 01470 01471 // Has to be on a different line for Mac 01472 readOffset++; 01473 01474 return true; 01475 } 01476 01479 template <> 01480 inline bool BitStream::Read(SystemAddress &outTemplateVar) 01481 { 01482 unsigned char ipVersion; 01483 Read(ipVersion); 01484 if (ipVersion==4) 01485 { 01486 outTemplateVar.address.addr4.sin_family=AF_INET; 01487 // Read(var.binaryAddress); 01488 // Don't endian swap the address or port 01489 uint32_t binaryAddress; 01490 ReadBits( ( unsigned char* ) & binaryAddress, sizeof(binaryAddress) * 8, true ); 01491 // Unhide the IP address, done to prevent routers from changing it 01492 outTemplateVar.address.addr4.sin_addr.s_addr=~binaryAddress; 01493 bool b = ReadBits(( unsigned char* ) & outTemplateVar.address.addr4.sin_port, sizeof(outTemplateVar.address.addr4.sin_port) * 8, true); 01494 outTemplateVar.debugPort=ntohs(outTemplateVar.address.addr4.sin_port); 01495 return b; 01496 } 01497 else 01498 { 01499 #if RAKNET_SUPPORT_IPV6==1 01500 bool b = ReadBits((unsigned char*) &outTemplateVar.address.addr6, sizeof(outTemplateVar.address.addr6)*8, true); 01501 outTemplateVar.debugPort=ntohs(outTemplateVar.address.addr6.sin6_port); 01502 return b; 01503 #else 01504 return false; 01505 #endif 01506 } 01507 } 01508 01509 template <> 01510 inline bool BitStream::Read(uint24_t &outTemplateVar) 01511 { 01512 AlignReadToByteBoundary(); 01513 if ( readOffset + 3*8 > numberOfBitsUsed ) 01514 return false; 01515 01516 if (IsBigEndian()==false) 01517 { 01518 ((char *)&outTemplateVar.val)[0]=data[ (readOffset >> 3) + 0]; 01519 ((char *)&outTemplateVar.val)[1]=data[ (readOffset >> 3) + 1]; 01520 ((char *)&outTemplateVar.val)[2]=data[ (readOffset >> 3) + 2]; 01521 ((char *)&outTemplateVar.val)[3]=0; 01522 } 01523 else 01524 { 01525 01526 ((char *)&outTemplateVar.val)[3]=data[ (readOffset >> 3) + 0]; 01527 ((char *)&outTemplateVar.val)[2]=data[ (readOffset >> 3) + 1]; 01528 ((char *)&outTemplateVar.val)[1]=data[ (readOffset >> 3) + 2]; 01529 ((char *)&outTemplateVar.val)[0]=0; 01530 } 01531 01532 readOffset+=3*8; 01533 return true; 01534 } 01535 01536 template <> 01537 inline bool BitStream::Read(RakNetGUID &outTemplateVar) 01538 { 01539 return Read(outTemplateVar.g); 01540 } 01541 01542 01543 template <> 01544 inline bool BitStream::Read(RakString &outTemplateVar) 01545 { 01546 return outTemplateVar.Deserialize(this); 01547 } 01548 template <> 01549 inline bool BitStream::Read(RakWString &outTemplateVar) 01550 { 01551 return outTemplateVar.Deserialize(this); 01552 } 01553 template <> 01554 inline bool BitStream::Read(char *&varString) 01555 { 01556 return RakString::Deserialize(varString,this); 01557 } 01558 template <> 01559 inline bool BitStream::Read(wchar_t *&varString) 01560 { 01561 return RakWString::Deserialize(varString,this); 01562 } 01563 template <> 01564 inline bool BitStream::Read(unsigned char *&varString) 01565 { 01566 return RakString::Deserialize((char*) varString,this); 01567 } 01568 01574 template <class templateType> 01575 inline bool BitStream::ReadDelta(templateType &outTemplateVar) 01576 { 01577 bool dataWritten; 01578 bool success; 01579 success=Read(dataWritten); 01580 if (dataWritten) 01581 success=Read(outTemplateVar); 01582 return success; 01583 } 01584 01587 template <> 01588 inline bool BitStream::ReadDelta(bool &outTemplateVar) 01589 { 01590 return Read(outTemplateVar); 01591 } 01592 01599 template <class templateType> 01600 inline bool BitStream::ReadCompressed(templateType &outTemplateVar) 01601 { 01602 #ifdef _MSC_VER 01603 #pragma warning(disable:4127) // conditional expression is constant 01604 #endif 01605 if (sizeof(outTemplateVar)==1) 01606 return ReadCompressed( ( unsigned char* ) &outTemplateVar, sizeof(templateType) * 8, true ); 01607 else 01608 { 01609 #ifndef __BITSTREAM_NATIVE_END 01610 if (DoEndianSwap()) 01611 { 01612 unsigned char output[sizeof(templateType)]; 01613 if (ReadCompressed( ( unsigned char* ) output, sizeof(templateType) * 8, true )) 01614 { 01615 ReverseBytes(output, (unsigned char*)&outTemplateVar, sizeof(templateType)); 01616 return true; 01617 } 01618 return false; 01619 } 01620 else 01621 #endif 01622 return ReadCompressed( ( unsigned char* ) & outTemplateVar, sizeof(templateType) * 8, true ); 01623 } 01624 } 01625 01626 template <> 01627 inline bool BitStream::ReadCompressed(SystemAddress &outTemplateVar) 01628 { 01629 return Read(outTemplateVar); 01630 } 01631 01632 template <> 01633 inline bool BitStream::ReadCompressed(uint24_t &outTemplateVar) 01634 { 01635 return Read(outTemplateVar); 01636 } 01637 01638 template <> 01639 inline bool BitStream::ReadCompressed(RakNetGUID &outTemplateVar) 01640 { 01641 return Read(outTemplateVar); 01642 } 01643 01644 template <> 01645 inline bool BitStream::ReadCompressed(bool &outTemplateVar) 01646 { 01647 return Read(outTemplateVar); 01648 } 01649 01651 template <> 01652 inline bool BitStream::ReadCompressed(float &outTemplateVar) 01653 { 01654 unsigned short compressedFloat; 01655 if (Read(compressedFloat)) 01656 { 01657 outTemplateVar = ((float)compressedFloat / 32767.5f - 1.0f); 01658 return true; 01659 } 01660 return false; 01661 } 01662 01664 template <> 01665 inline bool BitStream::ReadCompressed(double &outTemplateVar) 01666 { 01667 uint32_t compressedFloat; 01668 if (Read(compressedFloat)) 01669 { 01670 outTemplateVar = ((double)compressedFloat / 2147483648.0 - 1.0); 01671 return true; 01672 } 01673 return false; 01674 } 01675 01677 template <> 01678 inline bool BitStream::ReadCompressed(RakString &outTemplateVar) 01679 { 01680 return outTemplateVar.DeserializeCompressed(this,false); 01681 } 01682 template <> 01683 inline bool BitStream::ReadCompressed(RakWString &outTemplateVar) 01684 { 01685 return outTemplateVar.Deserialize(this); 01686 } 01687 template <> 01688 inline bool BitStream::ReadCompressed(char *&outTemplateVar) 01689 { 01690 return RakString::DeserializeCompressed(outTemplateVar,this,false); 01691 } 01692 template <> 01693 inline bool BitStream::ReadCompressed(wchar_t *&outTemplateVar) 01694 { 01695 return RakWString::Deserialize(outTemplateVar,this); 01696 } 01697 template <> 01698 inline bool BitStream::ReadCompressed(unsigned char *&outTemplateVar) 01699 { 01700 return RakString::DeserializeCompressed((char*) outTemplateVar,this,false); 01701 } 01702 01712 template <class templateType> 01713 inline bool BitStream::ReadCompressedDelta(templateType &outTemplateVar) 01714 { 01715 bool dataWritten; 01716 bool success; 01717 success=Read(dataWritten); 01718 if (dataWritten) 01719 success=ReadCompressed(outTemplateVar); 01720 return success; 01721 } 01722 01725 template <> 01726 inline bool BitStream::ReadCompressedDelta(bool &outTemplateVar) 01727 { 01728 return Read(outTemplateVar); 01729 } 01730 01731 template <class destinationType, class sourceType > 01732 void BitStream::WriteCasted( const sourceType &value ) 01733 { 01734 destinationType val = (destinationType) value; 01735 Write(val); 01736 } 01737 01738 template <class templateType, class rangeType> 01739 void BitStream::WriteBitsFromIntegerRange( const templateType value, const rangeType minimum,const rangeType maximum, bool allowOutsideRange ) 01740 { 01741 static int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum)); 01742 WriteBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange); 01743 } 01744 template <class templateType, class rangeType> 01745 void BitStream::WriteBitsFromIntegerRange( const templateType value, const rangeType minimum,const rangeType maximum, const int requiredBits, bool allowOutsideRange ) 01746 { 01747 RakAssert(maximum>=minimum); 01748 RakAssert(allowOutsideRange==true || (value>=minimum && value<=maximum)); 01749 if (allowOutsideRange) 01750 { 01751 if (value<minimum || value>maximum) 01752 { 01753 Write(true); 01754 Write(value); 01755 return; 01756 } 01757 Write(false); 01758 } 01759 templateType valueOffMin=value-minimum; 01760 if (IsBigEndian()==true) 01761 { 01762 unsigned char output[sizeof(templateType)]; 01763 ReverseBytes((unsigned char*)&valueOffMin, output, sizeof(templateType)); 01764 WriteBits(output,requiredBits); 01765 } 01766 else 01767 { 01768 WriteBits((unsigned char*) &valueOffMin,requiredBits); 01769 } 01770 } 01771 01772 template <class templateType> // templateType for this function must be a float or double 01773 void BitStream::WriteNormVector( templateType x, templateType y, templateType z ) 01774 { 01775 #ifdef _DEBUG 01776 RakAssert(x <= 1.01 && y <= 1.01 && z <= 1.01 && x >= -1.01 && y >= -1.01 && z >= -1.01); 01777 #endif 01778 01779 WriteFloat16((float)x,-1.0f,1.0f); 01780 WriteFloat16((float)y,-1.0f,1.0f); 01781 WriteFloat16((float)z,-1.0f,1.0f); 01782 } 01783 01784 template <class templateType> // templateType for this function must be a float or double 01785 void BitStream::WriteVector( templateType x, templateType y, templateType z ) 01786 { 01787 templateType magnitude = sqrt(x * x + y * y + z * z); 01788 Write((float)magnitude); 01789 if (magnitude > 0.00001f) 01790 { 01791 WriteCompressed((float)(x/magnitude)); 01792 WriteCompressed((float)(y/magnitude)); 01793 WriteCompressed((float)(z/magnitude)); 01794 // Write((unsigned short)((x/magnitude+1.0f)*32767.5f)); 01795 // Write((unsigned short)((y/magnitude+1.0f)*32767.5f)); 01796 // Write((unsigned short)((z/magnitude+1.0f)*32767.5f)); 01797 } 01798 } 01799 01800 template <class templateType> // templateType for this function must be a float or double 01801 void BitStream::WriteNormQuat( templateType w, templateType x, templateType y, templateType z) 01802 { 01803 Write((bool)(w<0.0)); 01804 Write((bool)(x<0.0)); 01805 Write((bool)(y<0.0)); 01806 Write((bool)(z<0.0)); 01807 Write((unsigned short)(fabs(x)*65535.0)); 01808 Write((unsigned short)(fabs(y)*65535.0)); 01809 Write((unsigned short)(fabs(z)*65535.0)); 01810 // Leave out w and calculate it on the target 01811 } 01812 01813 template <class templateType> // templateType for this function must be a float or double 01814 void BitStream::WriteOrthMatrix( 01815 templateType m00, templateType m01, templateType m02, 01816 templateType m10, templateType m11, templateType m12, 01817 templateType m20, templateType m21, templateType m22 ) 01818 { 01819 01820 double qw; 01821 double qx; 01822 double qy; 01823 double qz; 01824 01825 // Convert matrix to quat 01826 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ 01827 float sum; 01828 sum = 1 + m00 + m11 + m22; 01829 if (sum < 0.0f) sum=0.0f; 01830 qw = sqrt( sum ) / 2; 01831 sum = 1 + m00 - m11 - m22; 01832 if (sum < 0.0f) sum=0.0f; 01833 qx = sqrt( sum ) / 2; 01834 sum = 1 - m00 + m11 - m22; 01835 if (sum < 0.0f) sum=0.0f; 01836 qy = sqrt( sum ) / 2; 01837 sum = 1 - m00 - m11 + m22; 01838 if (sum < 0.0f) sum=0.0f; 01839 qz = sqrt( sum ) / 2; 01840 if (qw < 0.0) qw=0.0; 01841 if (qx < 0.0) qx=0.0; 01842 if (qy < 0.0) qy=0.0; 01843 if (qz < 0.0) qz=0.0; 01844 qx = _copysign( (double) qx, (double) (m21 - m12) ); 01845 qy = _copysign( (double) qy, (double) (m02 - m20) ); 01846 qz = _copysign( (double) qz, (double) (m10 - m01) ); 01847 01848 WriteNormQuat(qw,qx,qy,qz); 01849 } 01850 01851 template <class serializationType, class sourceType > 01852 bool BitStream::ReadCasted( sourceType &value ) 01853 { 01854 serializationType val; 01855 bool success = Read(val); 01856 value=(sourceType) val; 01857 return success; 01858 } 01859 01860 template <class templateType, class rangeType> 01861 bool BitStream::ReadBitsFromIntegerRange( templateType &value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange ) 01862 { 01863 static int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum)); 01864 return ReadBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange); 01865 } 01866 template <class templateType, class rangeType> 01867 bool BitStream::ReadBitsFromIntegerRange( templateType &value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange ) 01868 { 01869 RakAssert(maximum>=minimum); 01870 if (allowOutsideRange) 01871 { 01872 bool isOutsideRange; 01873 Read(isOutsideRange); 01874 if (isOutsideRange) 01875 return Read(value); 01876 } 01877 unsigned char output[sizeof(templateType)]; 01878 memset(output,0,sizeof(output)); 01879 bool success = ReadBits(output,requiredBits); 01880 if (success) 01881 { 01882 if (IsBigEndian()==true) 01883 ReverseBytesInPlace(output,sizeof(output)); 01884 memcpy(&value,output,sizeof(output)); 01885 01886 value+=minimum; 01887 } 01888 01889 return success; 01890 } 01891 01892 template <class templateType> // templateType for this function must be a float or double 01893 bool BitStream::ReadNormVector( templateType &x, templateType &y, templateType &z ) 01894 { 01895 float xIn,yIn,zIn; 01896 ReadFloat16(xIn,-1.0f,1.0f); 01897 ReadFloat16(yIn,-1.0f,1.0f); 01898 ReadFloat16(zIn,-1.0f,1.0f); 01899 x=xIn; 01900 y=yIn; 01901 z=zIn; 01902 return true; 01903 } 01904 01905 template <class templateType> // templateType for this function must be a float or double 01906 bool BitStream::ReadVector( templateType &x, templateType &y, templateType &z ) 01907 { 01908 float magnitude; 01909 //unsigned short sx,sy,sz; 01910 if (!Read(magnitude)) 01911 return false; 01912 if (magnitude>0.00001f) 01913 { 01914 // Read(sx); 01915 // Read(sy); 01916 // if (!Read(sz)) 01917 // return false; 01918 // x=((float)sx / 32767.5f - 1.0f) * magnitude; 01919 // y=((float)sy / 32767.5f - 1.0f) * magnitude; 01920 // z=((float)sz / 32767.5f - 1.0f) * magnitude; 01921 float cx,cy,cz; 01922 ReadCompressed(cx); 01923 ReadCompressed(cy); 01924 if (!ReadCompressed(cz)) 01925 return false; 01926 x=cx; 01927 y=cy; 01928 z=cz; 01929 x*=magnitude; 01930 y*=magnitude; 01931 z*=magnitude; 01932 } 01933 else 01934 { 01935 x=0.0; 01936 y=0.0; 01937 z=0.0; 01938 } 01939 return true; 01940 } 01941 01942 template <class templateType> // templateType for this function must be a float or double 01943 bool BitStream::ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z) 01944 { 01945 bool cwNeg=false, cxNeg=false, cyNeg=false, czNeg=false; 01946 unsigned short cx,cy,cz; 01947 Read(cwNeg); 01948 Read(cxNeg); 01949 Read(cyNeg); 01950 Read(czNeg); 01951 Read(cx); 01952 Read(cy); 01953 if (!Read(cz)) 01954 return false; 01955 01956 // Calculate w from x,y,z 01957 x=(templateType)(cx/65535.0); 01958 y=(templateType)(cy/65535.0); 01959 z=(templateType)(cz/65535.0); 01960 if (cxNeg) x=-x; 01961 if (cyNeg) y=-y; 01962 if (czNeg) z=-z; 01963 float difference = 1.0f - x*x - y*y - z*z; 01964 if (difference < 0.0f) 01965 difference=0.0f; 01966 w = (templateType)(sqrt(difference)); 01967 if (cwNeg) 01968 w=-w; 01969 01970 return true; 01971 } 01972 01973 template <class templateType> // templateType for this function must be a float or double 01974 bool BitStream::ReadOrthMatrix( 01975 templateType &m00, templateType &m01, templateType &m02, 01976 templateType &m10, templateType &m11, templateType &m12, 01977 templateType &m20, templateType &m21, templateType &m22 ) 01978 { 01979 float qw,qx,qy,qz; 01980 if (!ReadNormQuat(qw,qx,qy,qz)) 01981 return false; 01982 01983 // Quat to orthogonal rotation matrix 01984 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm 01985 double sqw = (double)qw*(double)qw; 01986 double sqx = (double)qx*(double)qx; 01987 double sqy = (double)qy*(double)qy; 01988 double sqz = (double)qz*(double)qz; 01989 m00 = (templateType)(sqx - sqy - sqz + sqw); // since sqw + sqx + sqy + sqz =1 01990 m11 = (templateType)(-sqx + sqy - sqz + sqw); 01991 m22 = (templateType)(-sqx - sqy + sqz + sqw); 01992 01993 double tmp1 = (double)qx*(double)qy; 01994 double tmp2 = (double)qz*(double)qw; 01995 m10 = (templateType)(2.0 * (tmp1 + tmp2)); 01996 m01 = (templateType)(2.0 * (tmp1 - tmp2)); 01997 01998 tmp1 = (double)qx*(double)qz; 01999 tmp2 = (double)qy*(double)qw; 02000 m20 =(templateType)(2.0 * (tmp1 - tmp2)); 02001 m02 = (templateType)(2.0 * (tmp1 + tmp2)); 02002 tmp1 = (double)qy*(double)qz; 02003 tmp2 = (double)qx*(double)qw; 02004 m21 = (templateType)(2.0 * (tmp1 + tmp2)); 02005 m12 = (templateType)(2.0 * (tmp1 - tmp2)); 02006 02007 return true; 02008 } 02009 02010 template <class templateType> 02011 BitStream& operator<<(BitStream& out, templateType& c) 02012 { 02013 out.Write(c); 02014 return out; 02015 } 02016 template <class templateType> 02017 BitStream& operator>>(BitStream& in, templateType& c) 02018 { 02019 bool success = in.Read(c); 02020 RakAssert(success); 02021 return in; 02022 } 02023 02024 } 02025 02026 #ifdef _MSC_VER 02027 #pragma warning( pop ) 02028 #endif 02029 02030 #endif 02031 02032 #endif // VC6
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.