Subversion Repositories eduke32

Rev

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_