Rev 5038 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5 | Plagman | 1 | // Compatibility declarations for things which might not be present in |
2 | // certain build environments. It also levels the playing field caused |
||
3 | // by different platforms. |
||
4 | |||
4747 | terminx | 5 | #ifndef compat_h_ |
6 | #define compat_h_ |
||
5 | Plagman | 7 | |
4685 | hendricks2 | 8 | #ifdef __GNUC__ |
4762 | hendricks2 | 9 | # define EDUKE32_GCC_PREREQ(major, minor) (major < __GNUC__ || (major == __GNUC__ && minor <= __GNUC_MINOR__)) |
4685 | hendricks2 | 10 | #else |
11 | # define EDUKE32_GCC_PREREQ(major, minor) 0 |
||
12 | #endif |
||
13 | |||
14 | #ifdef __clang__ |
||
4762 | hendricks2 | 15 | # define EDUKE32_CLANG_PREREQ(major, minor) (major < __clang_major__ || (major == __clang_major__ && minor <= __clang_minor__)) |
4685 | hendricks2 | 16 | #else |
17 | # define EDUKE32_CLANG_PREREQ(major, minor) 0 |
||
18 | #endif |
||
19 | #ifndef __has_builtin |
||
20 | # define __has_builtin(x) 0 // Compatibility with non-clang compilers. |
||
21 | #endif |
||
22 | #ifndef __has_feature |
||
23 | # define __has_feature(x) 0 // Compatibility with non-clang compilers. |
||
24 | #endif |
||
25 | #ifndef __has_extension |
||
26 | # define __has_extension __has_feature // Compatibility with pre-3.0 compilers. |
||
27 | #endif |
||
28 | |||
4785 | helixhorne | 29 | #if !defined(_MSC_VER) || _MSC_FULL_VER < 180031101 |
4697 | terminx | 30 | #ifdef UNREFERENCED_PARAMETER |
31 | #undef UNREFERENCED_PARAMETER |
||
654 | terminx | 32 | #endif |
33 | |||
4697 | terminx | 34 | #define UNREFERENCED_PARAMETER(x) x = x |
4783 | terminx | 35 | #endif |
4697 | terminx | 36 | |
1743 | helixhorne | 37 | #if defined __GNUC__ || defined __clang__ |
38 | # define ATTRIBUTE(attrlist) __attribute__(attrlist) |
||
39 | #else |
||
40 | # define ATTRIBUTE(attrlist) |
||
41 | #endif |
||
42 | |||
3341 | helixhorne | 43 | #if !defined __clang__ && !defined USING_LTO |
44 | # define ATTRIBUTE_OPTIMIZE(str) ATTRIBUTE((optimize(str))) |
||
45 | #else |
||
46 | # define ATTRIBUTE_OPTIMIZE(str) |
||
47 | #endif |
||
48 | |||
4685 | hendricks2 | 49 | #if defined __GNUC__ || __has_builtin(__builtin_expect) |
4680 | terminx | 50 | #define EDUKE32_PREDICT_TRUE(x) __builtin_expect(!!(x),1) |
51 | #define EDUKE32_PREDICT_FALSE(x) __builtin_expect(!!(x),0) |
||
4685 | hendricks2 | 52 | #else |
53 | #define EDUKE32_PREDICT_TRUE(x) (x) |
||
54 | #define EDUKE32_PREDICT_FALSE(x) (x) |
||
55 | #endif |
||
56 | |||
57 | #if EDUKE32_GCC_PREREQ(4,5) || __has_builtin(__builtin_unreachable) |
||
4680 | terminx | 58 | #define EDUKE32_UNREACHABLE_SECTION(...) __builtin_unreachable() |
59 | #elif _MSC_VER |
||
60 | #define EDUKE32_UNREACHABLE_SECTION(...) __assume(0) |
||
4685 | hendricks2 | 61 | #else |
4680 | terminx | 62 | #define EDUKE32_UNREACHABLE_SECTION(...) __VA_ARGS__ |
63 | #endif |
||
64 | |||
3180 | helixhorne | 65 | #ifndef min |
66 | #define min(x,y) ((x) < (y) ? (x) : (y)) |
||
67 | #endif |
||
68 | #ifndef max |
||
69 | #define max(x,y) ((x) > (y) ? (x) : (y)) |
||
70 | #endif |
||
71 | |||
5038 | hendricks2 | 72 | #if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __bsdi__ || defined __DragonFly__ |
73 | # define EDUKE32_BSD |
||
74 | #endif |
||
75 | |||
5037 | hendricks2 | 76 | #if !defined __APPLE__ && (!defined EDUKE32_BSD || !__STDC__) |
4762 | hendricks2 | 77 | # include <malloc.h> |
78 | #endif |
||
79 | |||
80 | #ifdef _WIN32 |
||
81 | # define WIN32_LEAN_AND_MEAN |
||
82 | # include <windows.h> |
||
83 | #endif |
||
84 | |||
85 | #ifdef __APPLE__ |
||
86 | # include <TargetConditionals.h> |
||
4942 | hendricks2 | 87 | # if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR |
88 | # define EDUKE32_IOS |
||
89 | # else |
||
90 | # define EDUKE32_OSX |
||
4762 | hendricks2 | 91 | # if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_3 |
92 | # include <CoreFoundation/CoreFoundation.h> |
||
93 | # endif |
||
94 | # include <CoreServices/CoreServices.h> |
||
95 | # endif |
||
96 | #endif |
||
97 | |||
4942 | hendricks2 | 98 | #if defined __ANDROID__ || defined EDUKE32_IOS |
4852 | hendricks2 | 99 | # define EDUKE32_TOUCH_DEVICES |
4989 | terminx | 100 | # define EDUKE32_GLES |
4852 | hendricks2 | 101 | #endif |
102 | |||
618 | terminx | 103 | // This gives us access to 'intptr_t' and 'uintptr_t', which are |
104 | // abstractions to the size of a pointer on a given platform |
||
105 | // (ie, they're guaranteed to be the same size as a pointer) |
||
3116 | hendricks2 | 106 | |
4078 | hendricks2 | 107 | #undef __USE_MINGW_ANSI_STDIO // Workaround for MinGW-w64. |
108 | |||
4762 | hendricks2 | 109 | #ifndef __STDC_FORMAT_MACROS |
3116 | hendricks2 | 110 | #define __STDC_FORMAT_MACROS |
4762 | hendricks2 | 111 | #endif |
4540 | hendricks2 | 112 | #ifndef __STDC_LIMIT_MACROS |
4708 | helixhorne | 113 | # define __STDC_LIMIT_MACROS |
4540 | hendricks2 | 114 | #endif |
4619 | terminx | 115 | #if defined(HAVE_INTTYPES) || defined(__cplusplus) |
4708 | helixhorne | 116 | # include <stdint.h> |
117 | # include <inttypes.h> |
||
3496 | hendricks2 | 118 | |
119 | // Ghetto. Blame devkitPPC's faulty headers. |
||
4708 | helixhorne | 120 | # ifdef GEKKO |
3496 | hendricks2 | 121 | # undef PRIdPTR |
122 | # define PRIdPTR "d" |
||
123 | # undef PRIxPTR |
||
124 | # define PRIxPTR "x" |
||
125 | # undef SCNx32 |
||
126 | # define SCNx32 "x" |
||
4708 | helixhorne | 127 | # endif |
3496 | hendricks2 | 128 | |
795 | terminx | 129 | #elif defined(_MSC_VER) |
4708 | helixhorne | 130 | # include "msvc/inttypes.h" // from http://code.google.com/p/msinttypes/ |
618 | terminx | 131 | #endif |
132 | |||
1435 | terminx | 133 | #ifndef _MSC_VER |
3278 | hendricks2 | 134 | # ifndef __fastcall |
135 | # if defined(__GNUC__) && defined(__i386__) |
||
2992 | helixhorne | 136 | # define __fastcall __attribute__((fastcall)) |
3278 | hendricks2 | 137 | # else |
138 | # define __fastcall |
||
2992 | helixhorne | 139 | # endif |
140 | # endif |
||
1435 | terminx | 141 | #endif |
142 | |||
1346 | terminx | 143 | #ifndef TRUE |
2992 | helixhorne | 144 | # define TRUE 1 |
1346 | terminx | 145 | #endif |
146 | |||
147 | #ifndef FALSE |
||
2992 | helixhorne | 148 | # define FALSE 0 |
1346 | terminx | 149 | #endif |
150 | |||
1592 | terminx | 151 | #define WITHKPLIB |
152 | |||
4658 | terminx | 153 | #include "libdivide.h" |
154 | |||
5 | Plagman | 155 | // Define this to rewrite all 'B' versions to library functions. This |
156 | // is for platforms which give us a standard sort of C library so we |
||
157 | // link directly. Platforms like PalmOS which don't have a standard C |
||
158 | // library will need to wrap these functions with suitable emulations. |
||
4747 | terminx | 159 | #define compat_h_macrodef__ |
5 | Plagman | 160 | |
4766 | hendricks2 | 161 | #include <stdarg.h> |
162 | #include <stddef.h> |
||
5 | Plagman | 163 | |
4747 | terminx | 164 | #ifdef compat_h_macrodef__ |
4766 | hendricks2 | 165 | # include <stdio.h> |
166 | # include <string.h> |
||
167 | # include <stdlib.h> |
||
168 | # include <time.h> |
||
5 | Plagman | 169 | # include <fcntl.h> |
170 | # include <ctype.h> |
||
171 | # include <sys/types.h> |
||
172 | # include <sys/stat.h> |
||
173 | # include <errno.h> |
||
174 | # if defined(_WIN32) |
||
175 | # include <io.h> |
||
176 | # else |
||
177 | # include <unistd.h> |
||
178 | # endif |
||
179 | #endif |
||
180 | |||
2481 | helixhorne | 181 | #include <assert.h> |
182 | |||
5 | Plagman | 183 | #ifdef EFENCE |
184 | # include <efence.h> |
||
2254 | helixhorne | 185 | #elif defined DMALLOC |
186 | # include <dmalloc.h> |
||
5 | Plagman | 187 | #endif |
188 | |||
1454 | terminx | 189 | #if defined(_MSC_VER) |
4708 | helixhorne | 190 | # include <direct.h> |
5 | Plagman | 191 | # define longlong(x) x##i64 |
4708 | helixhorne | 192 | # if _MSC_VER < 1800 |
193 | # define inline __inline |
||
194 | # endif |
||
5 | Plagman | 195 | #else |
196 | # define longlong(x) x##ll |
||
197 | #endif |
||
198 | |||
4606 | terminx | 199 | #if defined(__arm__) |
4989 | terminx | 200 | # define Bsqrt __builtin_sqrt |
201 | # define Bsqrtf __builtin_sqrtf |
||
4606 | terminx | 202 | #else |
4708 | helixhorne | 203 | # define Bsqrt sqrt |
204 | # define Bsqrtf sqrtf |
||
4606 | terminx | 205 | #endif |
206 | |||
5 | Plagman | 207 | #ifndef NULL |
208 | # define NULL ((void *)0) |
||
209 | #endif |
||
210 | |||
2270 | helixhorne | 211 | #if DEBUGGINGAIDS>=2 |
212 | # define DEBUG_MAIN_ARRAYS |
||
213 | #endif |
||
214 | |||
4893 | terminx | 215 | #ifndef DISABLE_INLINING |
216 | # define EXTERN_INLINE static inline |
||
217 | # define EXTERN_INLINE_HEADER static inline |
||
3116 | hendricks2 | 218 | #else |
4247 | hendricks2 | 219 | # define EXTERN_INLINE __fastcall |
220 | # define EXTERN_INLINE_HEADER extern __fastcall |
||
3116 | hendricks2 | 221 | #endif |
222 | |||
4937 | helixhorne | 223 | #ifndef FORCE_INLINE |
224 | # ifdef _MSC_VER // Visual Studio |
||
225 | # define FORCE_INLINE static __forceinline |
||
226 | # else |
||
227 | # ifdef __GNUC__ |
||
228 | # define FORCE_INLINE static inline __attribute__((always_inline)) |
||
229 | # else |
||
230 | # define FORCE_INLINE static inline |
||
231 | # endif |
||
232 | # endif |
||
233 | #endif |
||
234 | |||
2495 | hendricks2 | 235 | #if !defined DEBUG_MAIN_ARRAYS |
236 | # define HAVE_CLIPSHAPE_FEATURE |
||
237 | #endif |
||
238 | |||
1935 | helixhorne | 239 | // redefined for apple/ppc, which chokes on stderr when linking... |
240 | #define ERRprintf(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__) |
||
241 | |||
5 | Plagman | 242 | #if defined(__linux) |
243 | # include <endian.h> |
||
244 | # if __BYTE_ORDER == __LITTLE_ENDIAN |
||
245 | # define B_LITTLE_ENDIAN 1 |
||
246 | # define B_BIG_ENDIAN 0 |
||
247 | # elif __BYTE_ORDER == __BIG_ENDIAN |
||
248 | # define B_LITTLE_ENDIAN 0 |
||
249 | # define B_BIG_ENDIAN 1 |
||
250 | # endif |
||
251 | # define B_ENDIAN_C_INLINE 1 |
||
252 | |||
2916 | terminx | 253 | #elif defined(GEKKO) || defined(__ANDROID__) |
2630 | helixhorne | 254 | # define B_LITTLE_ENDIAN 0 |
255 | # define B_BIG_ENDIAN 1 |
||
256 | # define B_ENDIAN_C_INLINE 1 |
||
257 | |||
2916 | terminx | 258 | #elif defined(__OpenBSD__) |
259 | # include <machine/endian.h> |
||
260 | # if _BYTE_ORDER == _LITTLE_ENDIAN |
||
261 | # define B_LITTLE_ENDIAN 1 |
||
262 | # define B_BIG_ENDIAN 0 |
||
263 | # elif _BYTE_ORDER == _BIG_ENDIAN |
||
264 | # define B_LITTLE_ENDIAN 0 |
||
265 | # define B_BIG_ENDIAN 1 |
||
266 | # endif |
||
267 | # define B_SWAP64(x) __swap64(x) |
||
268 | # define B_SWAP32(x) __swap32(x) |
||
269 | # define B_SWAP16(x) __swap16(x) |
||
270 | |||
5037 | hendricks2 | 271 | #elif defined EDUKE32_BSD |
5 | Plagman | 272 | # include <sys/endian.h> |
273 | # if _BYTE_ORDER == _LITTLE_ENDIAN |
||
274 | # define B_LITTLE_ENDIAN 1 |
||
275 | # define B_BIG_ENDIAN 0 |
||
276 | # elif _BYTE_ORDER == _BIG_ENDIAN |
||
277 | # define B_LITTLE_ENDIAN 0 |
||
278 | # define B_BIG_ENDIAN 1 |
||
279 | # endif |
||
280 | # define B_SWAP64(x) __bswap64(x) |
||
281 | # define B_SWAP32(x) __bswap32(x) |
||
282 | # define B_SWAP16(x) __bswap16(x) |
||
283 | |||
284 | #elif defined(__APPLE__) |
||
4708 | helixhorne | 285 | # if !defined __x86_64__ && defined __GNUC__ |
1935 | helixhorne | 286 | // PK 20110617: is*() crashes for me in x86 code compiled from 64-bit, and gives link errors on ppc |
1905 | helixhorne | 287 | // This hack patches all occurences. |
1907 | helixhorne | 288 | # define isdigit(ch) ({ int32_t c__dontuse_=ch; c__dontuse_>='0' && c__dontuse_<='9'; }) |
289 | # define isalpha(ch) ({ int32_t c__dontuse2_=ch; (c__dontuse2_>='A' && c__dontuse2_<='Z') || (c__dontuse2_>='a' && c__dontuse2_<='z'); }) |
||
290 | # define isalnum(ch2) ({ int32_t c2__dontuse_=ch2; isalpha(c2__dontuse_) || isdigit(c2__dontuse_); }) |
||
1935 | helixhorne | 291 | # if defined __BIG_ENDIAN__ |
292 | # define isspace(ch) ({ int32_t c__dontuse_=ch; (c__dontuse_==' ' || c__dontuse_=='\t' || c__dontuse_=='\n' || c__dontuse_=='\v' || c__dontuse_=='\f' || c__dontuse_=='\r'); }) |
||
293 | # define isprint(ch) ({ int32_t c__dontuse_=ch; (c__dontuse_>=0x20 && c__dontuse_<0x7f); }) |
||
294 | # undef ERRprintf |
||
295 | # define ERRprintf(fmt, ...) printf(fmt, ## __VA_ARGS__) |
||
296 | # endif |
||
1905 | helixhorne | 297 | # endif |
5 | Plagman | 298 | # if defined(__LITTLE_ENDIAN__) |
299 | # define B_LITTLE_ENDIAN 1 |
||
300 | # define B_BIG_ENDIAN 0 |
||
301 | # elif defined(__BIG_ENDIAN__) |
||
302 | # define B_LITTLE_ENDIAN 0 |
||
303 | # define B_BIG_ENDIAN 1 |
||
304 | # endif |
||
305 | # include <libkern/OSByteOrder.h> |
||
306 | # define B_SWAP64(x) OSSwapConstInt64(x) |
||
307 | # define B_SWAP32(x) OSSwapConstInt32(x) |
||
308 | # define B_SWAP16(x) OSSwapConstInt16(x) |
||
309 | |||
310 | #elif defined(__BEOS__) |
||
311 | # include <posix/endian.h> |
||
312 | # if LITTLE_ENDIAN != 0 |
||
313 | # define B_LITTLE_ENDIAN 1 |
||
314 | # define B_BIG_ENDIAN 0 |
||
315 | # elif BIG_ENDIAN != 0 |
||
316 | # define B_LITTLE_ENDIAN 0 |
||
317 | # define B_BIG_ENDIAN 1 |
||
318 | # endif |
||
319 | # define B_ENDIAN_C_INLINE 1 |
||
320 | |||
321 | #elif defined(__QNX__) |
||
322 | # if defined __LITTLEENDIAN__ |
||
323 | # define B_LITTLE_ENDIAN 1 |
||
324 | # define B_BIG_ENDIAN 0 |
||
325 | # elif defined __BIGENDIAN__ |
||
326 | # define B_LITTLE_ENDIAN 0 |
||
327 | # define B_BIG_ENDIAN 1 |
||
328 | # endif |
||
329 | # define B_ENDIAN_C_INLINE 1 |
||
330 | |||
331 | #elif defined(__sun) |
||
332 | # if defined _LITTLE_ENDIAN |
||
333 | # define B_LITTLE_ENDIAN 1 |
||
334 | # define B_BIG_ENDIAN 0 |
||
335 | # elif defined _BIG_ENDIAN |
||
336 | # define B_LITTLE_ENDIAN 0 |
||
337 | # define B_BIG_ENDIAN 1 |
||
338 | # endif |
||
339 | # define B_ENDIAN_C_INLINE 1 |
||
340 | |||
341 | #elif defined(_WIN32) || defined(SKYOS) || defined(__SYLLABLE__) |
||
342 | # define B_LITTLE_ENDIAN 1 |
||
343 | # define B_BIG_ENDIAN 0 |
||
344 | # define B_ENDIAN_C_INLINE 1 |
||
345 | #endif |
||
346 | |||
347 | #if !defined(B_LITTLE_ENDIAN) || !defined(B_BIG_ENDIAN) |
||
348 | # error Unknown endianness |
||
349 | #endif |
||
350 | |||
4893 | terminx | 351 | #if defined _LP64 || defined __LP64__ || defined __64BIT__ || _ADDR64 || defined _WIN64 || defined __arch64__ || \ |
352 | __WORDSIZE == 64 || (defined __sparc && defined __sparcv9) || defined __x86_64 || defined __amd64 || \ |
||
353 | defined __x86_64__ || defined __amd64__ || defined _M_X64 || defined _M_IA64 || defined __ia64 || defined __IA64__ |
||
354 | |||
4274 | hendricks2 | 355 | # define BITNESS64 |
4893 | terminx | 356 | |
4274 | hendricks2 | 357 | #endif |
358 | |||
4766 | hendricks2 | 359 | #ifdef __cplusplus |
285 | terminx | 360 | |
361 | # ifndef SCREWED_UP_CPP |
||
1124 | terminx | 362 | // using namespace std; |
285 | terminx | 363 | # endif |
364 | |||
5 | Plagman | 365 | extern "C" { |
366 | #endif |
||
367 | |||
368 | #if defined B_ENDIAN_X86_INLINE |
||
369 | # if defined(_MSC_VER) |
||
370 | // inline asm using bswap/xchg |
||
371 | # elif defined(__GNUC__) |
||
372 | // inline asm using bswap/xchg |
||
373 | # endif |
||
374 | #elif defined B_ENDIAN_C_INLINE |
||
4743 | terminx | 375 | FORCE_INLINE uint16_t B_SWAP16(uint16_t s) { return (s >> 8) | (s << 8); } |
376 | FORCE_INLINE uint32_t B_SWAP32(uint32_t l) |
||
4716 | terminx | 377 | { |
378 | return ((l >> 8) & 0xff00) | ((l & 0xff00) << 8) | (l << 24) | (l >> 24); |
||
379 | } |
||
4743 | terminx | 380 | FORCE_INLINE uint64_t B_SWAP64(uint64_t l) |
4716 | terminx | 381 | { |
382 | return (l >> 56) | ((l >> 40) & 0xff00) | ((l >> 24) & 0xff0000) | ((l >> 8) & 0xff000000) | |
||
383 | ((l & 255) << 56) | ((l & 0xff00) << 40) | ((l & 0xff0000) << 24) | ((l & 0xff000000) << 8); |
||
384 | } |
||
5 | Plagman | 385 | #endif |
386 | |||
4743 | terminx | 387 | FORCE_INLINE void B_BUF16(uint8_t *buf, uint16_t x) |
4322 | hendricks2 | 388 | { |
389 | buf[0] = (x & 0x00FF); |
||
390 | buf[1] = (x & 0xFF00) >> 8; |
||
391 | } |
||
4743 | terminx | 392 | FORCE_INLINE void B_BUF32(uint8_t *buf, uint32_t x) |
4322 | hendricks2 | 393 | { |
394 | buf[0] = (x & 0x000000FF); |
||
395 | buf[1] = (x & 0x0000FF00) >> 8; |
||
396 | buf[2] = (x & 0x00FF0000) >> 16; |
||
397 | buf[3] = (x & 0xFF000000) >> 24; |
||
398 | } |
||
4768 | hendricks2 | 399 | #if 0 |
400 | // i686-apple-darwin11-llvm-gcc-4.2 complains "integer constant is too large for 'long' type" |
||
4743 | terminx | 401 | FORCE_INLINE void B_BUF64(uint8_t *buf, uint64_t x) |
4322 | hendricks2 | 402 | { |
403 | buf[0] = (x & 0x00000000000000FF); |
||
404 | buf[1] = (x & 0x000000000000FF00) >> 8; |
||
405 | buf[2] = (x & 0x0000000000FF0000) >> 16; |
||
406 | buf[3] = (x & 0x00000000FF000000) >> 24; |
||
407 | buf[4] = (x & 0x000000FF00000000) >> 32; |
||
408 | buf[5] = (x & 0x0000FF0000000000) >> 40; |
||
409 | buf[6] = (x & 0x00FF000000000000) >> 48; |
||
410 | buf[7] = (x & 0xFF00000000000000) >> 56; |
||
411 | } |
||
4768 | hendricks2 | 412 | #endif |
4322 | hendricks2 | 413 | |
4743 | terminx | 414 | FORCE_INLINE uint16_t B_UNBUF16(const uint8_t *buf) { return (buf[1] << 8) | (buf[0]); } |
415 | FORCE_INLINE uint32_t B_UNBUF32(const uint8_t *buf) |
||
4716 | terminx | 416 | { |
417 | return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | (buf[0]); |
||
418 | } |
||
4743 | terminx | 419 | FORCE_INLINE uint64_t B_UNBUF64(const uint8_t *buf) |
4716 | terminx | 420 | { |
421 | return ((uint64_t)buf[7] << 56) | ((uint64_t)buf[6] << 48) | ((uint64_t)buf[5] << 40) | |
||
422 | ((uint64_t)buf[4] << 32) | (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | (buf[0]); |
||
423 | } |
||
4322 | hendricks2 | 424 | |
5013 | terminx | 425 | #if defined BITNESS64 && (defined __SSE2__ || defined _MSC_VER) |
4658 | terminx | 426 | #include <emmintrin.h> |
4743 | terminx | 427 | FORCE_INLINE int32_t Blrintf(const float x) |
1454 | terminx | 428 | { |
4658 | terminx | 429 | __m128 xx = _mm_load_ss(&x); |
430 | return _mm_cvtss_si32(xx); |
||
1454 | terminx | 431 | } |
4658 | terminx | 432 | #elif defined (_MSC_VER) |
4743 | terminx | 433 | FORCE_INLINE int32_t Blrintf(const float x) |
1454 | terminx | 434 | { |
4658 | terminx | 435 | int n; |
436 | __asm fld x; |
||
437 | __asm fistp n; |
||
438 | return n; |
||
1454 | terminx | 439 | } |
440 | #else |
||
4685 | hendricks2 | 441 | #include <math.h> |
4658 | terminx | 442 | #define Blrintf lrintf |
1454 | terminx | 443 | #endif |
444 | |||
5 | Plagman | 445 | #if B_LITTLE_ENDIAN == 1 |
446 | # define B_LITTLE64(x) (x) |
||
447 | # define B_BIG64(x) B_SWAP64(x) |
||
448 | # define B_LITTLE32(x) (x) |
||
449 | # define B_BIG32(x) B_SWAP32(x) |
||
450 | # define B_LITTLE16(x) (x) |
||
451 | # define B_BIG16(x) B_SWAP16(x) |
||
452 | #elif B_BIG_ENDIAN == 1 |
||
453 | # define B_LITTLE64(x) B_SWAP64(x) |
||
454 | # define B_BIG64(x) (x) |
||
455 | # define B_LITTLE32(x) B_SWAP32(x) |
||
456 | # define B_BIG32(x) (x) |
||
457 | # define B_LITTLE16(x) B_SWAP16(x) |
||
458 | # define B_BIG16(x) (x) |
||
459 | #endif |
||
460 | |||
461 | #ifndef FP_OFF |
||
714 | qbix79 | 462 | # define FP_OFF(__p) ((uintptr_t)(__p)) |
5 | Plagman | 463 | #endif |
464 | |||
4747 | terminx | 465 | #ifdef compat_h_macrodef__ |
5 | Plagman | 466 | |
467 | # ifndef O_BINARY |
||
468 | # define O_BINARY 0 |
||
469 | # endif |
||
470 | # ifndef O_TEXT |
||
471 | # define O_TEXT 0 |
||
472 | # endif |
||
473 | |||
474 | # ifndef F_OK |
||
475 | # define F_OK 0 |
||
476 | # endif |
||
477 | |||
478 | # define BO_BINARY O_BINARY |
||
479 | # define BO_TEXT O_TEXT |
||
480 | # define BO_RDONLY O_RDONLY |
||
481 | # define BO_WRONLY O_WRONLY |
||
482 | # define BO_RDWR O_RDWR |
||
483 | # define BO_APPEND O_APPEND |
||
484 | # define BO_CREAT O_CREAT |
||
485 | # define BO_TRUNC O_TRUNC |
||
486 | # define BS_IRGRP S_IRGRP |
||
487 | # define BS_IWGRP S_IWGRP |
||
488 | # define BS_IEXEC S_IEXEC |
||
2916 | terminx | 489 | # ifdef __ANDROID__ |
490 | # define BS_IWRITE S_IWUSR |
||
491 | # define BS_IREAD S_IRUSR |
||
492 | # else |
||
493 | # define BS_IWRITE S_IWRITE |
||
494 | # define BS_IREAD S_IREAD |
||
495 | # endif |
||
5 | Plagman | 496 | # define BS_IFIFO S_IFIFO |
497 | # define BS_IFCHR S_IFCHR |
||
498 | # define BS_IFBLK S_IFBLK |
||
499 | # define BS_IFDIR S_IFDIR |
||
500 | # define BS_IFREG S_IFREG |
||
501 | # define BSEEK_SET SEEK_SET |
||
502 | # define BSEEK_CUR SEEK_CUR |
||
503 | # define BSEEK_END SEEK_END |
||
504 | #else |
||
505 | # define BO_BINARY 0 |
||
506 | # define BO_TEXT 1 |
||
507 | # define BO_RDONLY 2 |
||
508 | # define BO_WRONLY 4 |
||
509 | # define BO_RDWR 6 |
||
510 | # define BO_APPEND 8 |
||
511 | # define BO_CREAT 16 |
||
512 | # define BO_TRUNC 32 |
||
513 | # define BS_IRGRP 0 |
||
514 | # define BS_IWGRP 0 |
||
515 | # define BS_IEXEC 1 |
||
516 | # define BS_IWRITE 2 |
||
517 | # define BS_IREAD 4 |
||
518 | # define BS_IFIFO 0x1000 |
||
519 | # define BS_IFCHR 0x2000 |
||
520 | # define BS_IFBLK 0x3000 |
||
521 | # define BS_IFDIR 0x4000 |
||
522 | # define BS_IFREG 0x8000 |
||
523 | # define BSEEK_SET 0 |
||
524 | # define BSEEK_CUR 1 |
||
525 | # define BSEEK_END 2 |
||
526 | #endif |
||
527 | |||
528 | #ifdef UNDERSCORES |
||
529 | # define ASMSYM(x) "_" x |
||
530 | #else |
||
531 | # define ASMSYM(x) x |
||
532 | #endif |
||
533 | |||
534 | #ifndef min |
||
4716 | terminx | 535 | # define min(a, b) (((a) < (b)) ? (a) : (b)) |
5 | Plagman | 536 | #endif |
537 | |||
538 | #ifndef max |
||
4716 | terminx | 539 | # define max(a, b) (((a) > (b)) ? (a) : (b)) |
5 | Plagman | 540 | #endif |
541 | |||
1854 | helixhorne | 542 | #if __GNUC__ >= 4 |
4743 | terminx | 543 | # define CLAMP_DECL FORCE_INLINE __attribute__((warn_unused_result)) |
1854 | helixhorne | 544 | #else |
4743 | terminx | 545 | # define CLAMP_DECL FORCE_INLINE |
1854 | helixhorne | 546 | #endif |
3780 | helixhorne | 547 | |
548 | // Clamp <in> to [<min>..<max>]. The case in <= min is handled first. |
||
4893 | terminx | 549 | CLAMP_DECL int32_t clamp(int32_t in, int32_t min, int32_t max) { return in <= min ? min : (in >= max ? max : in); } |
5 | Plagman | 550 | |
3780 | helixhorne | 551 | // Clamp <in> to [<min>..<max>]. The case in >= max is handled first. |
4893 | terminx | 552 | CLAMP_DECL int32_t clamp2(int32_t in, int32_t min, int32_t max) { return in >= max ? max : (in <= min ? min : in); } |
3780 | helixhorne | 553 | |
4431 | terminx | 554 | // Clamp <in> to [<min>..<max>]. The case in <= min is handled first. |
4893 | terminx | 555 | CLAMP_DECL float fclamp(float in, float min, float max) { return in <= min ? min : (in >= max ? max : in); } |
4431 | terminx | 556 | |
557 | // Clamp <in> to [<min>..<max>]. The case in >= max is handled first. |
||
4893 | terminx | 558 | CLAMP_DECL float fclamp2(float in, float min, float max) { return in >= max ? max : (in <= min ? min : in); } |
4431 | terminx | 559 | |
1457 | terminx | 560 | #define BMAX_PATH 256 |
5 | Plagman | 561 | |
5075 | terminx | 562 | /* Static assertions, based on source found in LuaJIT's src/lj_def.h. */ |
563 | #define EDUKE32_ASSERT_NAME2(name, line) name ## line |
||
564 | #define EDUKE32_ASSERT_NAME(line) EDUKE32_ASSERT_NAME2(eduke32_assert_, line) |
||
565 | #ifdef __COUNTER__ |
||
566 | # define EDUKE32_STATIC_ASSERT(cond) \ |
||
567 | extern void EDUKE32_ASSERT_NAME(__COUNTER__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1]) |
||
568 | #else |
||
569 | # define EDUKE32_STATIC_ASSERT(cond) \ |
||
570 | extern void EDUKE32_ASSERT_NAME(__LINE__)(int STATIC_ASSERTION_FAILED[(cond)?1:-1]) |
||
571 | #endif |
||
5 | Plagman | 572 | |
4716 | terminx | 573 | struct Bdirent |
574 | { |
||
575 | uint16_t namlen; |
||
576 | char *name; |
||
577 | uint32_t mode; |
||
578 | uint32_t size; |
||
579 | uint32_t mtime; |
||
5 | Plagman | 580 | }; |
581 | typedef void BDIR; |
||
582 | |||
4716 | terminx | 583 | BDIR *Bopendir(const char *name); |
584 | struct Bdirent *Breaddir(BDIR *dir); |
||
585 | int32_t Bclosedir(BDIR *dir); |
||
5 | Plagman | 586 | |
3411 | terminx | 587 | #ifdef _MSC_VER |
588 | typedef intptr_t ssize_t; |
||
589 | #endif |
||
5 | Plagman | 590 | |
4747 | terminx | 591 | #ifdef compat_h_macrodef__ |
285 | terminx | 592 | typedef FILE BFILE; |
5 | Plagman | 593 | # define bsize_t size_t |
594 | # define bssize_t ssize_t |
||
595 | #else |
||
285 | terminx | 596 | typedef void BFILE; |
1205 | terminx | 597 | typedef uint32_t bsize_t; |
1346 | terminx | 598 | typedef int32_t bssize_t; |
5 | Plagman | 599 | #endif |
600 | |||
4853 | hendricks2 | 601 | |
602 | typedef struct { |
||
603 | int32_t x, y; |
||
604 | } vec2_t; |
||
605 | |||
606 | typedef struct { |
||
607 | int32_t x, y, z; |
||
608 | } vec3_t; |
||
609 | |||
610 | typedef struct { |
||
611 | float x, y; |
||
612 | } vec2f_t; |
||
613 | |||
614 | typedef struct { |
||
5075 | terminx | 615 | union { float x; float d; }; |
616 | union { float y; float u; }; |
||
617 | union { float z; float v; }; |
||
4853 | hendricks2 | 618 | } vec3f_t; |
619 | |||
5075 | terminx | 620 | EDUKE32_STATIC_ASSERT(sizeof(vec3f_t) == sizeof(float) * 3); |
4853 | hendricks2 | 621 | |
5075 | terminx | 622 | typedef struct { |
623 | union { double x; double d; }; |
||
624 | union { double y; double u; }; |
||
625 | union { double z; double v; }; |
||
626 | } vec3d_t; |
||
627 | |||
628 | EDUKE32_STATIC_ASSERT(sizeof(vec3d_t) == sizeof(double) * 3); |
||
629 | |||
2105 | helixhorne | 630 | #if RAND_MAX == 32767 |
4743 | terminx | 631 | FORCE_INLINE uint16_t system_15bit_rand(void) { return (uint16_t)rand(); } |
2105 | helixhorne | 632 | #else // RAND_MAX > 32767, assumed to be of the form 2^k - 1 |
4743 | terminx | 633 | FORCE_INLINE uint16_t system_15bit_rand(void) { return ((uint16_t)rand())&0x7fff; } |
2105 | helixhorne | 634 | #endif |
5 | Plagman | 635 | |
2394 | helixhorne | 636 | #if defined(_MSC_VER) |
637 | // XXX: non-__compat_h_macrodef__ version? |
||
638 | #define strtoll _strtoi64 |
||
639 | #endif |
||
640 | |||
4747 | terminx | 641 | #ifdef compat_h_macrodef__ |
2546 | helixhorne | 642 | # define Bassert assert |
5 | Plagman | 643 | # define Brand rand |
644 | # define Balloca alloca |
||
4708 | helixhorne | 645 | # define Bmalloc malloc |
646 | # define Bcalloc calloc |
||
647 | # define Brealloc realloc |
||
648 | # define Bfree free |
||
649 | # if defined(__cplusplus) && defined(_MSC_VER) |
||
4697 | terminx | 650 | # define Bstrdup _strdup |
4708 | helixhorne | 651 | # define Bchdir _chdir |
652 | # define Bgetcwd _getcwd |
||
653 | # else |
||
2105 | helixhorne | 654 | # define Bstrdup strdup |
4708 | helixhorne | 655 | # define Bchdir chdir |
656 | # define Bgetcwd getcwd |
||
657 | # endif |
||
5 | Plagman | 658 | # define Bopen open |
659 | # define Bclose close |
||
660 | # define Bwrite write |
||
661 | # define Bread read |
||
662 | # define Blseek lseek |
||
663 | # if defined(__GNUC__) |
||
664 | # define Btell(h) lseek(h,0,SEEK_CUR) |
||
665 | # else |
||
666 | # define Btell tell |
||
667 | # endif |
||
3168 | helixhorne | 668 | # ifdef _MSC_VER |
4708 | helixhorne | 669 | # define Bstat stat |
670 | # define Bfstat fstat |
||
3168 | helixhorne | 671 | # else |
4708 | helixhorne | 672 | # define Bstat stat |
673 | # define Bfstat fstat |
||
3168 | helixhorne | 674 | # endif |
3163 | hendricks2 | 675 | # define Bfileno fileno |
676 | # define Bferror ferror |
||
5 | Plagman | 677 | # define Bfopen fopen |
678 | # define Bfclose fclose |
||
2725 | hendricks2 | 679 | # define Bfflush fflush |
5 | Plagman | 680 | # define Bfeof feof |
681 | # define Bfgetc fgetc |
||
682 | # define Brewind rewind |
||
683 | # define Bfgets fgets |
||
684 | # define Bfputc fputc |
||
685 | # define Bfputs fputs |
||
686 | # define Bfread fread |
||
687 | # define Bfwrite fwrite |
||
688 | # define Bfprintf fprintf |
||
2493 | hendricks2 | 689 | # define Bfscanf fscanf |
690 | # define Bfseek fseek |
||
2521 | hendricks2 | 691 | # define Bftell ftell |
692 | # define Bputs puts |
||
5 | Plagman | 693 | # define Bstrcpy strcpy |
694 | # define Bstrncpy strncpy |
||
695 | # define Bstrcmp strcmp |
||
696 | # define Bstrncmp strncmp |
||
4802 | hendricks2 | 697 | # if defined(_MSC_VER) |
1454 | terminx | 698 | # define Bstrcasecmp _stricmp |
699 | # define Bstrncasecmp _strnicmp |
||
4708 | helixhorne | 700 | # elif defined(__QNX__) |
5 | Plagman | 701 | # define Bstrcasecmp stricmp |
702 | # define Bstrncasecmp strnicmp |
||
703 | # else |
||
704 | # define Bstrcasecmp strcasecmp |
||
705 | # define Bstrncasecmp strncasecmp |
||
706 | # endif |
||
707 | # if defined(_WIN32) |
||
708 | # define Bstrlwr strlwr |
||
709 | # define Bstrupr strupr |
||
710 | # define Bmkdir(s,x) mkdir(s) |
||
711 | # else |
||
712 | # define Bmkdir mkdir |
||
713 | # endif |
||
714 | # define Bstrcat strcat |
||
715 | # define Bstrncat strncat |
||
716 | # define Bstrlen strlen |
||
717 | # define Bstrchr strchr |
||
718 | # define Bstrrchr strrchr |
||
2412 | helixhorne | 719 | // XXX: different across 32- and 64-bit archs (e.g. |
720 | // parsing the decimal representation of 0xffffffff, |
||
721 | // 4294967295 -- long is signed, so strtol would |
||
722 | // return LONG_MAX (== 0x7fffffff on 32-bit archs)) |
||
2374 | helixhorne | 723 | # define Batoi(str) ((int32_t)strtol(str, NULL, 10)) |
724 | # define Batol(str) (strtol(str, NULL, 10)) |
||
2521 | hendricks2 | 725 | # define Batof(str) (strtod(str, NULL)) |
5 | Plagman | 726 | # define Bstrtol strtol |
727 | # define Bstrtoul strtoul |
||
728 | # define Bstrtod strtod |
||
1763 | terminx | 729 | # define Bstrstr strstr |
3833 | hendricks2 | 730 | # define Bislower islower |
731 | # define Bisupper isupper |
||
732 | # define Bisdigit isdigit |
||
5 | Plagman | 733 | # define Btoupper toupper |
734 | # define Btolower tolower |
||
735 | # define Bmemcpy memcpy |
||
736 | # define Bmemmove memmove |
||
737 | # define Bmemchr memchr |
||
738 | # define Bmemset memset |
||
739 | # define Bmemcmp memcmp |
||
2521 | hendricks2 | 740 | # define Bscanf scanf |
5 | Plagman | 741 | # define Bprintf printf |
2521 | hendricks2 | 742 | # define Bsscanf sscanf |
5 | Plagman | 743 | # define Bsprintf sprintf |
744 | # ifdef _MSC_VER |
||
745 | # define Bsnprintf _snprintf |
||
746 | # define Bvsnprintf _vsnprintf |
||
747 | # else |
||
748 | # define Bsnprintf snprintf |
||
749 | # define Bvsnprintf vsnprintf |
||
750 | # endif |
||
751 | # define Bvfprintf vfprintf |
||
752 | # define Bgetenv getenv |
||
753 | # define Btime() time(NULL) |
||
3293 | hendricks2 | 754 | # define Butime utime |
5 | Plagman | 755 | |
756 | #else |
||
757 | |||
2546 | helixhorne | 758 | void Bassert(int); |
1205 | terminx | 759 | int32_t Brand(void); |
5 | Plagman | 760 | void *Bmalloc(bsize_t size); |
761 | void Bfree(void *ptr); |
||
1205 | terminx | 762 | int32_t Bopen(const char *pathname, int32_t flags, unsigned mode); |
763 | int32_t Bclose(int32_t fd); |
||
764 | bssize_t Bwrite(int32_t fd, const void *buf, bsize_t count); |
||
765 | bssize_t Bread(int32_t fd, void *buf, bsize_t count); |
||
766 | int32_t Blseek(int32_t fildes, int32_t offset, int32_t whence); |
||
5 | Plagman | 767 | BFILE *Bfopen(const char *path, const char *mode); |
1205 | terminx | 768 | int32_t Bfclose(BFILE *stream); |
769 | int32_t Bfeof(BFILE *stream); |
||
770 | int32_t Bfgetc(BFILE *stream); |
||
5 | Plagman | 771 | void Brewind(BFILE *stream); |
1205 | terminx | 772 | char *Bfgets(char *s, int32_t size, BFILE *stream); |
773 | int32_t Bfputc(int32_t c, BFILE *stream); |
||
774 | int32_t Bfputs(const char *s, BFILE *stream); |
||
5 | Plagman | 775 | bsize_t Bfread(void *ptr, bsize_t size, bsize_t nmemb, BFILE *stream); |
776 | bsize_t Bfwrite(const void *ptr, bsize_t size, bsize_t nmemb, BFILE *stream); |
||
777 | char *Bstrdup(const char *s); |
||
778 | char *Bstrcpy(char *dest, const char *src); |
||
779 | char *Bstrncpy(char *dest, const char *src, bsize_t n); |
||
1205 | terminx | 780 | int32_t Bstrcmp(const char *s1, const char *s2); |
781 | int32_t Bstrncmp(const char *s1, const char *s2, bsize_t n); |
||
782 | int32_t Bstrcasecmp(const char *s1, const char *s2); |
||
783 | int32_t Bstrncasecmp(const char *s1, const char *s2, bsize_t n); |
||
5 | Plagman | 784 | char *Bstrcat(char *dest, const char *src); |
785 | char *Bstrncat(char *dest, const char *src, bsize_t n); |
||
786 | bsize_t Bstrlen(const char *s); |
||
1205 | terminx | 787 | char *Bstrchr(const char *s, int32_t c); |
788 | char *Bstrrchr(const char *s, int32_t c); |
||
789 | int32_t Batoi(const char *nptr); |
||
790 | int32_t Batol(const char *nptr); |
||
1743 | helixhorne | 791 | int32_t Bstrtol(const char *nptr, char **endptr, int32_t base); |
792 | uint32_t Bstrtoul(const char *nptr, char **endptr, int32_t base); |
||
5 | Plagman | 793 | void *Bmemcpy(void *dest, const void *src, bsize_t n); |
794 | void *Bmemmove(void *dest, const void *src, bsize_t n); |
||
1205 | terminx | 795 | void *Bmemchr(const void *s, int32_t c, bsize_t n); |
796 | void *Bmemset(void *s, int32_t c, bsize_t n); |
||
797 | int32_t Bmemcmp(const void *s1, const void *s2, bsize_t n); |
||
4716 | terminx | 798 | int32_t Bprintf(const char *format, ...) ATTRIBUTE((format(printf, 1, 2))); |
799 | int32_t Bsprintf(char *str, const char *format, ...) ATTRIBUTE((format(printf, 2, 3))); |
||
800 | int32_t Bsnprintf(char *str, bsize_t size, const char *format, ...) ATTRIBUTE((format(printf, 3, 4))); |
||
1205 | terminx | 801 | int32_t Bvsnprintf(char *str, bsize_t size, const char *format, va_list ap); |
5 | Plagman | 802 | char *Bgetcwd(char *buf, bsize_t size); |
803 | char *Bgetenv(const char *name); |
||
804 | #endif |
||
805 | |||
806 | char *Bgethomedir(void); |
||
4801 | hendricks2 | 807 | char *Bgetappdir(void); |
1205 | terminx | 808 | uint32_t Bgetsysmemsize(void); |
809 | int32_t Bcorrectfilename(char *filename, int32_t removefn); |
||
810 | int32_t Bcanonicalisefilename(char *filename, int32_t removefn); |
||
5 | Plagman | 811 | char *Bgetsystemdrives(void); |
1205 | terminx | 812 | int32_t Bfilelength(int32_t fd); |
4893 | terminx | 813 | char *Bstrtoken(char *s, const char *delim, char **ptrptr, int chop); |
2458 | hendricks2 | 814 | char *Bstrtolower(char *str); |
4658 | terminx | 815 | #define Bwildmatch wildmatch |
5 | Plagman | 816 | |
817 | #if !defined(_WIN32) |
||
818 | char *Bstrlwr(char *); |
||
819 | char *Bstrupr(char *); |
||
820 | #endif |
||
821 | |||
3735 | helixhorne | 822 | // Copy min(strlen(src)+1, n) characters into dst, always terminate with a NUL. |
4743 | terminx | 823 | FORCE_INLINE char *Bstrncpyz(char *dst, const char *src, bsize_t n) |
3213 | terminx | 824 | { |
825 | Bstrncpy(dst, src, n); |
||
826 | dst[n-1] = 0; |
||
827 | return dst; |
||
828 | } |
||
829 | |||
3735 | helixhorne | 830 | // Append extension when <outbuf> contains no dot. |
3876 | helixhorne | 831 | // <ext> can be like ".mhk" or like "_crash.map", no need to start with a dot. |
3735 | helixhorne | 832 | // The ugly name is deliberate: we should be checking the sizes of all buffers! |
833 | static inline void append_ext_UNSAFE(char *outbuf, const char *ext) |
||
834 | { |
||
835 | char *p = Bstrrchr(outbuf,'.'); |
||
836 | |||
837 | if (!p) |
||
838 | Bstrcat(outbuf, ext); |
||
839 | else |
||
3876 | helixhorne | 840 | Bstrcpy(p, ext); |
3735 | helixhorne | 841 | } |
842 | |||
4490 | helixhorne | 843 | #ifdef DEBUGGINGAIDS |
844 | extern void xalloc_set_location(int32_t line, const char *file, const char *func); |
||
845 | #endif |
||
846 | void set_memerr_handler(void (*handlerfunc)(int32_t, const char *, const char *)); |
||
4619 | terminx | 847 | void handle_memerr(void); |
4490 | helixhorne | 848 | |
4743 | terminx | 849 | FORCE_INLINE char *xstrdup(const char *s) |
4619 | terminx | 850 | { |
851 | char *ptr = Bstrdup(s); |
||
852 | if (ptr == NULL) handle_memerr(); |
||
853 | return ptr; |
||
854 | } |
||
855 | |||
4743 | terminx | 856 | FORCE_INLINE void *xmalloc(const bsize_t size) |
4619 | terminx | 857 | { |
858 | void *ptr = Bmalloc(size); |
||
859 | if (ptr == NULL) handle_memerr(); |
||
860 | return ptr; |
||
861 | } |
||
862 | |||
4743 | terminx | 863 | FORCE_INLINE void *xcalloc(const bsize_t nmemb, const bsize_t size) |
4619 | terminx | 864 | { |
865 | void *ptr = Bcalloc(nmemb, size); |
||
866 | if (ptr == NULL) handle_memerr(); |
||
867 | return ptr; |
||
868 | } |
||
869 | |||
4743 | terminx | 870 | FORCE_INLINE void *xrealloc(void * const ptr, const bsize_t size) |
4619 | terminx | 871 | { |
872 | void *newptr = Brealloc(ptr, size); |
||
873 | |||
874 | // According to the C Standard, |
||
875 | // - ptr == NULL makes realloc() behave like malloc() |
||
876 | // - size == 0 make it behave like free() if ptr != NULL |
||
877 | // Since we want to catch an out-of-mem in the first case, this leaves: |
||
878 | if (newptr == NULL && size != 0) |
||
879 | handle_memerr(); |
||
880 | |||
881 | return newptr; |
||
882 | } |
||
883 | |||
4743 | terminx | 884 | FORCE_INLINE void *xaligned_malloc(const bsize_t alignment, const bsize_t size) |
4695 | terminx | 885 | { |
886 | #ifdef _WIN32 |
||
887 | void *ptr = _aligned_malloc(size, alignment); |
||
5037 | hendricks2 | 888 | #elif defined __APPLE__ || defined EDUKE32_BSD |
4762 | hendricks2 | 889 | void *ptr = NULL; |
890 | posix_memalign(&ptr, alignment, size); |
||
4695 | terminx | 891 | #else |
892 | void *ptr = memalign(alignment, size); |
||
893 | #endif |
||
4619 | terminx | 894 | |
4695 | terminx | 895 | if (ptr == NULL) handle_memerr(); |
896 | return ptr; |
||
897 | } |
||
898 | |||
899 | |||
4766 | hendricks2 | 900 | #ifdef __cplusplus |
5 | Plagman | 901 | } |
902 | #endif |
||
903 | |||
4442 | terminx | 904 | #define DO_FREE_AND_NULL(var) do { \ |
905 | if (var != NULL) { Bfree(var); var = NULL; } \ |
||
906 | } while (0) |
||
907 | |||
4695 | terminx | 908 | #define ALIGNED_FREE_AND_NULL(var) do { \ |
909 | if (var != NULL) { Baligned_free(var); var = NULL; } \ |
||
910 | } while (0) |
||
911 | |||
2995 | helixhorne | 912 | #define MAYBE_FCLOSE_AND_NULL(fileptr) do { \ |
913 | if (fileptr) { Bfclose(fileptr); fileptr=NULL; } \ |
||
914 | } while (0) |
||
915 | |||
4199 | helixhorne | 916 | #define ARRAY_SIZE(Ar) (sizeof(Ar)/sizeof((Ar)[0])) |
917 | #define ARRAY_SSIZE(Ar) (bssize_t)ARRAY_SIZE(Ar) |
||
918 | |||
4490 | helixhorne | 919 | ////////// PANICKING ALLOCATION MACROS (wrapping the functions) ////////// |
920 | #ifdef DEBUGGINGAIDS |
||
921 | // Detection of __func__ or equivalent functionality, found in SDL_assert.h |
||
922 | # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */ |
||
923 | # define EDUKE32_FUNCTION __func__ |
||
924 | # elif ((__GNUC__ >= 2) || defined(_MSC_VER)) |
||
925 | # define EDUKE32_FUNCTION __FUNCTION__ |
||
926 | # else |
||
927 | # define EDUKE32_FUNCTION "???" |
||
928 | # endif |
||
929 | |||
930 | # define EDUKE32_PRE_XALLLOC xalloc_set_location(__LINE__, __FILE__, EDUKE32_FUNCTION) |
||
931 | # define Xstrdup(s) (EDUKE32_PRE_XALLLOC, xstrdup(s)) |
||
932 | # define Xmalloc(size) (EDUKE32_PRE_XALLLOC, xmalloc(size)) |
||
933 | # define Xcalloc(nmemb, size) (EDUKE32_PRE_XALLLOC, xcalloc(nmemb, size)) |
||
934 | # define Xrealloc(ptr, size) (EDUKE32_PRE_XALLLOC, xrealloc(ptr, size)) |
||
4695 | terminx | 935 | # define Xaligned_alloc(size, alignment) (EDUKE32_PRE_XALLLOC, xaligned_malloc(size, alignment)) |
4502 | hendricks2 | 936 | # define Bexit(status) do { initprintf("exit(%d) at %s:%d in %s()\n", status, __FILE__, __LINE__, EDUKE32_FUNCTION); exit(status); } while (0) |
4490 | helixhorne | 937 | #else |
938 | # define Xstrdup xstrdup |
||
939 | # define Xmalloc xmalloc |
||
940 | # define Xcalloc xcalloc |
||
941 | # define Xrealloc xrealloc |
||
4736 | helixhorne | 942 | # define Xaligned_alloc xaligned_malloc |
4502 | hendricks2 | 943 | # define Bexit exit |
4490 | helixhorne | 944 | #endif |
4695 | terminx | 945 | |
946 | #ifdef _WIN32 |
||
947 | # define Baligned_free(ptr) _aligned_free(ptr) |
||
948 | #else |
||
949 | # define Baligned_free(ptr) Bfree(ptr) |
||
950 | #endif |
||
951 | |||
4490 | helixhorne | 952 | ////////// |
953 | |||
4747 | terminx | 954 | #endif // compat_h_ |