1 // 2 // DESCRIPTION: 3 // Endianess handling, swapping 16bit and 32bit. 4 // 5 //----------------------------------------------------------------------------- 6 7 8 #ifndef __M_SWAP_H__ 9 #define __M_SWAP_H__ 10 11 #include <stdlib.h> 12 13 // Endianess handling. 14 // WAD files are stored little endian. 15 16 #ifdef __APPLE__ 17 #include <libkern/OSByteOrder.h> 18 LittleShort(short x)19inline short LittleShort(short x) 20 { 21 return (short)OSSwapLittleToHostInt16((uint16_t)x); 22 } 23 LittleShort(unsigned short x)24inline unsigned short LittleShort(unsigned short x) 25 { 26 return OSSwapLittleToHostInt16(x); 27 } 28 LittleShort(int x)29inline short LittleShort(int x) 30 { 31 return OSSwapLittleToHostInt16((uint16_t)x); 32 } 33 LittleShort(unsigned int x)34inline unsigned short LittleShort(unsigned int x) 35 { 36 return OSSwapLittleToHostInt16((uint16_t)x); 37 } 38 LittleLong(int x)39inline int LittleLong(int x) 40 { 41 return OSSwapLittleToHostInt32((uint32_t)x); 42 } 43 LittleLong(unsigned int x)44inline unsigned int LittleLong(unsigned int x) 45 { 46 return OSSwapLittleToHostInt32(x); 47 } 48 BigShort(short x)49inline short BigShort(short x) 50 { 51 return (short)OSSwapBigToHostInt16((uint16_t)x); 52 } 53 BigShort(unsigned short x)54inline unsigned short BigShort(unsigned short x) 55 { 56 return OSSwapBigToHostInt16(x); 57 } 58 BigLong(int x)59inline int BigLong(int x) 60 { 61 return OSSwapBigToHostInt32((uint32_t)x); 62 } 63 BigLong(unsigned int x)64inline unsigned int BigLong(unsigned int x) 65 { 66 return OSSwapBigToHostInt32(x); 67 } 68 69 #elif defined __BIG_ENDIAN__ 70 71 // Swap 16bit, that is, MSB and LSB byte. 72 // No masking with 0xFF should be necessary. LittleShort(short x)73inline short LittleShort (short x) 74 { 75 return (short)((((unsigned short)x)>>8) | (((unsigned short)x)<<8)); 76 } 77 LittleShort(unsigned short x)78inline unsigned short LittleShort (unsigned short x) 79 { 80 return (unsigned short)((x>>8) | (x<<8)); 81 } 82 LittleShort(int x)83inline short LittleShort (int x) 84 { 85 return LittleShort((short)x); 86 } 87 LittleShort(unsigned int x)88inline unsigned short LittleShort (unsigned int x) 89 { 90 return LittleShort((unsigned short)x); 91 } 92 93 // Swapping 32bit. LittleLong(unsigned int x)94inline unsigned int LittleLong (unsigned int x) 95 { 96 return (unsigned int)( 97 (x>>24) 98 | ((x>>8) & 0xff00) 99 | ((x<<8) & 0xff0000) 100 | (x<<24)); 101 } 102 LittleLong(int x)103inline int LittleLong (int x) 104 { 105 return (int)( 106 (((unsigned int)x)>>24) 107 | ((((unsigned int)x)>>8) & 0xff00) 108 | ((((unsigned int)x)<<8) & 0xff0000) 109 | (((unsigned int)x)<<24)); 110 } 111 BigShort(short x)112inline short BigShort(short x) 113 { 114 return x; 115 } 116 BigShort(unsigned short x)117inline unsigned short BigShort(unsigned short x) 118 { 119 return x; 120 } 121 BigLong(unsigned int x)122inline unsigned int BigLong(unsigned int x) 123 { 124 return x; 125 } 126 BigLong(int x)127inline int BigLong(int x) 128 { 129 return x; 130 } 131 132 #else 133 LittleShort(short x)134inline short LittleShort(short x) 135 { 136 return x; 137 } 138 LittleShort(unsigned short x)139inline unsigned short LittleShort(unsigned short x) 140 { 141 return x; 142 } 143 LittleLong(unsigned int x)144inline unsigned int LittleLong(unsigned int x) 145 { 146 return x; 147 } 148 LittleLong(int x)149inline int LittleLong(int x) 150 { 151 return x; 152 } 153 154 #ifdef _MSC_VER 155 BigShort(short x)156inline short BigShort(short x) 157 { 158 return (short)_byteswap_ushort((unsigned short)x); 159 } 160 BigShort(unsigned short x)161inline unsigned short BigShort(unsigned short x) 162 { 163 return _byteswap_ushort(x); 164 } 165 BigLong(int x)166inline int BigLong(int x) 167 { 168 return (int)_byteswap_ulong((unsigned long)x); 169 } 170 BigLong(unsigned int x)171inline unsigned int BigLong(unsigned int x) 172 { 173 return (unsigned int)_byteswap_ulong((unsigned long)x); 174 } 175 #pragma warning (default: 4035) 176 177 #else 178 BigShort(short x)179inline short BigShort (short x) 180 { 181 return (short)((((unsigned short)x)>>8) | (((unsigned short)x)<<8)); 182 } 183 BigShort(unsigned short x)184inline unsigned short BigShort (unsigned short x) 185 { 186 return (unsigned short)((x>>8) | (x<<8)); 187 } 188 BigLong(unsigned int x)189inline unsigned int BigLong (unsigned int x) 190 { 191 return (unsigned int)( 192 (x>>24) 193 | ((x>>8) & 0xff00) 194 | ((x<<8) & 0xff0000) 195 | (x<<24)); 196 } 197 BigLong(int x)198inline int BigLong (int x) 199 { 200 return (int)( 201 (((unsigned int)x)>>24) 202 | ((((unsigned int)x)>>8) & 0xff00) 203 | ((((unsigned int)x)<<8) & 0xff0000) 204 | (((unsigned int)x)<<24)); 205 } 206 207 #endif 208 209 #endif // __BIG_ENDIAN__ 210 211 // These may be destructive so they should create errors 212 unsigned long BigLong(unsigned long) = delete; 213 long BigLong(long) = delete; 214 unsigned long LittleLong(unsigned long) = delete; 215 long LittleLong(long) = delete; 216 217 218 // Data accessors, since some data is highly likely to be unaligned. 219 #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__) GetShort(const unsigned char * foo)220inline int GetShort(const unsigned char *foo) 221 { 222 return *(const short *)foo; 223 } GetInt(const unsigned char * foo)224inline int GetInt(const unsigned char *foo) 225 { 226 return *(const int *)foo; 227 } 228 #else GetShort(const unsigned char * foo)229inline int GetShort(const unsigned char *foo) 230 { 231 return short(foo[0] | (foo[1] << 8)); 232 } GetInt(const unsigned char * foo)233inline int GetInt(const unsigned char *foo) 234 { 235 return int(foo[0] | (foo[1] << 8) | (foo[2] << 16) | (foo[3] << 24)); 236 } 237 #endif GetBigInt(const unsigned char * foo)238inline int GetBigInt(const unsigned char *foo) 239 { 240 return int((foo[0] << 24) | (foo[1] << 16) | (foo[2] << 8) | foo[3]); 241 } 242 243 #ifdef __BIG_ENDIAN__ GetNativeInt(const unsigned char * foo)244inline int GetNativeInt(const unsigned char *foo) 245 { 246 return GetBigInt(foo); 247 } 248 #else GetNativeInt(const unsigned char * foo)249inline int GetNativeInt(const unsigned char *foo) 250 { 251 return GetInt(foo); 252 } 253 #endif 254 255 #endif // __M_SWAP_H__ 256