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)19 inline short LittleShort(short x)
20 {
21 	return (short)OSSwapLittleToHostInt16((uint16_t)x);
22 }
23 
LittleShort(unsigned short x)24 inline unsigned short LittleShort(unsigned short x)
25 {
26 	return OSSwapLittleToHostInt16(x);
27 }
28 
LittleShort(int x)29 inline short LittleShort(int x)
30 {
31 	return OSSwapLittleToHostInt16((uint16_t)x);
32 }
33 
LittleShort(unsigned int x)34 inline unsigned short LittleShort(unsigned int x)
35 {
36 	return OSSwapLittleToHostInt16((uint16_t)x);
37 }
38 
LittleLong(int x)39 inline int LittleLong(int x)
40 {
41 	return OSSwapLittleToHostInt32((uint32_t)x);
42 }
43 
LittleLong(unsigned int x)44 inline unsigned int LittleLong(unsigned int x)
45 {
46 	return OSSwapLittleToHostInt32(x);
47 }
48 
BigShort(short x)49 inline short BigShort(short x)
50 {
51 	return (short)OSSwapBigToHostInt16((uint16_t)x);
52 }
53 
BigShort(unsigned short x)54 inline unsigned short BigShort(unsigned short x)
55 {
56 	return OSSwapBigToHostInt16(x);
57 }
58 
BigLong(int x)59 inline int BigLong(int x)
60 {
61 	return OSSwapBigToHostInt32((uint32_t)x);
62 }
63 
BigLong(unsigned int x)64 inline 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)73 inline short LittleShort (short x)
74 {
75 	return (short)((((unsigned short)x)>>8) | (((unsigned short)x)<<8));
76 }
77 
LittleShort(unsigned short x)78 inline unsigned short LittleShort (unsigned short x)
79 {
80 	return (unsigned short)((x>>8) | (x<<8));
81 }
82 
LittleShort(int x)83 inline short LittleShort (int x)
84 {
85 	return LittleShort((short)x);
86 }
87 
LittleShort(unsigned int x)88 inline unsigned short LittleShort (unsigned int x)
89 {
90 	return LittleShort((unsigned short)x);
91 }
92 
93 // Swapping 32bit.
LittleLong(unsigned int x)94 inline 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)103 inline 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)112 inline short BigShort(short x)
113 {
114 	return x;
115 }
116 
BigShort(unsigned short x)117 inline unsigned short BigShort(unsigned short x)
118 {
119 	return x;
120 }
121 
BigLong(unsigned int x)122 inline unsigned int BigLong(unsigned int x)
123 {
124 	return x;
125 }
126 
BigLong(int x)127 inline int BigLong(int x)
128 {
129 	return x;
130 }
131 
132 #else
133 
LittleShort(short x)134 inline short LittleShort(short x)
135 {
136 	return x;
137 }
138 
LittleShort(unsigned short x)139 inline unsigned short LittleShort(unsigned short x)
140 {
141 	return x;
142 }
143 
LittleLong(unsigned int x)144 inline unsigned int LittleLong(unsigned int x)
145 {
146 	return x;
147 }
148 
LittleLong(int x)149 inline int LittleLong(int x)
150 {
151 	return x;
152 }
153 
154 #ifdef _MSC_VER
155 
BigShort(short x)156 inline short BigShort(short x)
157 {
158 	return (short)_byteswap_ushort((unsigned short)x);
159 }
160 
BigShort(unsigned short x)161 inline unsigned short BigShort(unsigned short x)
162 {
163 	return _byteswap_ushort(x);
164 }
165 
BigLong(int x)166 inline int BigLong(int x)
167 {
168 	return (int)_byteswap_ulong((unsigned long)x);
169 }
170 
BigLong(unsigned int x)171 inline 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)179 inline short BigShort (short x)
180 {
181 	return (short)((((unsigned short)x)>>8) | (((unsigned short)x)<<8));
182 }
183 
BigShort(unsigned short x)184 inline unsigned short BigShort (unsigned short x)
185 {
186 	return (unsigned short)((x>>8) | (x<<8));
187 }
188 
BigLong(unsigned int x)189 inline 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)198 inline 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)220 inline int GetShort(const unsigned char *foo)
221 {
222 	return *(const short *)foo;
223 }
GetInt(const unsigned char * foo)224 inline int GetInt(const unsigned char *foo)
225 {
226 	return *(const int *)foo;
227 }
228 #else
GetShort(const unsigned char * foo)229 inline int GetShort(const unsigned char *foo)
230 {
231 	return short(foo[0] | (foo[1] << 8));
232 }
GetInt(const unsigned char * foo)233 inline 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)238 inline 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)244 inline int GetNativeInt(const unsigned char *foo)
245 {
246 	return GetBigInt(foo);
247 }
248 #else
GetNativeInt(const unsigned char * foo)249 inline int GetNativeInt(const unsigned char *foo)
250 {
251 	return GetInt(foo);
252 }
253 #endif
254 
255 #endif // __M_SWAP_H__
256