Swap.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. 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.
  17. 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.
  18. ===========================================================================
  19. */
  20. #ifndef __SWAP_H__
  21. #define __SWAP_H__
  22. /*
  23. ================================================================================================
  24. Contains the Swap class, for CrossPlatform endian conversion.
  25. works
  26. ================================================================================================
  27. */
  28. /*
  29. ========================
  30. IsPointer
  31. ========================
  32. */
  33. template< typename type >
  34. bool IsPointer( type ) {
  35. return false;
  36. }
  37. /*
  38. ========================
  39. IsPointer
  40. ========================
  41. */
  42. template< typename type >
  43. bool IsPointer( type * ) {
  44. return true;
  45. }
  46. /*
  47. ================================================
  48. The *Swap* static template class, idSwap, is used by the SwapClass template class for
  49. performing EndianSwapping.
  50. ================================================
  51. */
  52. class idSwap {
  53. public:
  54. //#define SwapBytes( x, y ) (x) ^= (y) ^= (x) ^= (y)
  55. #define SwapBytes( x, y ) { byte t = (x); (x) = (y); (y) = t; }
  56. template<class type> static void Little( type &c ) {
  57. // byte swapping pointers is pointless because we should never store pointers on disk
  58. assert( !IsPointer( c ) );
  59. }
  60. template<class type> static void Big( type &c ) {
  61. // byte swapping pointers is pointless because we should never store pointers on disk
  62. assert( !IsPointer( c ) );
  63. if ( sizeof( type ) == 1 ) {
  64. } else if ( sizeof( type ) == 2 ) {
  65. byte *b = (byte *)&c;
  66. SwapBytes( b[0], b[1] );
  67. } else if ( sizeof( type ) == 4 ) {
  68. byte *b = (byte *)&c;
  69. SwapBytes( b[0], b[3] );
  70. SwapBytes( b[1], b[2] );
  71. } else if ( sizeof( type ) == 8 ) {
  72. byte * b = (byte *)&c;
  73. SwapBytes( b[0], b[7] );
  74. SwapBytes( b[1], b[6]);
  75. SwapBytes( b[2], b[5] );
  76. SwapBytes( b[3], b[4] );
  77. } else {
  78. assert( false );
  79. }
  80. }
  81. template<class type> static void LittleArray( type *c, int count ) {
  82. }
  83. template<class type> static void BigArray( type *c, int count ) {
  84. for ( int i = 0; i < count; i++ ) {
  85. Big( c[i] );
  86. }
  87. }
  88. static void SixtetsForInt( byte *out, int src ) {
  89. byte *b = (byte *)&src;
  90. out[0] = ( b[0] & 0xfc ) >> 2;
  91. out[1] = ( ( b[0] & 0x3 ) << 4 ) + ( ( b[1] & 0xf0 ) >> 4 );
  92. out[2] = ( ( b[1] & 0xf ) << 2 ) + ( ( b[2] & 0xc0 ) >> 6 );
  93. out[3] = b[2] & 0x3f;
  94. }
  95. static int IntForSixtets( byte *in ) {
  96. int ret = 0;
  97. byte *b = (byte *)&ret;
  98. b[0] |= in[0] << 2;
  99. b[0] |= ( in[1] & 0x30 ) >> 4;
  100. b[1] |= ( in[1] & 0xf ) << 4;
  101. b[1] |= ( in[2] & 0x3c ) >> 2;
  102. b[2] |= ( in[2] & 0x3 ) << 6;
  103. b[2] |= in[3];
  104. return ret;
  105. }
  106. public: // specializations
  107. #ifndef ID_SWAP_LITE // avoid dependency avalanche for SPU code
  108. #define SWAP_VECTOR( x ) \
  109. static void Little( x &c ) { LittleArray( c.ToFloatPtr(), c.GetDimension() ); } \
  110. static void Big( x &c ) { BigArray( c.ToFloatPtr(), c.GetDimension() ); }
  111. SWAP_VECTOR( idVec2 );
  112. SWAP_VECTOR( idVec3 );
  113. SWAP_VECTOR( idVec4 );
  114. SWAP_VECTOR( idVec5 );
  115. SWAP_VECTOR( idVec6 );
  116. SWAP_VECTOR( idMat2 );
  117. SWAP_VECTOR( idMat3 );
  118. SWAP_VECTOR( idMat4 );
  119. SWAP_VECTOR( idMat5 );
  120. SWAP_VECTOR( idMat6 );
  121. SWAP_VECTOR( idPlane );
  122. SWAP_VECTOR( idQuat );
  123. SWAP_VECTOR( idCQuat );
  124. SWAP_VECTOR( idAngles );
  125. SWAP_VECTOR( idBounds );
  126. static void Little( idDrawVert &v ) {
  127. Little( v.xyz );
  128. LittleArray( v.st, 2 );
  129. LittleArray( v.normal, 4 );
  130. LittleArray( v.tangent, 4 );
  131. LittleArray( v.color, 4 );
  132. }
  133. static void Big( idDrawVert &v ) {
  134. Big( v.xyz );
  135. BigArray( v.st, 2 );
  136. BigArray( v.normal, 4 );
  137. BigArray( v.tangent, 4 );
  138. BigArray( v.color, 4 );
  139. }
  140. #endif
  141. };
  142. /*
  143. ================================================
  144. idSwapClass is a template class for performing EndianSwapping.
  145. ================================================
  146. */
  147. template<class classType>
  148. class idSwapClass {
  149. public:
  150. idSwapClass() {
  151. #ifdef _DEBUG
  152. size = 0;
  153. #endif
  154. }
  155. ~idSwapClass() {
  156. #ifdef _DEBUG
  157. assert( size == sizeof( classType ) );
  158. #endif
  159. }
  160. template<class type> void Little( type &c ) {
  161. idSwap::Little( c );
  162. #ifdef _DEBUG
  163. size += sizeof( type );
  164. #endif
  165. }
  166. template<class type> void Big( type &c ) {
  167. idSwap::Big( c );
  168. #ifdef _DEBUG
  169. size += sizeof( type );
  170. #endif
  171. }
  172. template<class type> void LittleArray( type *c, int count ) {
  173. idSwap::LittleArray( c, count );
  174. #ifdef _DEBUG
  175. size += count * sizeof( type );
  176. #endif
  177. }
  178. template<class type> void BigArray( type *c, int count ) {
  179. idSwap::BigArray( c, count );
  180. #ifdef _DEBUG
  181. size += count * sizeof( type );
  182. #endif
  183. }
  184. #ifdef _DEBUG
  185. private:
  186. int size;
  187. #endif
  188. };
  189. #define BIG32(v) ((((uint32)(v)) >> 24) | (((uint32)(v) & 0x00FF0000) >> 8) | (((uint32)(v) & 0x0000FF00) << 8) | ((uint32)(v) << 24))
  190. #define BIG16(v) ((((uint16)(v)) >> 8) | ((uint16)(v) << 8))
  191. #endif // !__SWAP_H__