Subversion Repositories eduke32

Rev

Rev 8648 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8648 Rev 8762
1
// Compatibility declarations for things which might not be present in
1
// Compatibility declarations for things which might not be present in
2
// certain build environments. It also levels the playing field caused
2
// certain build environments. It also levels the playing field caused
3
// by different platforms.
3
// by different platforms.
4
4
5
#ifndef compat_h_
5
#ifndef compat_h_
6
#define compat_h_
6
#define compat_h_
7
7
8
#pragma once
8
#pragma once
9
9
10
#ifdef _WIN32
10
#ifdef _WIN32
11
# include "windows_inc.h"
11
# include "windows_inc.h"
12
#endif
12
#endif
13
13
14
////////// Compiler detection //////////
14
////////// Compiler detection //////////
15
15
16
#ifdef __GNUC__
16
#ifdef __GNUC__
17
# define EDUKE32_GCC_PREREQ(major, minor) (major < __GNUC__ || (major == __GNUC__ && minor <= __GNUC_MINOR__))
17
# define EDUKE32_GCC_PREREQ(major, minor) (major < __GNUC__ || (major == __GNUC__ && minor <= __GNUC_MINOR__))
18
#else
18
#else
19
# define EDUKE32_GCC_PREREQ(major, minor) 0
19
# define EDUKE32_GCC_PREREQ(major, minor) 0
20
#endif
20
#endif
21
21
22
#ifdef __clang__
22
#ifdef __clang__
23
# define EDUKE32_CLANG_PREREQ(major, minor) (major < __clang_major__ || (major == __clang_major__ && minor <= __clang_minor__))
23
# define EDUKE32_CLANG_PREREQ(major, minor) (major < __clang_major__ || (major == __clang_major__ && minor <= __clang_minor__))
24
#else
24
#else
25
# define EDUKE32_CLANG_PREREQ(major, minor) 0
25
# define EDUKE32_CLANG_PREREQ(major, minor) 0
26
#endif
26
#endif
27
#ifndef __has_builtin
27
#ifndef __has_builtin
28
# define __has_builtin(x) 0  // Compatibility with non-clang compilers.
28
# define __has_builtin(x) 0  // Compatibility with non-clang compilers.
29
#endif
29
#endif
30
#ifndef __has_feature
30
#ifndef __has_feature
31
# define __has_feature(x) 0  // Compatibility with non-clang compilers.
31
# define __has_feature(x) 0  // Compatibility with non-clang compilers.
32
#endif
32
#endif
33
#ifndef __has_extension
33
#ifndef __has_extension
34
# define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
34
# define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
35
#endif
35
#endif
36
#ifndef __has_cpp_attribute
36
#ifndef __has_cpp_attribute
37
# define __has_cpp_attribute(x) 0
37
# define __has_cpp_attribute(x) 0
38
#endif
38
#endif
39
39
40
#ifdef _MSC_VER
40
#ifdef _MSC_VER
41
# define EDUKE32_MSVC_PREREQ(major) ((major) <= (_MSC_VER))
41
# define EDUKE32_MSVC_PREREQ(major) ((major) <= (_MSC_VER))
42
# ifdef __cplusplus
42
# ifdef __cplusplus
43
#  define EDUKE32_MSVC_CXX_PREREQ(major) ((major) <= (_MSC_VER))
43
#  define EDUKE32_MSVC_CXX_PREREQ(major) ((major) <= (_MSC_VER))
44
# else
44
# else
45
#  define EDUKE32_MSVC_CXX_PREREQ(major) 0
45
#  define EDUKE32_MSVC_CXX_PREREQ(major) 0
46
# endif
46
# endif
47
#else
47
#else
48
# define EDUKE32_MSVC_PREREQ(major) 0
48
# define EDUKE32_MSVC_PREREQ(major) 0
49
# define EDUKE32_MSVC_CXX_PREREQ(major) 0
49
# define EDUKE32_MSVC_CXX_PREREQ(major) 0
50
#endif
50
#endif
51
51
52
52
53
////////// Language detection //////////
53
////////// Language detection //////////
54
54
55
#if defined __STDC__
55
#if defined __STDC__
56
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
56
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
57
#  define CSTD 2011
57
#  define CSTD 2011
58
# elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
58
# elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
59
#  define CSTD 1999
59
#  define CSTD 1999
60
# elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199409L
60
# elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199409L
61
#  define CSTD 1994
61
#  define CSTD 1994
62
# else
62
# else
63
#  define CSTD 1989
63
#  define CSTD 1989
64
# endif
64
# endif
65
#else
65
#else
66
# define CSTD 0
66
# define CSTD 0
67
#endif
67
#endif
68
68
69
#if defined __cplusplus && __cplusplus >= 201703L
69
#if defined __cplusplus && __cplusplus >= 201703L
70
# define CXXSTD 2017
70
# define CXXSTD 2017
71
#elif defined __cplusplus && __cplusplus >= 201402L
71
#elif defined __cplusplus && __cplusplus >= 201402L
72
# define CXXSTD 2014
72
# define CXXSTD 2014
73
#elif defined __cplusplus && __cplusplus >= 201103L
73
#elif defined __cplusplus && __cplusplus >= 201103L
74
# define CXXSTD 2011
74
# define CXXSTD 2011
75
#elif defined __cplusplus && __cplusplus >= 199711L
75
#elif defined __cplusplus && __cplusplus >= 199711L
76
# define CXXSTD 1998
76
# define CXXSTD 1998
77
#else
77
#else
78
# define CXXSTD 0
78
# define CXXSTD 0
79
#endif
79
#endif
80
80
81
81
82
////////// Language and compiler feature polyfills //////////
82
////////// Language and compiler feature polyfills //////////
83
83
84
#ifdef __cplusplus
84
#ifdef __cplusplus
85
# define EXTERNC extern "C"
85
# define EXTERNC extern "C"
86
#else
86
#else
87
# define EXTERNC
87
# define EXTERNC
88
#endif
88
#endif
89
89
90
#ifndef UNREFERENCED_PARAMETER
90
#ifndef UNREFERENCED_PARAMETER
91
# define UNREFERENCED_PARAMETER(x) (x) = (x)
91
# define UNREFERENCED_PARAMETER(x) (x) = (x)
92
#endif
92
#endif
93
93
94
#ifndef UNREFERENCED_CONST_PARAMETER
94
#ifndef UNREFERENCED_CONST_PARAMETER
95
# ifdef _MSC_VER
95
# ifdef _MSC_VER
96
#  define UNREFERENCED_CONST_PARAMETER(x) ((void)(x))
96
#  define UNREFERENCED_CONST_PARAMETER(x) ((void)(x))
97
# else
97
# else
98
#  define UNREFERENCED_CONST_PARAMETER(x)
98
#  define UNREFERENCED_CONST_PARAMETER(x)
99
# endif
99
# endif
100
#endif
100
#endif
101
101
102
#ifdef __GNUC__
102
#ifdef __GNUC__
103
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
103
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
104
# define PRINTF_FORMAT(stringindex, firstargindex) __attribute__((format (printf, stringindex, firstargindex)))
104
# define PRINTF_FORMAT(stringindex, firstargindex) __attribute__((format (printf, stringindex, firstargindex)))
105
#else
105
#else
106
# define UNUSED(x) x
106
# define UNUSED(x) x
107
# define PRINTF_FORMAT(stringindex, firstargindex)
107
# define PRINTF_FORMAT(stringindex, firstargindex)
108
#endif
108
#endif
109
109
110
#if defined __GNUC__ || defined __clang__
110
#if defined __GNUC__ || defined __clang__
111
# define ATTRIBUTE(attrlist) __attribute__(attrlist)
111
# define ATTRIBUTE(attrlist) __attribute__(attrlist)
112
#else
112
#else
113
# define ATTRIBUTE(attrlist)
113
# define ATTRIBUTE(attrlist)
114
#endif
114
#endif
115
115
116
#if !defined __clang__ && !defined USING_LTO
116
#if !defined __clang__ && !defined USING_LTO
117
# define ATTRIBUTE_OPTIMIZE(str) ATTRIBUTE((optimize(str)))
117
# define ATTRIBUTE_OPTIMIZE(str) ATTRIBUTE((optimize(str)))
118
#else
118
#else
119
# define ATTRIBUTE_OPTIMIZE(str)
119
# define ATTRIBUTE_OPTIMIZE(str)
120
#endif
120
#endif
121
121
122
#if EDUKE32_GCC_PREREQ(4,0)
122
#if EDUKE32_GCC_PREREQ(4,0)
123
# define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
123
# define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
124
#else
124
#else
125
# define WARN_UNUSED_RESULT
125
# define WARN_UNUSED_RESULT
126
#endif
126
#endif
127
127
128
#if defined _MSC_VER && _MSC_VER < 1800
128
#if defined _MSC_VER && _MSC_VER < 1800
129
# define inline __inline
129
# define inline __inline
130
#endif
130
#endif
131
131
132
#ifndef MAY_ALIAS
132
#ifndef MAY_ALIAS
133
# ifdef _MSC_VER
133
# ifdef _MSC_VER
134
#  define MAY_ALIAS
134
#  define MAY_ALIAS
135
# else
135
# else
136
#  define MAY_ALIAS __attribute__((may_alias))
136
#  define MAY_ALIAS __attribute__((may_alias))
137
# endif
137
# endif
138
#endif
138
#endif
139
139
140
#ifndef FORCE_INLINE
140
#ifndef FORCE_INLINE
141
# ifdef _MSC_VER
141
# ifdef _MSC_VER
142
#  define FORCE_INLINE __forceinline
142
#  define FORCE_INLINE __forceinline
143
# else
143
# else
144
#  ifdef __GNUC__
144
#  ifdef __GNUC__
145
#    define FORCE_INLINE inline __attribute__((always_inline))
145
#    define FORCE_INLINE inline __attribute__((always_inline))
146
#  else
146
#  else
147
#    define FORCE_INLINE inline
147
#    define FORCE_INLINE inline
148
#  endif
148
#  endif
149
# endif
149
# endif
150
#endif
150
#endif
151
151
152
#ifndef _MSC_VER
152
#ifndef _MSC_VER
153
#  ifndef __fastcall
153
#  ifndef __fastcall
154
#    if defined(__GNUC__) && defined(__i386__)
154
#    if defined(__GNUC__) && defined(__i386__)
155
#      define __fastcall __attribute__((fastcall))
155
#      define __fastcall __attribute__((fastcall))
156
#    else
156
#    else
157
#      define __fastcall
157
#      define __fastcall
158
#    endif
158
#    endif
159
#  endif
159
#  endif
160
#endif
160
#endif
161
161
162
#ifndef DISABLE_INLINING
162
#ifndef DISABLE_INLINING
163
# define EXTERN_INLINE static inline
163
# define EXTERN_INLINE static inline
164
# define EXTERN_INLINE_HEADER static inline
164
# define EXTERN_INLINE_HEADER static inline
165
#else
165
#else
166
# define EXTERN_INLINE __fastcall
166
# define EXTERN_INLINE __fastcall
167
# define EXTERN_INLINE_HEADER extern __fastcall
167
# define EXTERN_INLINE_HEADER extern __fastcall
168
#endif
168
#endif
169
169
170
#if 0 && defined(__OPTIMIZE__) && (defined __GNUC__ || __has_builtin(__builtin_expect))
170
#if 0 && defined(__OPTIMIZE__) && (defined __GNUC__ || __has_builtin(__builtin_expect))
171
#define EDUKE32_PREDICT_TRUE(x)       __builtin_expect(!!(x),1)
171
#define EDUKE32_PREDICT_TRUE(x)       __builtin_expect(!!(x),1)
172
#define EDUKE32_PREDICT_FALSE(x)     __builtin_expect(!!(x),0)
172
#define EDUKE32_PREDICT_FALSE(x)     __builtin_expect(!!(x),0)
173
#else
173
#else
174
#define EDUKE32_PREDICT_TRUE(x) (x)
174
#define EDUKE32_PREDICT_TRUE(x) (x)
175
#define EDUKE32_PREDICT_FALSE(x) (x)
175
#define EDUKE32_PREDICT_FALSE(x) (x)
176
#endif
176
#endif
177
177
178
#if EDUKE32_GCC_PREREQ(4,5)  || __has_builtin(__builtin_unreachable)
178
#if EDUKE32_GCC_PREREQ(4,5)  || __has_builtin(__builtin_unreachable)
179
#define EDUKE32_UNREACHABLE_SECTION(...)   __builtin_unreachable()
179
#define EDUKE32_UNREACHABLE_SECTION(...)   __builtin_unreachable()
180
#elif _MSC_VER
180
#elif _MSC_VER
181
#define EDUKE32_UNREACHABLE_SECTION(...)   __assume(0)
181
#define EDUKE32_UNREACHABLE_SECTION(...)   __assume(0)
182
#else
182
#else
183
#define EDUKE32_UNREACHABLE_SECTION(...) __VA_ARGS__
183
#define EDUKE32_UNREACHABLE_SECTION(...) __VA_ARGS__
184
#endif
184
#endif
185
185
186
#if EDUKE32_GCC_PREREQ(2,0) || defined _MSC_VER
186
#if EDUKE32_GCC_PREREQ(2,0) || defined _MSC_VER
187
# define EDUKE32_FUNCTION __FUNCTION__
187
# define EDUKE32_FUNCTION __FUNCTION__
188
#elif CSTD >= 1999 || CXXSTD >= 2011
188
#elif CSTD >= 1999 || CXXSTD >= 2011
189
# define EDUKE32_FUNCTION __func__
189
# define EDUKE32_FUNCTION __func__
190
#else
190
#else
191
# define EDUKE32_FUNCTION "???"
191
# define EDUKE32_FUNCTION "???"
192
#endif
192
#endif
193
193
194
#ifdef _MSC_VER
194
#ifdef _MSC_VER
195
# define EDUKE32_PRETTY_FUNCTION __FUNCSIG__
195
# define EDUKE32_PRETTY_FUNCTION __FUNCSIG__
196
#elif EDUKE32_GCC_PREREQ(2,0)
196
#elif EDUKE32_GCC_PREREQ(2,0)
197
# define EDUKE32_PRETTY_FUNCTION __PRETTY_FUNCTION__
197
# define EDUKE32_PRETTY_FUNCTION __PRETTY_FUNCTION__
198
#else
198
#else
199
# define EDUKE32_PRETTY_FUNCTION EDUKE32_FUNCTION
199
# define EDUKE32_PRETTY_FUNCTION EDUKE32_FUNCTION
200
#endif
200
#endif
201
201
202
#ifdef __COUNTER__
202
#ifdef __COUNTER__
203
# define EDUKE32_UNIQUE_SRC_ID __COUNTER__
203
# define EDUKE32_UNIQUE_SRC_ID __COUNTER__
204
#else
204
#else
205
# define EDUKE32_UNIQUE_SRC_ID __LINE__
205
# define EDUKE32_UNIQUE_SRC_ID __LINE__
206
#endif
206
#endif
207
207
208
#if CXXSTD >= 2017
208
#if CXXSTD >= 2017
209
# define EDUKE32_STATIC_ASSERT(cond) static_assert(cond)
209
# define EDUKE32_STATIC_ASSERT(cond) static_assert(cond)
210
#elif CXXSTD >= 2011 || CSTD >= 2011 || EDUKE32_MSVC_CXX_PREREQ(1600)
210
#elif CXXSTD >= 2011 || CSTD >= 2011 || EDUKE32_MSVC_CXX_PREREQ(1600)
211
# define EDUKE32_STATIC_ASSERT(cond) static_assert(cond, "")
211
# define EDUKE32_STATIC_ASSERT(cond) static_assert(cond, "")
212
#else
212
#else
213
/* C99 / C++03 static assertions based on source found in LuaJIT's src/lj_def.h. */
213
/* C99 / C++03 static assertions based on source found in LuaJIT's src/lj_def.h. */
214
# define EDUKE32_ASSERT_NAME2(name, line) name ## line
214
# define EDUKE32_ASSERT_NAME2(name, line) name ## line
215
# define EDUKE32_ASSERT_NAME(line) EDUKE32_ASSERT_NAME2(eduke32_assert_, line)
215
# define EDUKE32_ASSERT_NAME(line) EDUKE32_ASSERT_NAME2(eduke32_assert_, line)
216
# define EDUKE32_STATIC_ASSERT(cond) \
216
# define EDUKE32_STATIC_ASSERT(cond) \
217
    extern void EDUKE32_ASSERT_NAME(EDUKE32_UNIQUE_SRC_ID)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
217
    extern void EDUKE32_ASSERT_NAME(EDUKE32_UNIQUE_SRC_ID)(int STATIC_ASSERTION_FAILED[(cond)?1:-1])
218
#endif
218
#endif
219
219
220
#ifdef _MSC_VER
220
#ifdef _MSC_VER
221
# define longlong(x) x##i64
221
# define longlong(x) x##i64
222
#else
222
#else
223
# define longlong(x) x##ll
223
# define longlong(x) x##ll
224
#endif
224
#endif
225
225
226
#ifndef FP_OFF
226
#ifndef FP_OFF
227
# define FP_OFF(__p) ((uintptr_t)(__p))
227
# define FP_OFF(__p) ((uintptr_t)(__p))
228
#endif
228
#endif
229
229
230
#ifdef UNDERSCORES
230
#ifdef UNDERSCORES
231
# define ASMSYM(x) "_" x
231
# define ASMSYM(x) "_" x
232
#else
232
#else
233
# define ASMSYM(x) x
233
# define ASMSYM(x) x
234
#endif
234
#endif
235
235
236
#if defined __cplusplus
236
#if defined __cplusplus
237
# define STATIC_CAST_OP(t) static_cast<t>
237
# define STATIC_CAST_OP(t) static_cast<t>
238
# define REINTERPRET_CAST_OP(t) reinterpret_cast<t>
238
# define REINTERPRET_CAST_OP(t) reinterpret_cast<t>
239
#else
239
#else
240
# define STATIC_CAST_OP(t) (t)
240
# define STATIC_CAST_OP(t) (t)
241
# define REINTERPRET_CAST_OP(t) (t)
241
# define REINTERPRET_CAST_OP(t) (t)
242
#endif
242
#endif
243
#define STATIC_CAST(t, v) (STATIC_CAST_OP(t)(v))
243
#define STATIC_CAST(t, v) (STATIC_CAST_OP(t)(v))
244
#define REINTERPRET_CAST(t, v) (REINTERPRET_CAST_OP(t)(v))
244
#define REINTERPRET_CAST(t, v) (REINTERPRET_CAST_OP(t)(v))
245
245
246
#if defined __cplusplus && (__cplusplus >= 201103L || __has_feature(cxx_constexpr) || EDUKE32_MSVC_PREREQ(1900))
246
#if defined __cplusplus && (__cplusplus >= 201103L || __has_feature(cxx_constexpr) || EDUKE32_MSVC_PREREQ(1900))
247
# define HAVE_CONSTEXPR
247
# define HAVE_CONSTEXPR
248
# define CONSTEXPR constexpr
248
# define CONSTEXPR constexpr
249
#else
249
#else
250
# define CONSTEXPR
250
# define CONSTEXPR
251
#endif
251
#endif
252
252
253
#if CXXSTD >= 2011 || EDUKE32_MSVC_PREREQ(1700)
253
#if CXXSTD >= 2011 || EDUKE32_MSVC_PREREQ(1700)
254
# define FINAL final
254
# define FINAL final
255
#else
255
#else
256
# define FINAL
256
# define FINAL
257
#endif
257
#endif
258
258
259
#if CXXSTD >= 2014
259
#if CXXSTD >= 2014
260
# define CONSTEXPR_CXX14 CONSTEXPR
260
# define CONSTEXPR_CXX14 CONSTEXPR
261
#else
261
#else
262
# define CONSTEXPR_CXX14
262
# define CONSTEXPR_CXX14
263
#endif
263
#endif
264
264
265
#if CXXSTD >= 2011
265
#if CXXSTD >= 2011
266
# if __has_cpp_attribute(fallthrough)
266
# if __has_cpp_attribute(fallthrough)
267
#  define fallthrough__ [[fallthrough]]
267
#  define fallthrough__ [[fallthrough]]
268
# elif __has_cpp_attribute(clang::fallthrough)
268
# elif __has_cpp_attribute(clang::fallthrough)
269
#  define fallthrough__ [[clang::fallthrough]]
269
#  define fallthrough__ [[clang::fallthrough]]
270
# elif __has_cpp_attribute(gnu::fallthrough)
270
# elif __has_cpp_attribute(gnu::fallthrough)
271
#  define fallthrough__ [[gnu::fallthrough]]
271
#  define fallthrough__ [[gnu::fallthrough]]
272
# endif
272
# endif
273
#endif
273
#endif
274
#ifndef fallthrough__
274
#ifndef fallthrough__
275
# if !defined __clang__ && EDUKE32_GCC_PREREQ(7,0)
275
# if !defined __clang__ && EDUKE32_GCC_PREREQ(7,0)
276
#  define fallthrough__ __attribute__((fallthrough))
276
#  define fallthrough__ __attribute__((fallthrough))
277
# elif defined _MSC_VER
277
# elif defined _MSC_VER
278
#  define fallthrough__ __fallthrough
278
#  define fallthrough__ __fallthrough
279
# else
279
# else
280
#  define fallthrough__
280
#  define fallthrough__
281
# endif
281
# endif
282
#endif
282
#endif
283
283
284
284
285
////////// Platform detection //////////
285
////////// Platform detection //////////
286
286
287
#if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __bsdi__ || defined __DragonFly__
287
#if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __bsdi__ || defined __DragonFly__
288
# define EDUKE32_BSD
288
# define EDUKE32_BSD
289
#endif
289
#endif
290
290
291
#ifdef __APPLE__
291
#ifdef __APPLE__
292
# include <TargetConditionals.h>
292
# include <TargetConditionals.h>
293
# if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
293
# if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
294
#  define EDUKE32_IOS
294
#  define EDUKE32_IOS
295
# else
295
# else
296
#  define EDUKE32_OSX
296
#  define EDUKE32_OSX
297
# endif
297
# endif
298
#endif
298
#endif
299
299
300
300
301
////////// Architecture detection //////////
301
////////// Architecture detection //////////
302
302
303
#if defined __arm__ || defined __aarch64__
303
#if defined __arm__ || defined __aarch64__
304
# define EDUKE32_CPU_ARM
304
# define EDUKE32_CPU_ARM
305
#elif defined __i386 || defined __i386__ || defined _M_IX86 || defined _M_X64 || defined __x86_64__
305
#elif defined __i386 || defined __i386__ || defined _M_IX86 || defined _M_X64 || defined __x86_64__
306
# define EDUKE32_CPU_X86
306
# define EDUKE32_CPU_X86
307
#elif defined _M_PPC || defined __powerpc__ || defined __powerpc64__
307
#elif defined _M_PPC || defined __powerpc__ || defined __powerpc64__
308
# define EDUKE32_CPU_PPC
308
# define EDUKE32_CPU_PPC
309
#elif defined __MIPSEL__ || defined __mips_isa_rev
309
#elif defined __MIPSEL__ || defined __mips_isa_rev
310
# define EDUKE32_CPU_MIPS
310
# define EDUKE32_CPU_MIPS
311
#endif
311
#endif
312
312
313
#if defined _LP64 || defined __LP64__ || defined __64BIT__ || _ADDR64 || defined _WIN64 || defined __arch64__ ||       \
313
#if defined _LP64 || defined __LP64__ || defined __64BIT__ || _ADDR64 || defined _WIN64 || defined __arch64__ ||       \
314
__WORDSIZE == 64 || (defined __sparc && defined __sparcv9) || defined __x86_64 || defined __amd64 ||                   \
314
__WORDSIZE == 64 || (defined __sparc && defined __sparcv9) || defined __x86_64 || defined __amd64 ||                   \
315
defined __x86_64__ || defined __amd64__ || defined _M_X64 || defined _M_IA64 || defined __ia64 || defined __IA64__
315
defined __x86_64__ || defined __amd64__ || defined _M_X64 || defined _M_IA64 || defined __ia64 || defined __IA64__
316
316
317
# define BITNESS64
317
# define BITNESS64
318
318
319
#endif
319
#endif
320
320
321
#if defined(__linux)
321
#if defined(__linux)
322
# include <endian.h>
322
# include <endian.h>
323
# if __BYTE_ORDER == __LITTLE_ENDIAN
323
# if __BYTE_ORDER == __LITTLE_ENDIAN
324
#  define B_LITTLE_ENDIAN 1
324
#  define B_LITTLE_ENDIAN 1
325
#  define B_BIG_ENDIAN    0
325
#  define B_BIG_ENDIAN    0
326
# elif __BYTE_ORDER == __BIG_ENDIAN
326
# elif __BYTE_ORDER == __BIG_ENDIAN
327
#  define B_LITTLE_ENDIAN 0
327
#  define B_LITTLE_ENDIAN 0
328
#  define B_BIG_ENDIAN    1
328
#  define B_BIG_ENDIAN    1
329
# endif
329
# endif
330
330
331
#elif defined(GEKKO) || defined(__ANDROID__)
331
#elif defined(GEKKO) || defined(__ANDROID__)
332
# define B_LITTLE_ENDIAN 0
332
# define B_LITTLE_ENDIAN 0
333
# define B_BIG_ENDIAN 1
333
# define B_BIG_ENDIAN 1
334
334
335
#elif defined(__OpenBSD__)
335
#elif defined(__OpenBSD__)
336
# include <machine/endian.h>
336
# include <machine/endian.h>
337
# if _BYTE_ORDER == _LITTLE_ENDIAN
337
# if _BYTE_ORDER == _LITTLE_ENDIAN
338
#  define B_LITTLE_ENDIAN 1
338
#  define B_LITTLE_ENDIAN 1
339
#  define B_BIG_ENDIAN    0
339
#  define B_BIG_ENDIAN    0
340
# elif _BYTE_ORDER == _BIG_ENDIAN
340
# elif _BYTE_ORDER == _BIG_ENDIAN
341
#  define B_LITTLE_ENDIAN 0
341
#  define B_LITTLE_ENDIAN 0
342
#  define B_BIG_ENDIAN    1
342
#  define B_BIG_ENDIAN    1
343
# endif
343
# endif
344
344
345
#elif defined EDUKE32_BSD
345
#elif defined EDUKE32_BSD
346
# include <sys/endian.h>
346
# include <sys/endian.h>
347
# if _BYTE_ORDER == _LITTLE_ENDIAN
347
# if _BYTE_ORDER == _LITTLE_ENDIAN
348
#  define B_LITTLE_ENDIAN 1
348
#  define B_LITTLE_ENDIAN 1
349
#  define B_BIG_ENDIAN    0
349
#  define B_BIG_ENDIAN    0
350
# elif _BYTE_ORDER == _BIG_ENDIAN
350
# elif _BYTE_ORDER == _BIG_ENDIAN
351
#  define B_LITTLE_ENDIAN 0
351
#  define B_LITTLE_ENDIAN 0
352
#  define B_BIG_ENDIAN    1
352
#  define B_BIG_ENDIAN    1
353
# endif
353
# endif
354
354
355
#elif defined(__APPLE__)
355
#elif defined(__APPLE__)
356
# if defined(__LITTLE_ENDIAN__)
356
# if defined(__LITTLE_ENDIAN__)
357
#  define B_LITTLE_ENDIAN 1
357
#  define B_LITTLE_ENDIAN 1
358
#  define B_BIG_ENDIAN    0
358
#  define B_BIG_ENDIAN    0
359
# elif defined(__BIG_ENDIAN__)
359
# elif defined(__BIG_ENDIAN__)
360
#  define B_LITTLE_ENDIAN 0
360
#  define B_LITTLE_ENDIAN 0
361
#  define B_BIG_ENDIAN    1
361
#  define B_BIG_ENDIAN    1
362
# endif
362
# endif
363
# include <libkern/OSByteOrder.h>
363
# include <libkern/OSByteOrder.h>
364
364
365
#elif defined(__BEOS__)
365
#elif defined(__BEOS__)
366
# include <posix/endian.h>
366
# include <posix/endian.h>
367
# if LITTLE_ENDIAN != 0
367
# if LITTLE_ENDIAN != 0
368
#  define B_LITTLE_ENDIAN 1
368
#  define B_LITTLE_ENDIAN 1
369
#  define B_BIG_ENDIAN    0
369
#  define B_BIG_ENDIAN    0
370
# elif BIG_ENDIAN != 0
370
# elif BIG_ENDIAN != 0
371
#  define B_LITTLE_ENDIAN 0
371
#  define B_LITTLE_ENDIAN 0
372
#  define B_BIG_ENDIAN    1
372
#  define B_BIG_ENDIAN    1
373
# endif
373
# endif
374
374
375
#elif defined(__QNX__)
375
#elif defined(__QNX__)
376
# if defined __LITTLEENDIAN__
376
# if defined __LITTLEENDIAN__
377
#  define B_LITTLE_ENDIAN 1
377
#  define B_LITTLE_ENDIAN 1
378
#  define B_BIG_ENDIAN    0
378
#  define B_BIG_ENDIAN    0
379
# elif defined __BIGENDIAN__
379
# elif defined __BIGENDIAN__
380
#  define B_LITTLE_ENDIAN 0
380
#  define B_LITTLE_ENDIAN 0
381
#  define B_BIG_ENDIAN    1
381
#  define B_BIG_ENDIAN    1
382
# endif
382
# endif
383
383
384
#elif defined(__sun)
384
#elif defined(__sun)
385
# if defined _LITTLE_ENDIAN
385
# if defined _LITTLE_ENDIAN
386
#  define B_LITTLE_ENDIAN 1
386
#  define B_LITTLE_ENDIAN 1
387
#  define B_BIG_ENDIAN    0
387
#  define B_BIG_ENDIAN    0
388
# elif defined _BIG_ENDIAN
388
# elif defined _BIG_ENDIAN
389
#  define B_LITTLE_ENDIAN 0
389
#  define B_LITTLE_ENDIAN 0
390
#  define B_BIG_ENDIAN    1
390
#  define B_BIG_ENDIAN    1
391
# endif
391
# endif
392
392
393
#elif defined(_WIN32) || defined(SKYOS) || defined(__SYLLABLE__)
393
#elif defined(_WIN32) || defined(SKYOS) || defined(__SYLLABLE__)
394
# define B_LITTLE_ENDIAN 1
394
# define B_LITTLE_ENDIAN 1
395
# define B_BIG_ENDIAN    0
395
# define B_BIG_ENDIAN    0
396
#endif
396
#endif
397
397
398
#if !defined(B_LITTLE_ENDIAN) || !defined(B_BIG_ENDIAN)
398
#if !defined(B_LITTLE_ENDIAN) || !defined(B_BIG_ENDIAN)
399
# error Unknown endianness
399
# error Unknown endianness
400
#endif
400
#endif
401
401
402
402
403
////////// Standard library headers //////////
403
////////// Standard library headers //////////
404
404
405
#undef __USE_MINGW_ANSI_STDIO // Workaround for MinGW-w64.
405
#undef __USE_MINGW_ANSI_STDIO // Workaround for MinGW-w64.
406
406
407
#ifndef __STDC_FORMAT_MACROS
407
#ifndef __STDC_FORMAT_MACROS
408
# define __STDC_FORMAT_MACROS
408
# define __STDC_FORMAT_MACROS
409
#endif
409
#endif
410
#ifndef __STDC_LIMIT_MACROS
410
#ifndef __STDC_LIMIT_MACROS
411
# define __STDC_LIMIT_MACROS
411
# define __STDC_LIMIT_MACROS
412
#endif
412
#endif
413
413
414
#ifndef _USE_MATH_DEFINES
414
#ifndef _USE_MATH_DEFINES
415
# define _USE_MATH_DEFINES
415
# define _USE_MATH_DEFINES
416
#endif
416
#endif
417
417
418
#include <inttypes.h>
418
#include <inttypes.h>
419
#include <stdint.h>
419
#include <stdint.h>
420
420
421
#include <limits.h>
421
#include <limits.h>
422
#include <stdarg.h>
422
#include <stdarg.h>
423
#include <stddef.h>
423
#include <stddef.h>
424
#ifndef USE_PHYSFS
424
#ifndef USE_PHYSFS
425
#include <stdio.h>
425
#include <stdio.h>
426
#endif
426
#endif
427
#include <stdlib.h>
427
#include <stdlib.h>
428
#include <string.h>
428
#include <string.h>
429
429
430
#if !(defined _WIN32 && defined __clang__)
430
#if !(defined _WIN32 && defined __clang__)
431
#include <float.h>
431
#include <float.h>
432
#endif
432
#endif
433
#include <math.h>
433
#include <math.h>
434
434
435
#include <ctype.h>
435
#include <ctype.h>
436
#include <errno.h>
436
#include <errno.h>
437
#include <time.h>
437
#include <time.h>
438
438
439
#include <assert.h>
439
#include <assert.h>
440
440
441
#ifdef __cplusplus
441
#ifdef __cplusplus
442
# include <limits>
442
# include <limits>
443
# if CXXSTD >= 2011 || EDUKE32_MSVC_PREREQ(1800)
443
# if CXXSTD >= 2011 || EDUKE32_MSVC_PREREQ(1800)
444
#  include <algorithm>
444
#  include <algorithm>
445
#  include <functional>
445
#  include <functional>
446
#  include <type_traits>
446
#  include <type_traits>
447
// we need this because MSVC does not properly identify C++11 support
447
// we need this because MSVC does not properly identify C++11 support
448
#  define HAVE_CXX11_HEADERS
448
#  define HAVE_CXX11_HEADERS
449
# endif
449
# endif
450
#endif
450
#endif
451
451
452
////////// Platform headers //////////
452
////////// Platform headers //////////
453
453
454
#if !defined __APPLE__ && (!defined EDUKE32_BSD || !__STDC__)
454
#if !defined __APPLE__ && (!defined EDUKE32_BSD || !__STDC__)
455
# include <malloc.h>
455
# include <malloc.h>
456
#endif
456
#endif
457
457
458
#ifndef USE_PHYSFS
458
#ifndef USE_PHYSFS
459
#include <fcntl.h>
459
#include <fcntl.h>
460
#include <sys/stat.h>
460
#include <sys/stat.h>
461
#include <sys/types.h>
461
#include <sys/types.h>
462
462
463
#if defined(_WIN32)
463
#if defined(_WIN32)
464
# include <direct.h>
464
# include <direct.h>
465
# include <io.h>
465
# include <io.h>
466
#else
466
#else
467
# include <unistd.h>
467
# include <unistd.h>
468
#endif
468
#endif
469
#endif
469
#endif
470
470
471
471
472
////////// DEPRECATED: Standard library prefixing //////////
472
////////// DEPRECATED: Standard library prefixing //////////
473
473
474
#ifdef _MSC_VER
474
#ifdef _MSC_VER
475
# if defined _M_AMD64 || defined _M_ARM64 || defined _M_X64 || defined _WIN64
475
# if defined _M_AMD64 || defined _M_ARM64 || defined _M_X64 || defined _WIN64
476
// should be int64_t, if not for a suspected VS compiler bug
476
// should be int64_t, if not for a suspected VS compiler bug
477
typedef int32_t ssize_t;
477
typedef int32_t ssize_t;
478
# else
478
# else
479
typedef int32_t ssize_t;
479
typedef int32_t ssize_t;
480
# endif
480
# endif
481
#endif
481
#endif
482
482
483
typedef size_t bsize_t;
483
typedef size_t bsize_t;
484
typedef ssize_t bssize_t;
484
typedef ssize_t bssize_t;
485
485
486
typedef FILE BFILE;
486
typedef FILE BFILE;
487
487
488
#define BO_BINARY O_BINARY
488
#define BO_BINARY O_BINARY
489
#define BO_TEXT   O_TEXT
489
#define BO_TEXT   O_TEXT
490
#define BO_RDONLY O_RDONLY
490
#define BO_RDONLY O_RDONLY
491
#define BO_WRONLY O_WRONLY
491
#define BO_WRONLY O_WRONLY
492
#define BO_RDWR   O_RDWR
492
#define BO_RDWR   O_RDWR
493
#define BO_APPEND O_APPEND
493
#define BO_APPEND O_APPEND
494
#define BO_CREAT  O_CREAT
494
#define BO_CREAT  O_CREAT
495
#define BO_TRUNC  O_TRUNC
495
#define BO_TRUNC  O_TRUNC
496
#define BS_IRGRP  S_IRGRP
496
#define BS_IRGRP  S_IRGRP
497
#define BS_IWGRP  S_IWGRP
497
#define BS_IWGRP  S_IWGRP
498
#define BS_IEXEC  S_IEXEC
498
#define BS_IEXEC  S_IEXEC
499
#define BS_IFIFO  S_IFIFO
499
#define BS_IFIFO  S_IFIFO
500
#define BS_IFCHR  S_IFCHR
500
#define BS_IFCHR  S_IFCHR
501
#define BS_IFBLK  S_IFBLK
501
#define BS_IFBLK  S_IFBLK
502
#define BS_IFDIR  S_IFDIR
502
#define BS_IFDIR  S_IFDIR
503
#define BS_IFREG  S_IFREG
503
#define BS_IFREG  S_IFREG
504
#define BSEEK_SET SEEK_SET
504
#define BSEEK_SET SEEK_SET
505
#define BSEEK_CUR SEEK_CUR
505
#define BSEEK_CUR SEEK_CUR
506
#define BSEEK_END SEEK_END
506
#define BSEEK_END SEEK_END
507
507
508
#define BMAX_PATH 256
508
#define BMAX_PATH 256
509
509
510
#define Bassert assert
510
#define Bassert assert
511
#define Brand rand
511
#define Brand rand
512
#define Bmalloc malloc
512
#define Bmalloc malloc
513
#define Bcalloc calloc
513
#define Bcalloc calloc
514
#define Brealloc realloc
514
#define Brealloc realloc
515
#define Bfree free
515
#define Bfree free
516
#define Bopen open
516
#define Bopen open
517
#define Bclose close
517
#define Bclose close
518
#define Bwrite write
518
#define Bwrite write
519
#define Bread read
519
#define Bread read
520
#define Blseek lseek
520
#define Blseek lseek
521
#define Bstat stat
521
#define Bstat stat
522
#define Bfstat fstat
522
#define Bfstat fstat
523
#define Bfileno fileno
523
#define Bfileno fileno
524
#define Bferror ferror
524
#define Bferror ferror
525
#define Bfopen fopen
525
#define Bfopen fopen
526
#define Bfclose fclose
526
#define Bfclose fclose
527
#define Bfflush fflush
527
#define Bfflush fflush
528
#define Bfeof feof
528
#define Bfeof feof
529
#define Bfgetc fgetc
529
#define Bfgetc fgetc
530
#define Brewind rewind
530
#define Brewind rewind
531
#define Bfgets fgets
531
#define Bfgets fgets
532
#define Bfputc fputc
532
#define Bfputc fputc
533
#define Bfputs fputs
533
#define Bfputs fputs
534
#define Bfread fread
534
#define Bfread fread
535
#define Bfwrite fwrite
535
#define Bfwrite fwrite
536
#define Bfprintf fprintf
536
#define Bfprintf fprintf
537
#define Bfscanf fscanf
537
#define Bfscanf fscanf
538
#define Bfseek fseek
538
#define Bfseek fseek
539
#define Bftell ftell
539
#define Bftell ftell
540
#define Bputs puts
540
#define Bputs puts
541
#define Bstrcpy strcpy
541
#define Bstrcpy strcpy
542
#define Bstrncpy strncpy
542
#define Bstrncpy strncpy
543
#define Bstrcmp strcmp
543
#define Bstrcmp strcmp
544
#define Bstrncmp strncmp
544
#define Bstrncmp strncmp
545
#define Bstrcat strcat
545
#define Bstrcat strcat
546
#define Bstrncat strncat
546
#define Bstrncat strncat
547
#define Bstrlen strlen
547
#define Bstrlen strlen
548
#define Bstrchr strchr
548
#define Bstrchr strchr
549
#define Bstrrchr strrchr
549
#define Bstrrchr strrchr
550
#define Bstrtol strtol
550
#define Bstrtol strtol
551
#define Bstrtoul strtoul
551
#define Bstrtoul strtoul
552
#define Bstrtod strtod
552
#define Bstrtod strtod
553
#define Bstrstr strstr
553
#define Bstrstr strstr
554
#define Bislower islower
554
#define Bislower islower
555
#define Bisupper isupper
555
#define Bisupper isupper
556
#define Bisdigit isdigit
556
#define Bisdigit isdigit
557
#define Btoupper toupper
557
#define Btoupper toupper
558
#define Btolower tolower
558
#define Btolower tolower
559
#define Bmemcpy memcpy
559
#define Bmemcpy memcpy
560
#define Bmemmove memmove
560
#define Bmemmove memmove
561
#define Bmemchr memchr
561
#define Bmemchr memchr
562
#define Bmemset memset
562
#define Bmemset memset
563
#define Bmemcmp memcmp
563
#define Bmemcmp memcmp
564
#define Bscanf scanf
564
#define Bscanf scanf
565
#define Bprintf printf
565
#define Bprintf printf
566
#define Bsscanf sscanf
566
#define Bsscanf sscanf
567
#define Bsprintf sprintf
567
#define Bsprintf sprintf
568
#define Bvfprintf vfprintf
568
#define Bvfprintf vfprintf
569
#define Bgetenv getenv
569
#define Bgetenv getenv
570
#define Butime utime
570
#define Butime utime
571
571
572
572
573
////////// Standard library wrappers //////////
573
////////// Standard library wrappers //////////
574
574
575
#ifdef __ANDROID__
575
#ifdef __ANDROID__
576
# define BS_IWRITE S_IWUSR
576
# define BS_IWRITE S_IWUSR
577
# define BS_IREAD  S_IRUSR
577
# define BS_IREAD  S_IRUSR
578
#else
578
#else
579
# define BS_IWRITE S_IWRITE
579
# define BS_IWRITE S_IWRITE
580
# define BS_IREAD  S_IREAD
580
# define BS_IREAD  S_IREAD
581
#endif
581
#endif
582
582
583
#if defined(__cplusplus) && defined(_MSC_VER)
583
#if defined(__cplusplus) && defined(_MSC_VER)
584
# define Bstrdup _strdup
584
# define Bstrdup _strdup
585
# define Bchdir _chdir
585
# define Bchdir _chdir
586
# define Bgetcwd _getcwd
586
# define Bgetcwd _getcwd
587
#else
587
#else
588
# define Bstrdup strdup
588
# define Bstrdup strdup
589
# define Bchdir chdir
589
# define Bchdir chdir
590
# define Bgetcwd getcwd
590
# define Bgetcwd getcwd
591
#endif
591
#endif
592
592
593
#if defined(__GNUC__)
593
#if defined(__GNUC__)
594
# define Btell(h) lseek(h,0,SEEK_CUR)
594
# define Btell(h) lseek(h,0,SEEK_CUR)
595
#else
595
#else
596
# define Btell tell
596
# define Btell tell
597
#endif
597
#endif
598
598
599
#if defined(_MSC_VER)
599
#if defined(_MSC_VER)
600
# define Bstrcasecmp _stricmp
600
# define Bstrcasecmp _stricmp
601
# define Bstrncasecmp _strnicmp
601
# define Bstrncasecmp _strnicmp
602
#elif defined(__QNX__)
602
#elif defined(__QNX__)
603
# define Bstrcasecmp stricmp
603
# define Bstrcasecmp stricmp
604
# define Bstrncasecmp strnicmp
604
# define Bstrncasecmp strnicmp
605
#else
605
#else
606
# define Bstrcasecmp strcasecmp
606
# define Bstrcasecmp strcasecmp
607
# define Bstrncasecmp strncasecmp
607
# define Bstrncasecmp strncasecmp
608
#endif
608
#endif
609
609
610
#ifdef _MSC_VER
610
#ifdef _WIN32
611
# define Bsnprintf _snprintf
611
# define Bsnprintf _snprintf
612
# define Bvsnprintf _vsnprintf
612
# define Bvsnprintf _vsnprintf
613
#else
613
#else
614
# define Bsnprintf snprintf
614
# define Bsnprintf snprintf
615
# define Bvsnprintf vsnprintf
615
# define Bvsnprintf vsnprintf
616
#endif
616
#endif
617
617
618
#ifdef _MSC_VER
618
#ifdef _MSC_VER
619
# define Balloca _alloca
619
# define Balloca _alloca
620
#elif defined __GNUC__
620
#elif defined __GNUC__
621
# define Balloca __builtin_alloca
621
# define Balloca __builtin_alloca
622
#else
622
#else
623
# define Balloca alloca
623
# define Balloca alloca
624
#endif
624
#endif
625
625
626
#ifdef _MSC_VER
626
#ifdef _MSC_VER
627
# define Bmalloca _malloca
627
# define Bmalloca _malloca
628
# define Bfreea _freea
628
# define Bfreea _freea
629
#else
629
#else
630
# define Bmalloca alloca
630
# define Bmalloca alloca
631
# define Bfreea(ptr) do { } while (0)
631
# define Bfreea(ptr) do { } while (0)
632
#endif
632
#endif
633
633
634
#define Btime() time(NULL)
634
#define Btime() time(NULL)
635
635
636
#if defined(_WIN32)
636
#if defined(_WIN32)
637
# define Bmkdir(s,x) mkdir(s)
637
# define Bmkdir(s,x) mkdir(s)
638
#else
638
#else
639
# define Bmkdir mkdir
639
# define Bmkdir mkdir
640
#endif
640
#endif
641
641
642
// XXX: different across 32- and 64-bit archs (e.g.
642
// XXX: different across 32- and 64-bit archs (e.g.
643
// parsing the decimal representation of 0xffffffff,
643
// parsing the decimal representation of 0xffffffff,
644
// 4294967295 -- long is signed, so strtol would
644
// 4294967295 -- long is signed, so strtol would
645
// return LONG_MAX (== 0x7fffffff on 32-bit archs))
645
// return LONG_MAX (== 0x7fffffff on 32-bit archs))
646
646
647
static FORCE_INLINE int32_t atoi_safe(const char *str) { return (int32_t)Bstrtol(str, NULL, 10); }
647
static FORCE_INLINE int32_t atoi_safe(const char *str) { return (int32_t)Bstrtol(str, NULL, 10); }
648
648
649
#define Batoi(x) atoi_safe(x)
649
#define Batoi(x) atoi_safe(x)
650
#define Batol(str) (strtol(str, NULL, 10))
650
#define Batol(str) (strtol(str, NULL, 10))
651
#define Batof(str) (strtod(str, NULL))
651
#define Batof(str) (strtod(str, NULL))
652
652
653
#if defined BITNESS64 && (defined __SSE2__ || defined _MSC_VER)
653
#if defined BITNESS64 && (defined __SSE2__ || defined _MSC_VER)
654
#include <emmintrin.h>
654
#include <emmintrin.h>
655
static FORCE_INLINE int32_t Blrintf(const float x)
655
static FORCE_INLINE int32_t Blrintf(const float x)
656
{
656
{
657
    __m128 xx = _mm_load_ss(&x);
657
    __m128 xx = _mm_load_ss(&x);
658
    return _mm_cvtss_si32(xx);
658
    return _mm_cvtss_si32(xx);
659
}
659
}
660
#elif defined (_MSC_VER)
660
#elif defined (_MSC_VER)
661
static FORCE_INLINE int32_t Blrintf(const float x)
661
static FORCE_INLINE int32_t Blrintf(const float x)
662
{
662
{
663
    int n;
663
    int n;
664
    __asm fld x;
664
    __asm fld x;
665
    __asm fistp n;
665
    __asm fistp n;
666
    return n;
666
    return n;
667
}
667
}
668
#else
668
#else
669
#define Blrintf(x) ((int32_t)lrintf(x))
669
#define Blrintf(x) ((int32_t)lrintf(x))
670
#endif
670
#endif
671
671
672
#if defined(__arm__)
672
#if defined(__arm__)
673
# define Bsqrt __builtin_sqrt
673
# define Bsqrt __builtin_sqrt
674
# define Bsqrtf __builtin_sqrtf
674
# define Bsqrtf __builtin_sqrtf
675
#else
675
#else
676
# define Bsqrt sqrt
676
# define Bsqrt sqrt
677
# define Bsqrtf sqrtf
677
# define Bsqrtf sqrtf
678
#endif
678
#endif
679
679
680
// redefined for apple/ppc, which chokes on stderr when linking...
680
// redefined for apple/ppc, which chokes on stderr when linking...
681
#if defined EDUKE32_OSX && defined __BIG_ENDIAN__
681
#if defined EDUKE32_OSX && defined __BIG_ENDIAN__
682
# define ERRprintf(fmt, ...) printf(fmt, ## __VA_ARGS__)
682
# define ERRprintf(fmt, ...) printf(fmt, ## __VA_ARGS__)
683
#else
683
#else
684
# define ERRprintf(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
684
# define ERRprintf(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
685
#endif
685
#endif
686
686
687
// Bexit is ONLY for errors!
687
// Bexit is ONLY for errors!
688
#ifdef DEBUGGINGAIDS
688
#ifdef DEBUGGINGAIDS
689
# define Bexit(status) do { initprintf("exit(%d) at %s:%d in %s()\n", status, __FILE__, __LINE__, EDUKE32_FUNCTION); exit(status); } while (0)
689
# define Bexit(status) do { initprintf("exit(%d) at %s:%d in %s()\n", status, __FILE__, __LINE__, EDUKE32_FUNCTION); exit(status); } while (0)
690
#else
690
#else
691
# define Bexit exit
691
# define Bexit exit
692
#endif
692
#endif
693
693
694
#ifdef _WIN32
694
#ifdef _WIN32
695
#define fatal_exit__(x) FatalAppExitA(0, x)
695
#define fatal_exit__(x) FatalAppExitA(0, x)
696
#else
696
#else
697
#define fatal_exit__(x) do { wm_msgbox("Fatal Error", "%s", x); exit(EXIT_FAILURE); } while(0)
697
#define fatal_exit__(x) do { wm_msgbox("Fatal Error", "%s", x); exit(EXIT_FAILURE); } while(0)
698
#endif
698
#endif
699
699
700
#define fatal_exit(status) do { initprintf("fatal_exit(%s) at %s:%d in %s()\n", status, __FILE__, __LINE__, EDUKE32_FUNCTION); fatal_exit__(status); } while (0)
700
#define fatal_exit(status) do { initprintf("fatal_exit(%s) at %s:%d in %s()\n", status, __FILE__, __LINE__, EDUKE32_FUNCTION); fatal_exit__(status); } while (0)
701
701
702
////////// Standard library monkey patching //////////
702
////////// Standard library monkey patching //////////
703
703
704
#ifndef NULL
704
#ifndef NULL
705
# define NULL ((void *)0)
705
# define NULL ((void *)0)
706
#endif
706
#endif
707
707
708
#ifdef _MSC_VER
708
#ifdef _MSC_VER
709
# define strtoll _strtoi64
709
# define strtoll _strtoi64
710
#endif
710
#endif
711
711
712
#ifndef O_BINARY
712
#ifndef O_BINARY
713
# define O_BINARY 0
713
# define O_BINARY 0
714
#endif
714
#endif
715
#ifndef O_TEXT
715
#ifndef O_TEXT
716
# define O_TEXT 0
716
# define O_TEXT 0
717
#endif
717
#endif
718
718
719
#ifndef F_OK
719
#ifndef F_OK
720
# define F_OK 0
720
# define F_OK 0
721
#endif
721
#endif
722
722
723
#ifdef GEKKO
723
#ifdef GEKKO
724
# undef PRIdPTR
724
# undef PRIdPTR
725
# define PRIdPTR "d"
725
# define PRIdPTR "d"
726
# undef PRIxPTR
726
# undef PRIxPTR
727
# define PRIxPTR "x"
727
# define PRIxPTR "x"
728
# undef SCNx32
728
# undef SCNx32
729
# define SCNx32 "x"
729
# define SCNx32 "x"
730
#endif
730
#endif
731
731
732
#if defined EDUKE32_OSX
732
#if defined EDUKE32_OSX
733
# if !defined __x86_64__ && defined __GNUC__
733
# if !defined __x86_64__ && defined __GNUC__
734
// PK 20110617: is*() crashes for me in x86 code compiled from 64-bit, and gives link errors on ppc
734
// PK 20110617: is*() crashes for me in x86 code compiled from 64-bit, and gives link errors on ppc
735
//              This hack patches all occurences.
735
//              This hack patches all occurences.
736
#  define isdigit(ch) ({ int32_t c__dontuse_=ch; c__dontuse_>='0' && c__dontuse_<='9'; })
736
#  define isdigit(ch) ({ int32_t c__dontuse_=ch; c__dontuse_>='0' && c__dontuse_<='9'; })
737
#  define isalpha(ch) ({ int32_t c__dontuse2_=ch; (c__dontuse2_>='A' && c__dontuse2_<='Z') || (c__dontuse2_>='a' && c__dontuse2_<='z'); })
737
#  define isalpha(ch) ({ int32_t c__dontuse2_=ch; (c__dontuse2_>='A' && c__dontuse2_<='Z') || (c__dontuse2_>='a' && c__dontuse2_<='z'); })
738
#  define isalnum(ch2)  ({ int32_t c2__dontuse_=ch2; isalpha(c2__dontuse_) || isdigit(c2__dontuse_); })
738
#  define isalnum(ch2)  ({ int32_t c2__dontuse_=ch2; isalpha(c2__dontuse_) || isdigit(c2__dontuse_); })
739
#  if defined __BIG_ENDIAN__
739
#  if defined __BIG_ENDIAN__
740
#   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'); })
740
#   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'); })
741
#   define isprint(ch)  ({ int32_t c__dontuse_=ch; (c__dontuse_>=0x20 && c__dontuse_<0x7f); })
741
#   define isprint(ch)  ({ int32_t c__dontuse_=ch; (c__dontuse_>=0x20 && c__dontuse_<0x7f); })
742
#  endif
742
#  endif
743
# endif
743
# endif
744
#endif
744
#endif
745
745
746
#ifdef __ANDROID__
746
#ifdef __ANDROID__
747
void eduke32_exit_return(int) ATTRIBUTE((noreturn));
747
void eduke32_exit_return(int) ATTRIBUTE((noreturn));
748
# define exit(x) eduke32_exit_return(x)
748
# define exit(x) eduke32_exit_return(x)
749
#endif
749
#endif
750
750
751
751
752
////////// Metaprogramming structs //////////
752
////////// Metaprogramming structs //////////
753
753
754
#ifdef __cplusplus
754
#ifdef __cplusplus
755
755
756
# ifdef HAVE_CXX11_HEADERS
756
# ifdef HAVE_CXX11_HEADERS
757
using std::is_integral;
757
using std::is_integral;
758
template <typename T>
758
template <typename T>
759
struct is_signed
759
struct is_signed
760
{
760
{
761
    static constexpr bool value = std::is_signed<T>::value;
761
    static constexpr bool value = std::is_signed<T>::value;
762
};
762
};
763
template <typename T>
763
template <typename T>
764
struct is_unsigned
764
struct is_unsigned
765
{
765
{
766
    static constexpr bool value = std::is_unsigned<T>::value;
766
    static constexpr bool value = std::is_unsigned<T>::value;
767
};
767
};
768
# endif
768
# endif
769
769
770
# if CXXSTD >= 2014
770
# if CXXSTD >= 2014
771
using std::enable_if_t;
771
using std::enable_if_t;
772
using std::conditional_t;
772
using std::conditional_t;
773
using std::make_signed_t;
773
using std::make_signed_t;
774
using std::make_unsigned_t;
774
using std::make_unsigned_t;
775
using std::remove_pointer_t;
775
using std::remove_pointer_t;
776
# elif defined HAVE_CXX11_HEADERS
776
# elif defined HAVE_CXX11_HEADERS
777
template <bool B, class T = void>
777
template <bool B, class T = void>
778
using enable_if_t = typename std::enable_if<B, T>::type;
778
using enable_if_t = typename std::enable_if<B, T>::type;
779
template<bool B, class T, class F>
779
template<bool B, class T, class F>
780
using conditional_t = typename std::conditional<B, T, F>::type;
780
using conditional_t = typename std::conditional<B, T, F>::type;
781
template <typename T>
781
template <typename T>
782
using make_signed_t = typename std::make_signed<T>::type;
782
using make_signed_t = typename std::make_signed<T>::type;
783
template <typename T>
783
template <typename T>
784
using make_unsigned_t = typename std::make_unsigned<T>::type;
784
using make_unsigned_t = typename std::make_unsigned<T>::type;
785
template <class T>
785
template <class T>
786
using remove_pointer_t = typename std::remove_pointer<T>::type;
786
using remove_pointer_t = typename std::remove_pointer<T>::type;
787
# endif
787
# endif
788
788
789
# ifdef HAVE_CXX11_HEADERS
789
# ifdef HAVE_CXX11_HEADERS
790
template <typename type, typename other_type_with_sign>
790
template <typename type, typename other_type_with_sign>
791
using take_sign_t = conditional_t< is_signed<other_type_with_sign>::value, make_signed_t<type>, make_unsigned_t<type> >;
791
using take_sign_t = conditional_t< is_signed<other_type_with_sign>::value, make_signed_t<type>, make_unsigned_t<type> >;
792
# endif
792
# endif
793
793
794
template <size_t size>
794
template <size_t size>
795
struct integers_of_size { };
795
struct integers_of_size { };
796
template <>
796
template <>
797
struct integers_of_size<sizeof(int8_t)>
797
struct integers_of_size<sizeof(int8_t)>
798
{
798
{
799
    typedef int8_t i;
799
    typedef int8_t i;
800
    typedef uint8_t u;
800
    typedef uint8_t u;
801
};
801
};
802
template <>
802
template <>
803
struct integers_of_size<sizeof(int16_t)>
803
struct integers_of_size<sizeof(int16_t)>
804
{
804
{
805
    typedef int16_t i;
805
    typedef int16_t i;
806
    typedef uint16_t u;
806
    typedef uint16_t u;
807
};
807
};
808
template <>
808
template <>
809
struct integers_of_size<sizeof(int32_t)>
809
struct integers_of_size<sizeof(int32_t)>
810
{
810
{
811
    typedef int32_t i;
811
    typedef int32_t i;
812
    typedef uint32_t u;
812
    typedef uint32_t u;
813
};
813
};
814
template <>
814
template <>
815
struct integers_of_size<sizeof(int64_t)>
815
struct integers_of_size<sizeof(int64_t)>
816
{
816
{
817
    typedef int64_t i;
817
    typedef int64_t i;
818
    typedef uint64_t u;
818
    typedef uint64_t u;
819
};
819
};
820
820
821
#endif
821
#endif
822
822
823
823
824
////////// Typedefs //////////
824
////////// Typedefs //////////
825
825
826
#ifdef __cplusplus
826
#ifdef __cplusplus
827
// for use in SFINAE constructs in place of the pointer trick (to which 0 can unintentionally be implicitly cast)
827
// for use in SFINAE constructs in place of the pointer trick (to which 0 can unintentionally be implicitly cast)
828
struct Dummy FINAL
828
struct Dummy FINAL
829
{
829
{
830
    FORCE_INLINE CONSTEXPR Dummy() : dummy(0) { }
830
    FORCE_INLINE CONSTEXPR Dummy() : dummy(0) { }
831
    char dummy;
831
    char dummy;
832
};
832
};
833
#endif
833
#endif
834
834
835
#if defined(__x86_64__)
835
#if defined(__x86_64__)
836
// for 32-bit pointers in x86_64 code, such as `gcc -mx32`
836
// for 32-bit pointers in x86_64 code, such as `gcc -mx32`
837
typedef uint64_t reg_t;
837
typedef uint64_t reg_t;
838
typedef int64_t sreg_t;
838
typedef int64_t sreg_t;
839
#else
839
#else
840
typedef size_t reg_t;
840
typedef size_t reg_t;
841
typedef ssize_t sreg_t;
841
typedef ssize_t sreg_t;
842
#endif
842
#endif
843
843
844
#ifdef HAVE_CXX11_HEADERS
844
#ifdef HAVE_CXX11_HEADERS
845
using  native_t = typename integers_of_size<sizeof(reg_t)>::i;
845
using  native_t = typename integers_of_size<sizeof(reg_t)>::i;
846
using unative_t = typename integers_of_size<sizeof(reg_t)>::u;
846
using unative_t = typename integers_of_size<sizeof(reg_t)>::u;
847
#else
847
#else
848
typedef sreg_t native_t;
848
typedef sreg_t native_t;
849
typedef reg_t unative_t;
849
typedef reg_t unative_t;
850
#endif
850
#endif
851
EDUKE32_STATIC_ASSERT(sizeof(native_t) == sizeof(unative_t));
851
EDUKE32_STATIC_ASSERT(sizeof(native_t) == sizeof(unative_t));
852
852
853
typedef struct MAY_ALIAS {
853
typedef struct MAY_ALIAS {
854
    int32_t x, y;
854
    int32_t x, y;
855
} vec2_t;
855
} vec2_t;
856
856
857
typedef struct MAY_ALIAS {
857
typedef struct MAY_ALIAS {
858
    int16_t x, y;
858
    int16_t x, y;
859
} vec2_16_t;
859
} vec2_16_t;
860
860
861
typedef struct {
861
typedef struct {
862
    uint32_t x, y;
862
    uint32_t x, y;
863
} vec2u_t;
863
} vec2u_t;
864
864
865
typedef struct {
865
typedef struct {
866
    float x, y;
866
    float x, y;
867
} vec2f_t;
867
} vec2f_t;
868
868
869
typedef struct {
869
typedef struct {
870
    double x, y;
870
    double x, y;
871
} vec2d_t;
871
} vec2d_t;
872
872
873
typedef struct MAY_ALIAS {
873
typedef struct MAY_ALIAS {
874
    union {
874
    union {
875
        struct { int32_t x, y, z; };
875
        struct { int32_t x, y, z; };
876
        vec2_t  vec2;
876
        vec2_t  vec2;
877
    };
877
    };
878
} vec3_t;
878
} vec3_t;
879
879
880
typedef struct MAY_ALIAS {
880
typedef struct MAY_ALIAS {
881
    union {
881
    union {
882
        struct { int16_t x, y, z; };
882
        struct { int16_t x, y, z; };
883
        vec2_16_t vec2;
883
        vec2_16_t vec2;
884
    };
884
    };
885
} vec3_16_t;
885
} vec3_16_t;
886
886
887
typedef struct {
887
typedef struct {
888
    union {
888
    union {
889
        struct {
889
        struct {
890
            union { float x, d; };
890
            union { float x, d; };
891
            union { float y, u; };
891
            union { float y, u; };
892
            union { float z, v; };
892
            union { float z, v; };
893
        };
893
        };
894
        vec2f_t vec2;
894
        vec2f_t vec2;
895
    };
895
    };
896
} vec3f_t;
896
} vec3f_t;
897
897
898
EDUKE32_STATIC_ASSERT(sizeof(vec3f_t) == sizeof(float) * 3);
898
EDUKE32_STATIC_ASSERT(sizeof(vec3f_t) == sizeof(float) * 3);
899
899
900
typedef struct {
900
typedef struct {
901
    union { double x; double d; };
901
    union { double x; double d; };
902
    union { double y; double u; };
902
    union { double y; double u; };
903
    union { double z; double v; };
903
    union { double z; double v; };
904
} vec3d_t;
904
} vec3d_t;
905
905
906
EDUKE32_STATIC_ASSERT(sizeof(vec3d_t) == sizeof(double) * 3);
906
EDUKE32_STATIC_ASSERT(sizeof(vec3d_t) == sizeof(double) * 3);
907
907
908
typedef struct {
908
typedef struct {
909
    float x, y, z, w;
909
    float x, y, z, w;
910
} vec4f_t;
910
} vec4f_t;
911
911
912
typedef struct {
912
typedef struct {
913
    float x, y, z, w;
913
    float x, y, z, w;
914
} vec4d_t;
914
} vec4d_t;
915
915
916
916
917
////////// Language tricks that depend on size_t //////////
917
////////// Language tricks that depend on size_t //////////
918
918
919
#if defined _MSC_VER
919
#if defined _MSC_VER
920
# define ARRAY_SIZE(arr) _countof(arr)
920
# define ARRAY_SIZE(arr) _countof(arr)
921
#elif defined HAVE_CONSTEXPR
921
#elif defined HAVE_CONSTEXPR
922
template <typename T, size_t N>
922
template <typename T, size_t N>
923
static FORCE_INLINE constexpr size_t ARRAY_SIZE(T const (&)[N]) noexcept
923
static FORCE_INLINE constexpr size_t ARRAY_SIZE(T const (&)[N]) noexcept
924
{
924
{
925
    return N;
925
    return N;
926
}
926
}
927
#elif defined __cplusplus
927
#elif defined __cplusplus
928
struct bad_arg_to_ARRAY_SIZE
928
struct bad_arg_to_ARRAY_SIZE
929
{
929
{
930
   class Is_pointer; // incomplete
930
   class Is_pointer; // incomplete
931
   class Is_array {};
931
   class Is_array {};
932
   template <typename T>
932
   template <typename T>
933
   static Is_pointer check_type(const T*, const T* const*);
933
   static Is_pointer check_type(const T*, const T* const*);
934
   static Is_array check_type(const void*, const void*);
934
   static Is_array check_type(const void*, const void*);
935
};
935
};
936
# define ARRAY_SIZE(arr) ( \
936
# define ARRAY_SIZE(arr) ( \
937
   0 * sizeof(reinterpret_cast<const ::bad_arg_to_ARRAY_SIZE*>(arr)) + \
937
   0 * sizeof(reinterpret_cast<const ::bad_arg_to_ARRAY_SIZE*>(arr)) + \
938
   0 * sizeof(::bad_arg_to_ARRAY_SIZE::check_type((arr), &(arr))) + \
938
   0 * sizeof(::bad_arg_to_ARRAY_SIZE::check_type((arr), &(arr))) + \
939
   sizeof(arr) / sizeof((arr)[0]) )
939
   sizeof(arr) / sizeof((arr)[0]) )
940
#else
940
#else
941
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
941
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
942
#endif
942
#endif
943
#define ARRAY_SSIZE(arr) (native_t)ARRAY_SIZE(arr)
943
#define ARRAY_SSIZE(arr) (native_t)ARRAY_SIZE(arr)
944
944
945
945
946
////////// Memory management //////////
946
////////// Memory management //////////
947
947
948
#if !defined NO_ALIGNED_MALLOC
948
#if !defined NO_ALIGNED_MALLOC
949
static FORCE_INLINE void *Baligned_alloc(const size_t alignment, const size_t size)
949
static FORCE_INLINE void *Baligned_alloc(const size_t alignment, const size_t size)
950
{
950
{
951
#ifdef _WIN32
951
#ifdef _WIN32
952
    void *ptr = _aligned_malloc(size, alignment);
952
    void *ptr = _aligned_malloc(size, alignment);
953
#elif defined __APPLE__ || defined EDUKE32_BSD
953
#elif defined __APPLE__ || defined EDUKE32_BSD
954
    void *ptr = NULL;
954
    void *ptr = NULL;
955
    posix_memalign(&ptr, alignment, size);
955
    posix_memalign(&ptr, alignment, size);
956
#else
956
#else
957
    void *ptr = memalign(alignment, size);
957
    void *ptr = memalign(alignment, size);
958
#endif
958
#endif
959
959
960
    return ptr;
960
    return ptr;
961
}
961
}
962
#else
962
#else
963
# define Baligned_alloc(alignment, size) Bmalloc(size)
963
# define Baligned_alloc(alignment, size) Bmalloc(size)
964
#endif
964
#endif
965
965
966
#if defined _WIN32 && !defined NO_ALIGNED_MALLOC
966
#if defined _WIN32 && !defined NO_ALIGNED_MALLOC
967
# define Baligned_free _aligned_free
967
# define Baligned_free _aligned_free
968
#else
968
#else
969
# define Baligned_free Bfree
969
# define Baligned_free Bfree
970
#endif
970
#endif
971
971
972
972
973
////////// Pointer management //////////
973
////////// Pointer management //////////
974
974
975
#define DO_FREE_AND_NULL(var) do { \
975
#define DO_FREE_AND_NULL(var) do { \
976
    Xfree(var); (var) = NULL; \
976
    Xfree(var); (var) = NULL; \
977
} while (0)
977
} while (0)
978
978
979
#define ALIGNED_FREE_AND_NULL(var) do { \
979
#define ALIGNED_FREE_AND_NULL(var) do { \
980
    Xaligned_free(var); (var) = NULL; \
980
    Xaligned_free(var); (var) = NULL; \
981
} while (0)
981
} while (0)
982
982
983
983
984
////////// Data serialization //////////
984
////////// Data serialization //////////
985
985
986
static FORCE_INLINE CONSTEXPR uint16_t B_SWAP16_impl(uint16_t value)
986
static FORCE_INLINE CONSTEXPR uint16_t B_SWAP16_impl(uint16_t value)
987
{
987
{
988
    return
988
    return
989
        ((value & 0xFF00u) >> 8u) |
989
        ((value & 0xFF00u) >> 8u) |
990
        ((value & 0x00FFu) << 8u);
990
        ((value & 0x00FFu) << 8u);
991
}
991
}
992
static FORCE_INLINE CONSTEXPR uint32_t B_SWAP32_impl(uint32_t value)
992
static FORCE_INLINE CONSTEXPR uint32_t B_SWAP32_impl(uint32_t value)
993
{
993
{
994
    return
994
    return
995
        ((value & 0xFF000000u) >> 24u) |
995
        ((value & 0xFF000000u) >> 24u) |
996
        ((value & 0x00FF0000u) >>  8u) |
996
        ((value & 0x00FF0000u) >>  8u) |
997
        ((value & 0x0000FF00u) <<  8u) |
997
        ((value & 0x0000FF00u) <<  8u) |
998
        ((value & 0x000000FFu) << 24u);
998
        ((value & 0x000000FFu) << 24u);
999
}
999
}
1000
static FORCE_INLINE CONSTEXPR uint64_t B_SWAP64_impl(uint64_t value)
1000
static FORCE_INLINE CONSTEXPR uint64_t B_SWAP64_impl(uint64_t value)
1001
{
1001
{
1002
    return
1002
    return
1003
      ((value & 0xFF00000000000000ULL) >> 56ULL) |
1003
      ((value & 0xFF00000000000000ULL) >> 56ULL) |
1004
      ((value & 0x00FF000000000000ULL) >> 40ULL) |
1004
      ((value & 0x00FF000000000000ULL) >> 40ULL) |
1005
      ((value & 0x0000FF0000000000ULL) >> 24ULL) |
1005
      ((value & 0x0000FF0000000000ULL) >> 24ULL) |
1006
      ((value & 0x000000FF00000000ULL) >>  8ULL) |
1006
      ((value & 0x000000FF00000000ULL) >>  8ULL) |
1007
      ((value & 0x00000000FF000000ULL) <<  8ULL) |
1007
      ((value & 0x00000000FF000000ULL) <<  8ULL) |
1008
      ((value & 0x0000000000FF0000ULL) << 24ULL) |
1008
      ((value & 0x0000000000FF0000ULL) << 24ULL) |
1009
      ((value & 0x000000000000FF00ULL) << 40ULL) |
1009
      ((value & 0x000000000000FF00ULL) << 40ULL) |
1010
      ((value & 0x00000000000000FFULL) << 56ULL);
1010
      ((value & 0x00000000000000FFULL) << 56ULL);
1011
}
1011
}
1012
1012
1013
/* The purpose of B_PASS* as functions, as opposed to macros, is to prevent them from being used as lvalues. */
1013
/* The purpose of B_PASS* as functions, as opposed to macros, is to prevent them from being used as lvalues. */
1014
#if CXXSTD >= 2011 || EDUKE32_MSVC_PREREQ(1900)
1014
#if CXXSTD >= 2011 || EDUKE32_MSVC_PREREQ(1900)
1015
template <typename T>
1015
template <typename T>
1016
static FORCE_INLINE CONSTEXPR take_sign_t<int16_t, T> B_SWAP16(T x)
1016
static FORCE_INLINE CONSTEXPR take_sign_t<int16_t, T> B_SWAP16(T x)
1017
{
1017
{
1018
    return static_cast< take_sign_t<int16_t, T> >(B_SWAP16_impl(static_cast<uint16_t>(x)));
1018
    return static_cast< take_sign_t<int16_t, T> >(B_SWAP16_impl(static_cast<uint16_t>(x)));
1019
}
1019
}
1020
template <typename T>
1020
template <typename T>
1021
static FORCE_INLINE CONSTEXPR take_sign_t<int32_t, T> B_SWAP32(T x)
1021
static FORCE_INLINE CONSTEXPR take_sign_t<int32_t, T> B_SWAP32(T x)
1022
{
1022
{
1023
    return static_cast< take_sign_t<int32_t, T> >(B_SWAP32_impl(static_cast<uint32_t>(x)));
1023
    return static_cast< take_sign_t<int32_t, T> >(B_SWAP32_impl(static_cast<uint32_t>(x)));
1024
}
1024
}
1025
template <typename T>
1025
template <typename T>
1026
static FORCE_INLINE CONSTEXPR take_sign_t<int64_t, T> B_SWAP64(T x)
1026
static FORCE_INLINE CONSTEXPR take_sign_t<int64_t, T> B_SWAP64(T x)
1027
{
1027
{
1028
    return static_cast< take_sign_t<int64_t, T> >(B_SWAP64_impl(static_cast<uint64_t>(x)));
1028
    return static_cast< take_sign_t<int64_t, T> >(B_SWAP64_impl(static_cast<uint64_t>(x)));
1029
}
1029
}
1030
1030
1031
template <typename T>
1031
template <typename T>
1032
static FORCE_INLINE CONSTEXPR take_sign_t<int16_t, T> B_PASS16(T x)
1032
static FORCE_INLINE CONSTEXPR take_sign_t<int16_t, T> B_PASS16(T x)
1033
{
1033
{
1034
    return static_cast< take_sign_t<int16_t, T> >(x);
1034
    return static_cast< take_sign_t<int16_t, T> >(x);
1035
}
1035
}
1036
template <typename T>
1036
template <typename T>
1037
static FORCE_INLINE CONSTEXPR take_sign_t<int32_t, T> B_PASS32(T x)
1037
static FORCE_INLINE CONSTEXPR take_sign_t<int32_t, T> B_PASS32(T x)
1038
{
1038
{
1039
    return static_cast< take_sign_t<int32_t, T> >(x);
1039
    return static_cast< take_sign_t<int32_t, T> >(x);
1040
}
1040
}
1041
template <typename T>
1041
template <typename T>
1042
static FORCE_INLINE CONSTEXPR take_sign_t<int64_t, T> B_PASS64(T x)
1042
static FORCE_INLINE CONSTEXPR take_sign_t<int64_t, T> B_PASS64(T x)
1043
{
1043
{
1044
    return static_cast< take_sign_t<int64_t, T> >(x);
1044
    return static_cast< take_sign_t<int64_t, T> >(x);
1045
}
1045
}
1046
#else
1046
#else
1047
#define B_SWAP16(x) B_SWAP16_impl(x)
1047
#define B_SWAP16(x) B_SWAP16_impl(x)
1048
#define B_SWAP32(x) B_SWAP32_impl(x)
1048
#define B_SWAP32(x) B_SWAP32_impl(x)
1049
#define B_SWAP64(x) B_SWAP64_impl(x)
1049
#define B_SWAP64(x) B_SWAP64_impl(x)
1050
1050
1051
static FORCE_INLINE CONSTEXPR uint16_t B_PASS16(uint16_t const x) { return x; }
1051
static FORCE_INLINE CONSTEXPR uint16_t B_PASS16(uint16_t const x) { return x; }
1052
static FORCE_INLINE CONSTEXPR uint32_t B_PASS32(uint32_t const x) { return x; }
1052
static FORCE_INLINE CONSTEXPR uint32_t B_PASS32(uint32_t const x) { return x; }
1053
static FORCE_INLINE CONSTEXPR uint64_t B_PASS64(uint64_t const x) { return x; }
1053
static FORCE_INLINE CONSTEXPR uint64_t B_PASS64(uint64_t const x) { return x; }
1054
#endif
1054
#endif
1055
1055
1056
#if B_LITTLE_ENDIAN == 1
1056
#if B_LITTLE_ENDIAN == 1
1057
# define B_LITTLE64(x) B_PASS64(x)
1057
# define B_LITTLE64(x) B_PASS64(x)
1058
# define B_BIG64(x)    B_SWAP64(x)
1058
# define B_BIG64(x)    B_SWAP64(x)
1059
# define B_LITTLE32(x) B_PASS32(x)
1059
# define B_LITTLE32(x) B_PASS32(x)
1060
# define B_BIG32(x)    B_SWAP32(x)
1060
# define B_BIG32(x)    B_SWAP32(x)
1061
# define B_LITTLE16(x) B_PASS16(x)
1061
# define B_LITTLE16(x) B_PASS16(x)
1062
# define B_BIG16(x)    B_SWAP16(x)
1062
# define B_BIG16(x)    B_SWAP16(x)
1063
#elif B_BIG_ENDIAN == 1
1063
#elif B_BIG_ENDIAN == 1
1064
# define B_LITTLE64(x) B_SWAP64(x)
1064
# define B_LITTLE64(x) B_SWAP64(x)
1065
# define B_BIG64(x)    B_PASS64(x)
1065
# define B_BIG64(x)    B_PASS64(x)
1066
# define B_LITTLE32(x) B_SWAP32(x)
1066
# define B_LITTLE32(x) B_SWAP32(x)
1067
# define B_BIG32(x)    B_PASS32(x)
1067
# define B_BIG32(x)    B_PASS32(x)
1068
# define B_LITTLE16(x) B_SWAP16(x)
1068
# define B_LITTLE16(x) B_SWAP16(x)
1069
# define B_BIG16(x)    B_PASS16(x)
1069
# define B_BIG16(x)    B_PASS16(x)
1070
#endif
1070
#endif
1071
1071
1072
// TODO: Determine when, if ever, we should use the bit-shift-and-mask variants
1072
// TODO: Determine when, if ever, we should use the bit-shift-and-mask variants
1073
// due to alignment issues or performance gains.
1073
// due to alignment issues or performance gains.
1074
#if 1
1074
#if 1
1075
static FORCE_INLINE void B_BUF16(void * const buf, uint16_t const x) { *(uint16_t *) buf = x; }
1075
static FORCE_INLINE void B_BUF16(void * const buf, uint16_t const x) { *(uint16_t *) buf = x; }
1076
static FORCE_INLINE void B_BUF32(void * const buf, uint32_t const x) { *(uint32_t *) buf = x; }
1076
static FORCE_INLINE void B_BUF32(void * const buf, uint32_t const x) { *(uint32_t *) buf = x; }
1077
static FORCE_INLINE void B_BUF64(void * const buf, uint64_t const x) { *(uint64_t *) buf = x; }
1077
static FORCE_INLINE void B_BUF64(void * const buf, uint64_t const x) { *(uint64_t *) buf = x; }
1078
1078
1079
static FORCE_INLINE CONSTEXPR uint16_t B_UNBUF16(void const * const buf) { return *(uint16_t const *) buf; }
1079
static FORCE_INLINE CONSTEXPR uint16_t B_UNBUF16(void const * const buf) { return *(uint16_t const *) buf; }
1080
static FORCE_INLINE CONSTEXPR uint32_t B_UNBUF32(void const * const buf) { return *(uint32_t const *) buf; }
1080
static FORCE_INLINE CONSTEXPR uint32_t B_UNBUF32(void const * const buf) { return *(uint32_t const *) buf; }
1081
static FORCE_INLINE CONSTEXPR uint64_t B_UNBUF64(void const * const buf) { return *(uint64_t const *) buf; }
1081
static FORCE_INLINE CONSTEXPR uint64_t B_UNBUF64(void const * const buf) { return *(uint64_t const *) buf; }
1082
#else
1082
#else
1083
static FORCE_INLINE void B_BUF16(void * const vbuf, uint16_t const x)
1083
static FORCE_INLINE void B_BUF16(void * const vbuf, uint16_t const x)
1084
{
1084
{
1085
    uint8_t * const buf = (uint8_t *) vbuf;
1085
    uint8_t * const buf = (uint8_t *) vbuf;
1086
    buf[0] = (x & 0x00FF);
1086
    buf[0] = (x & 0x00FF);
1087
    buf[1] = (x & 0xFF00) >> 8;
1087
    buf[1] = (x & 0xFF00) >> 8;
1088
}
1088
}
1089
static FORCE_INLINE void B_BUF32(void * const vbuf, uint32_t const x)
1089
static FORCE_INLINE void B_BUF32(void * const vbuf, uint32_t const x)
1090
{
1090
{
1091
    uint8_t * const buf = (uint8_t *) vbuf;
1091
    uint8_t * const buf = (uint8_t *) vbuf;
1092
    buf[0] = (x & 0x000000FF);
1092
    buf[0] = (x & 0x000000FF);
1093
    buf[1] = (x & 0x0000FF00) >> 8;
1093
    buf[1] = (x & 0x0000FF00) >> 8;
1094
    buf[2] = (x & 0x00FF0000) >> 16;
1094
    buf[2] = (x & 0x00FF0000) >> 16;
1095
    buf[3] = (x & 0xFF000000) >> 24;
1095
    buf[3] = (x & 0xFF000000) >> 24;
1096
}
1096
}
1097
# if 0
1097
# if 0
1098
// i686-apple-darwin11-llvm-gcc-4.2 complains "integer constant is too large for 'long' type"
1098
// i686-apple-darwin11-llvm-gcc-4.2 complains "integer constant is too large for 'long' type"
1099
static FORCE_INLINE void B_BUF64(void * const vbuf, uint64_t const x)
1099
static FORCE_INLINE void B_BUF64(void * const vbuf, uint64_t const x)
1100
{
1100
{
1101
    uint8_t * const buf = (uint8_t *) vbuf;
1101
    uint8_t * const buf = (uint8_t *) vbuf;
1102
    buf[0] = (x & 0x00000000000000FF);
1102
    buf[0] = (x & 0x00000000000000FF);
1103
    buf[1] = (x & 0x000000000000FF00) >> 8;
1103
    buf[1] = (x & 0x000000000000FF00) >> 8;
1104
    buf[2] = (x & 0x0000000000FF0000) >> 16;
1104
    buf[2] = (x & 0x0000000000FF0000) >> 16;
1105
    buf[3] = (x & 0x00000000FF000000) >> 24;
1105
    buf[3] = (x & 0x00000000FF000000) >> 24;
1106
    buf[4] = (x & 0x000000FF00000000) >> 32;
1106
    buf[4] = (x & 0x000000FF00000000) >> 32;
1107
    buf[5] = (x & 0x0000FF0000000000) >> 40;
1107
    buf[5] = (x & 0x0000FF0000000000) >> 40;
1108
    buf[6] = (x & 0x00FF000000000000) >> 48;
1108
    buf[6] = (x & 0x00FF000000000000) >> 48;
1109
    buf[7] = (x & 0xFF00000000000000) >> 56;
1109
    buf[7] = (x & 0xFF00000000000000) >> 56;
1110
}
1110
}
1111
# endif
1111
# endif
1112
1112
1113
static FORCE_INLINE uint16_t B_UNBUF16(void const * const vbuf)
1113
static FORCE_INLINE uint16_t B_UNBUF16(void const * const vbuf)
1114
{
1114
{
1115
    uint8_t const * const buf = (uint8_t const *) vbuf;
1115
    uint8_t const * const buf = (uint8_t const *) vbuf;
1116
    return (buf[1] << 8) | (buf[0]);
1116
    return (buf[1] << 8) | (buf[0]);
1117
}
1117
}
1118
static FORCE_INLINE uint32_t B_UNBUF32(void const * const vbuf)
1118
static FORCE_INLINE uint32_t B_UNBUF32(void const * const vbuf)
1119
{
1119
{
1120
    uint8_t const * const buf = (uint8_t const *) vbuf;
1120
    uint8_t const * const buf = (uint8_t const *) vbuf;
1121
    return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | (buf[0]);
1121
    return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | (buf[0]);
1122
}
1122
}
1123
static FORCE_INLINE uint64_t B_UNBUF64(void const * const vbuf)
1123
static FORCE_INLINE uint64_t B_UNBUF64(void const * const vbuf)
1124
{
1124
{
1125
    uint8_t const * const buf = (uint8_t const *) vbuf;
1125
    uint8_t const * const buf = (uint8_t const *) vbuf;
1126
    return ((uint64_t)buf[7] << 56) | ((uint64_t)buf[6] << 48) | ((uint64_t)buf[5] << 40) |
1126
    return ((uint64_t)buf[7] << 56) | ((uint64_t)buf[6] << 48) | ((uint64_t)buf[5] << 40) |
1127
        ((uint64_t)buf[4] << 32) | (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | (buf[0]);
1127
        ((uint64_t)buf[4] << 32) | (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | (buf[0]);
1128
}
1128
}
1129
#endif
1129
#endif
1130
1130
1131
1131
1132
////////// Abstract data operations //////////
1132
////////// Abstract data operations //////////
1133
1133
1134
#define ABSTRACT_DECL static FORCE_INLINE WARN_UNUSED_RESULT CONSTEXPR
1134
#define ABSTRACT_DECL static FORCE_INLINE WARN_UNUSED_RESULT CONSTEXPR
1135
1135
1136
#ifdef __cplusplus
1136
#ifdef __cplusplus
1137
template <typename T, typename X, typename Y> ABSTRACT_DECL T clamp(T in, X min, Y max) { return in <= (T) min ? (T) min : (in >= (T) max ? (T) max : in); }
1137
template <typename T, typename X, typename Y> ABSTRACT_DECL T clamp(T in, X min, Y max) { return in <= (T) min ? (T) min : (in >= (T) max ? (T) max : in); }
1138
template <typename T, typename X, typename Y> ABSTRACT_DECL T clamp2(T in, X min, Y max) { return in >= (T) max ? (T) max : (in <= (T) min ? (T) min : in); }
1138
template <typename T, typename X, typename Y> ABSTRACT_DECL T clamp2(T in, X min, Y max) { return in >= (T) max ? (T) max : (in <= (T) min ? (T) min : in); }
1139
using std::min;
1139
using std::min;
1140
using std::max;
1140
using std::max;
1141
# define fclamp clamp
1141
# define fclamp clamp
1142
# define fclamp2 clamp2
1142
# define fclamp2 clamp2
1143
#else
1143
#else
1144
// Clamp <in> to [<min>..<max>]. The case in <= min is handled first.
1144
// Clamp <in> to [<min>..<max>]. The case in <= min is handled first.
1145
ABSTRACT_DECL int32_t clamp(int32_t in, int32_t min, int32_t max) { return in <= min ? min : (in >= max ? max : in); }
1145
ABSTRACT_DECL int32_t clamp(int32_t in, int32_t min, int32_t max) { return in <= min ? min : (in >= max ? max : in); }
1146
ABSTRACT_DECL float fclamp(float in, float min, float max) { return in <= min ? min : (in >= max ? max : in); }
1146
ABSTRACT_DECL float fclamp(float in, float min, float max) { return in <= min ? min : (in >= max ? max : in); }
1147
// Clamp <in> to [<min>..<max>]. The case in >= max is handled first.
1147
// Clamp <in> to [<min>..<max>]. The case in >= max is handled first.
1148
ABSTRACT_DECL int32_t clamp2(int32_t in, int32_t min, int32_t max) { return in >= max ? max : (in <= min ? min : in); }
1148
ABSTRACT_DECL int32_t clamp2(int32_t in, int32_t min, int32_t max) { return in >= max ? max : (in <= min ? min : in); }
1149
ABSTRACT_DECL float fclamp2(float in, float min, float max) { return in >= max ? max : (in <= min ? min : in); }
1149
ABSTRACT_DECL float fclamp2(float in, float min, float max) { return in >= max ? max : (in <= min ? min : in); }
1150
1150
1151
#ifndef min
1151
#ifndef min
1152
# define min(a, b) (((a) < (b)) ? (a) : (b))
1152
# define min(a, b) (((a) < (b)) ? (a) : (b))
1153
#endif
1153
#endif
1154
#ifndef max
1154
#ifndef max
1155
# define max(a, b) (((a) > (b)) ? (a) : (b))
1155
# define max(a, b) (((a) > (b)) ? (a) : (b))
1156
#endif
1156
#endif
1157
#endif
1157
#endif
1158
1158
1159
////////// Mathematical operations //////////
1159
////////// Mathematical operations //////////
1160
1160
1161
#ifdef __cplusplus
1161
#ifdef __cplusplus
1162
#ifdef HAVE_CXX11_HEADERS
1162
#ifdef HAVE_CXX11_HEADERS
1163
template <typename T>
1163
template <typename T>
1164
struct DivResult
1164
struct DivResult
1165
{
1165
{
1166
    T q; // quotient
1166
    T q; // quotient
1167
    T r; // remainder
1167
    T r; // remainder
1168
};
1168
};
1169
template <typename T>
1169
template <typename T>
1170
FORCE_INLINE CONSTEXPR DivResult<T> divide(T lhs, T rhs)
1170
FORCE_INLINE CONSTEXPR DivResult<T> divide(T lhs, T rhs)
1171
{
1171
{
1172
    return DivResult<T>{(T)(lhs / rhs), (T)(lhs % rhs)};
1172
    return DivResult<T>{(T)(lhs / rhs), (T)(lhs % rhs)};
1173
}
1173
}
1174
template <native_t base, typename T>
1174
template <native_t base, typename T>
1175
FORCE_INLINE CONSTEXPR DivResult<T> divrhs(T lhs)
1175
FORCE_INLINE CONSTEXPR DivResult<T> divrhs(T lhs)
1176
{
1176
{
1177
    return divide(lhs, (T)base);
1177
    return divide(lhs, (T)base);
1178
}
1178
}
1179
1179
1180
template <typename T, typename T2>
1180
template <typename T, typename T2>
1181
static FORCE_INLINE CONSTEXPR_CXX14 enable_if_t<is_signed<T>::value, T> NEGATE_ON_CONDITION(T value, T2 condition)
1181
static FORCE_INLINE CONSTEXPR_CXX14 enable_if_t<is_signed<T>::value, T> NEGATE_ON_CONDITION(T value, T2 condition)
1182
{
1182
{
1183
    T const invert = !!condition;
1183
    T const invert = !!condition;
1184
    return (value ^ -invert) + invert;
1184
    return (value ^ -invert) + invert;
1185
}
1185
}
1186
#endif
1186
#endif
1187
1187
1188
template <size_t base, typename T>
1188
template <size_t base, typename T>
1189
CONSTEXPR size_t logbase(T n)
1189
CONSTEXPR size_t logbase(T n)
1190
{
1190
{
1191
    return n < static_cast<T>(base) ? 1 : 1 + logbase<base>(n / static_cast<T>(base));
1191
    return n < static_cast<T>(base) ? 1 : 1 + logbase<base>(n / static_cast<T>(base));
1192
}
1192
}
1193
// hackish version to work around the impossibility of representing abs(INT*_MIN)
1193
// hackish version to work around the impossibility of representing abs(INT*_MIN)
1194
template <size_t base, typename T>
1194
template <size_t base, typename T>
1195
CONSTEXPR size_t logbasenegative(T n)
1195
CONSTEXPR size_t logbasenegative(T n)
1196
{
1196
{
1197
    return n > static_cast<T>(-(native_t)base) ? 1 : 1 + logbase<base>(n / static_cast<T>(-(native_t)base));
1197
    return n > static_cast<T>(-(native_t)base) ? 1 : 1 + logbase<base>(n / static_cast<T>(-(native_t)base));
1198
}
1198
}
1199
1199
1200
#endif
1200
#endif
1201
1201
1202
#define isPow2OrZero(v) (((v) & ((v) - 1)) == 0)
1202
#define isPow2OrZero(v) (((v) & ((v) - 1)) == 0)
1203
#define isPow2(v) (isPow2OrZero(v) && (v))
1203
#define isPow2(v) (isPow2OrZero(v) && (v))
1204
1204
1205
////////// Bitfield manipulation //////////
1205
////////// Bitfield manipulation //////////
1206
1206
1207
static CONSTEXPR const char pow2char[8] = {1,2,4,8,16,32,64,128u};
1207
static CONSTEXPR const char pow2char[8] = {1,2,4,8,16,32,64,128u};
1208
1208
1209
static FORCE_INLINE void bitmap_set(uint8_t *const ptr, int const n) { ptr[n>>3] |= pow2char[n&7]; }
1209
static FORCE_INLINE void bitmap_set(uint8_t *const ptr, int const n) { ptr[n>>3] |= pow2char[n&7]; }
1210
static FORCE_INLINE void bitmap_clear(uint8_t *const ptr, int const n) { ptr[n>>3] &= ~pow2char[n&7]; }
1210
static FORCE_INLINE void bitmap_clear(uint8_t *const ptr, int const n) { ptr[n>>3] &= ~pow2char[n&7]; }
1211
static FORCE_INLINE CONSTEXPR char bitmap_test(uint8_t const *const ptr, int const n) { return ptr[n>>3] & pow2char[n&7]; }
1211
static FORCE_INLINE CONSTEXPR char bitmap_test(uint8_t const *const ptr, int const n) { return ptr[n>>3] & pow2char[n&7]; }
1212
1212
1213
////////// Utility functions //////////
1213
////////// Utility functions //////////
1214
1214
1215
// breadth-first search helpers
1215
// breadth-first search helpers
1216
template <typename T>
1216
template <typename T>
1217
void bfirst_search_init(T *const list, uint8_t *const bitmap, T *const eltnumptr, int const maxelts, int const firstelt)
1217
void bfirst_search_init(T *const list, uint8_t *const bitmap, T *const eltnumptr, int const maxelts, int const firstelt)
1218
{
1218
{
1219
    Bmemset(bitmap, 0, (maxelts+7)>>3);
1219
    Bmemset(bitmap, 0, (maxelts+7)>>3);
1220
1220
1221
    list[0] = firstelt;
1221
    list[0] = firstelt;
1222
    bitmap_set(bitmap, firstelt);
1222
    bitmap_set(bitmap, firstelt);
1223
    *eltnumptr = 1;
1223
    *eltnumptr = 1;
1224
}
1224
}
1225
1225
1226
template <typename T>
1226
template <typename T>
1227
void bfirst_search_try(T *const list, uint8_t *const bitmap, T *const eltnumptr, int const elt)
1227
void bfirst_search_try(T *const list, uint8_t *const bitmap, T *const eltnumptr, int const elt)
1228
{
1228
{
1229
    if (!bitmap_test(bitmap, elt))
1229
    if (!bitmap_test(bitmap, elt))
1230
    {
1230
    {
1231
        bitmap_set(bitmap, elt);
1231
        bitmap_set(bitmap, elt);
1232
        list[(*eltnumptr)++] = elt;
1232
        list[(*eltnumptr)++] = elt;
1233
    }
1233
    }
1234
}
1234
}
1235
1235
1236
#if RAND_MAX == 32767
1236
#if RAND_MAX == 32767
1237
static FORCE_INLINE uint16_t system_15bit_rand(void) { return (uint16_t)rand(); }
1237
static FORCE_INLINE uint16_t system_15bit_rand(void) { return (uint16_t)rand(); }
1238
#else  // RAND_MAX > 32767, assumed to be of the form 2^k - 1
1238
#else  // RAND_MAX > 32767, assumed to be of the form 2^k - 1
1239
static FORCE_INLINE uint16_t system_15bit_rand(void) { return ((uint16_t)rand())&0x7fff; }
1239
static FORCE_INLINE uint16_t system_15bit_rand(void) { return ((uint16_t)rand())&0x7fff; }
1240
#endif
1240
#endif
1241
1241
1242
// Copy min(strlen(src)+1, n) characters into dst, always terminate with a NUL.
1242
// Copy min(strlen(src)+1, n) characters into dst, always terminate with a NUL.
1243
static FORCE_INLINE char *Bstrncpyz(char *dst, const char *src, bsize_t n)
1243
static FORCE_INLINE char *Bstrncpyz(char *dst, const char *src, bsize_t n)
1244
{
1244
{
1245
    Bstrncpy(dst, src, n);
1245
    Bstrncpy(dst, src, n);
1246
    dst[n-1] = 0;
1246
    dst[n-1] = 0;
1247
    return dst;
1247
    return dst;
1248
}
1248
}
1249
1249
1250
// Append extension when <outbuf> contains no dot.
1250
// Append extension when <outbuf> contains no dot.
1251
// <ext> can be like ".mhk" or like "_crash.map", no need to start with a dot.
1251
// <ext> can be like ".mhk" or like "_crash.map", no need to start with a dot.
1252
// The ugly name is deliberate: we should be checking the sizes of all buffers!
1252
// The ugly name is deliberate: we should be checking the sizes of all buffers!
1253
static inline void append_ext_UNSAFE(char *outbuf, const char *ext)
1253
static inline void append_ext_UNSAFE(char *outbuf, const char *ext)
1254
{
1254
{
1255
    char *p = Bstrrchr(outbuf,'.');
1255
    char *p = Bstrrchr(outbuf,'.');
1256
1256
1257
    if (!p)
1257
    if (!p)
1258
        Bstrcat(outbuf, ext);
1258
        Bstrcat(outbuf, ext);
1259
    else
1259
    else
1260
        Bstrcpy(p, ext);
1260
        Bstrcpy(p, ext);
1261
}
1261
}
1262
1262
1263
/* Begin dependence on compat.o object. */
1263
/* Begin dependence on compat.o object. */
1264
1264
1265
1265
1266
#ifdef __cplusplus
1266
#ifdef __cplusplus
1267
extern "C" {
1267
extern "C" {
1268
#endif
1268
#endif
1269
1269
1270
1270
1271
#ifndef USE_PHYSFS
1271
#ifndef USE_PHYSFS
1272
////////// Directory enumeration //////////
1272
////////// Directory enumeration //////////
1273
1273
1274
struct Bdirent
1274
struct Bdirent
1275
{
1275
{
1276
    char *name;
1276
    char *name;
1277
    uint32_t mode;
1277
    uint32_t mode;
1278
    uint32_t size;
1278
    uint32_t size;
1279
    uint32_t mtime;
1279
    uint32_t mtime;
1280
    uint16_t namlen;
1280
    uint16_t namlen;
1281
};
1281
};
1282
1282
1283
typedef void BDIR;
1283
typedef void BDIR;
1284
1284
1285
BDIR *Bopendir(const char *name);
1285
BDIR *Bopendir(const char *name);
1286
struct Bdirent *Breaddir(BDIR *dir);
1286
struct Bdirent *Breaddir(BDIR *dir);
1287
int32_t Bclosedir(BDIR *dir);
1287
int32_t Bclosedir(BDIR *dir);
1288
#endif
1288
#endif
1289
1289
1290
1290
1291
////////// Paths //////////
1291
////////// Paths //////////
1292
1292
1293
char *Bgethomedir(void);
1293
char *Bgethomedir(void);
1294
char *Bgetappdir(void);
1294
char *Bgetappdir(void);
1295
1295
1296
int32_t Bcorrectfilename(char *filename, int32_t removefn);
1296
int32_t Bcorrectfilename(char *filename, int32_t removefn);
1297
int32_t Bcanonicalisefilename(char *filename, int32_t removefn);
1297
int32_t Bcanonicalisefilename(char *filename, int32_t removefn);
1298
1298
1299
char *Bgetsystemdrives(void);
1299
char *Bgetsystemdrives(void);
1300
1300
1301
1301
1302
////////// String manipulation //////////
1302
////////// String manipulation //////////
1303
1303
1304
char *Bstrtoken(char *s, const char *delim, char **ptrptr, int chop);
1304
char *Bstrtoken(char *s, const char *delim, char **ptrptr, int chop);
1305
char *Bstrtolower(char *str);
1305
char *Bstrtolower(char *str);
1306
1306
1307
#define Bwildmatch wildmatch
1307
#define Bwildmatch wildmatch
1308
1308
1309
#ifdef _WIN32
1309
#ifdef _WIN32
1310
# ifdef _MSC_VER
1310
# ifdef _MSC_VER
1311
#  define Bstrlwr _strlwr
1311
#  define Bstrlwr _strlwr
1312
#  define Bstrupr _strupr
1312
#  define Bstrupr _strupr
1313
# else
1313
# else
1314
#  define Bstrlwr strlwr
1314
#  define Bstrlwr strlwr
1315
#  define Bstrupr strupr
1315
#  define Bstrupr strupr
1316
# endif
1316
# endif
1317
#else
1317
#else
1318
char *Bstrlwr(char *);
1318
char *Bstrlwr(char *);
1319
char *Bstrupr(char *);
1319
char *Bstrupr(char *);
1320
#endif
1320
#endif
1321
1321
1322
////////// Miscellaneous //////////
1322
////////// Miscellaneous //////////
1323
1323
1324
int Bgetpagesize(void);
1324
int Bgetpagesize(void);
1325
size_t Bgetsysmemsize(void);
1325
size_t Bgetsysmemsize(void);
1326
1326
1327
////////// PANICKING ALLOCATION WRAPPERS //////////
1327
////////// PANICKING ALLOCATION WRAPPERS //////////
1328
1328
1329
#ifdef DEBUGGINGAIDS
1329
#ifdef DEBUGGINGAIDS
1330
extern void xalloc_set_location(int32_t line, const char *file, const char *func);
1330
extern void xalloc_set_location(int32_t line, const char *file, const char *func);
1331
#endif
1331
#endif
1332
void set_memerr_handler(void (*handlerfunc)(int32_t, const char *, const char *));
1332
void set_memerr_handler(void (*handlerfunc)(int32_t, const char *, const char *));
1333
void *handle_memerr(void *);
1333
void *handle_memerr(void *);
1334
1334
1335
static FORCE_INLINE char *xstrdup(const char *s)
1335
static FORCE_INLINE char *xstrdup(const char *s)
1336
{
1336
{
1337
    char *ptr = Bstrdup(s);
1337
    char *ptr = Bstrdup(s);
1338
    return (EDUKE32_PREDICT_TRUE(ptr != NULL)) ? ptr : (char *)handle_memerr(ptr);
1338
    return (EDUKE32_PREDICT_TRUE(ptr != NULL)) ? ptr : (char *)handle_memerr(ptr);
1339
}
1339
}
1340
1340
1341
static FORCE_INLINE void *xmalloc(const bsize_t size)
1341
static FORCE_INLINE void *xmalloc(const bsize_t size)
1342
{
1342
{
1343
    void *ptr = Bmalloc(size);
1343
    void *ptr = Bmalloc(size);
1344
    return (EDUKE32_PREDICT_TRUE(ptr != NULL)) ? ptr : handle_memerr(ptr);
1344
    return (EDUKE32_PREDICT_TRUE(ptr != NULL)) ? ptr : handle_memerr(ptr);
1345
}
1345
}
1346
1346
1347
static FORCE_INLINE void *xcalloc(const bsize_t nmemb, const bsize_t size)
1347
static FORCE_INLINE void *xcalloc(const bsize_t nmemb, const bsize_t size)
1348
{
1348
{
1349
    void *ptr = Bcalloc(nmemb, size);
1349
    void *ptr = Bcalloc(nmemb, size);
1350
    return (EDUKE32_PREDICT_TRUE(ptr != NULL)) ? ptr : handle_memerr(ptr);
1350
    return (EDUKE32_PREDICT_TRUE(ptr != NULL)) ? ptr : handle_memerr(ptr);
1351
}
1351
}
1352
1352
1353
static FORCE_INLINE void *xrealloc(void * const ptr, const bsize_t size)
1353
static FORCE_INLINE void *xrealloc(void * const ptr, const bsize_t size)
1354
{
1354
{
1355
    void *newptr = Brealloc(ptr, size);
1355
    void *newptr = Brealloc(ptr, size);
1356
1356
1357
    // According to the C Standard,
1357
    // According to the C Standard,
1358
    //  - ptr == NULL makes realloc() behave like malloc()
1358
    //  - ptr == NULL makes realloc() behave like malloc()
1359
    //  - size == 0 make it behave like free() if ptr != NULL
1359
    //  - size == 0 make it behave like free() if ptr != NULL
1360
    // Since we want to catch an out-of-mem in the first case, this leaves:
1360
    // Since we want to catch an out-of-mem in the first case, this leaves:
1361
    return (EDUKE32_PREDICT_TRUE(newptr != NULL || size == 0)) ? newptr: handle_memerr(ptr);
1361
    return (EDUKE32_PREDICT_TRUE(newptr != NULL || size == 0)) ? newptr: handle_memerr(ptr);
1362
}
1362
}
1363
1363
1364
#if !defined NO_ALIGNED_MALLOC
1364
#if !defined NO_ALIGNED_MALLOC
1365
static FORCE_INLINE void *xaligned_alloc(const bsize_t alignment, const bsize_t size)
1365
static FORCE_INLINE void *xaligned_alloc(const bsize_t alignment, const bsize_t size)
1366
{
1366
{
1367
    void *ptr = Baligned_alloc(alignment, size);
1367
    void *ptr = Baligned_alloc(alignment, size);
1368
    return (EDUKE32_PREDICT_TRUE(ptr != NULL)) ? ptr : handle_memerr(ptr);
1368
    return (EDUKE32_PREDICT_TRUE(ptr != NULL)) ? ptr : handle_memerr(ptr);
1369
}
1369
}
1370
1370
1371
static FORCE_INLINE void *xaligned_calloc(const bsize_t alignment, const bsize_t count, const bsize_t size)
1371
static FORCE_INLINE void *xaligned_calloc(const bsize_t alignment, const bsize_t count, const bsize_t size)
1372
{
1372
{
1373
    bsize_t const blocksize = count * size;
1373
    bsize_t const blocksize = count * size;
1374
    void *ptr = Baligned_alloc(alignment, blocksize);
1374
    void *ptr = Baligned_alloc(alignment, blocksize);
1375
    if (EDUKE32_PREDICT_TRUE(ptr != NULL))
1375
    if (EDUKE32_PREDICT_TRUE(ptr != NULL))
1376
    {
1376
    {
1377
        Bmemset(ptr, 0, blocksize);
1377
        Bmemset(ptr, 0, blocksize);
1378
        return ptr;
1378
        return ptr;
1379
    }
1379
    }
1380
    return handle_memerr(ptr);
1380
    return handle_memerr(ptr);
1381
}
1381
}
1382
#else
1382
#else
1383
# define xaligned_alloc(alignment, size) xmalloc(size)
1383
# define xaligned_alloc(alignment, size) xmalloc(size)
1384
# define xaligned_calloc(alignment, count, size) xcalloc(count, size)
1384
# define xaligned_calloc(alignment, count, size) xcalloc(count, size)
1385
#endif
1385
#endif
1386
1386
1387
#ifdef DEBUGGINGAIDS
1387
#ifdef DEBUGGINGAIDS
1388
# define EDUKE32_PRE_XALLOC xalloc_set_location(__LINE__, __FILE__, EDUKE32_FUNCTION),
1388
# define EDUKE32_PRE_XALLOC xalloc_set_location(__LINE__, __FILE__, EDUKE32_FUNCTION),
1389
#else
1389
#else
1390
# define EDUKE32_PRE_XALLOC
1390
# define EDUKE32_PRE_XALLOC
1391
#endif
1391
#endif
1392
1392
1393
#define Xstrdup(s)    (EDUKE32_PRE_XALLOC xstrdup(s))
1393
#define Xstrdup(s)    (EDUKE32_PRE_XALLOC xstrdup(s))
1394
#define Xmalloc(size) (EDUKE32_PRE_XALLOC xmalloc(size))
1394
#define Xmalloc(size) (EDUKE32_PRE_XALLOC xmalloc(size))
1395
#define Xcalloc(nmemb, size) (EDUKE32_PRE_XALLOC xcalloc(nmemb, size))
1395
#define Xcalloc(nmemb, size) (EDUKE32_PRE_XALLOC xcalloc(nmemb, size))
1396
#define Xrealloc(ptr, size)  (EDUKE32_PRE_XALLOC xrealloc(ptr, size))
1396
#define Xrealloc(ptr, size)  (EDUKE32_PRE_XALLOC xrealloc(ptr, size))
1397
#define Xaligned_alloc(alignment, size) (EDUKE32_PRE_XALLOC xaligned_alloc(alignment, size))
1397
#define Xaligned_alloc(alignment, size) (EDUKE32_PRE_XALLOC xaligned_alloc(alignment, size))
1398
#define Xaligned_calloc(alignment, count, size) (EDUKE32_PRE_XALLOC xaligned_calloc(alignment, count, size))
1398
#define Xaligned_calloc(alignment, count, size) (EDUKE32_PRE_XALLOC xaligned_calloc(alignment, count, size))
1399
#define Xfree(ptr) (Bfree(ptr))
1399
#define Xfree(ptr) (Bfree(ptr))
1400
#define Xaligned_free(ptr) (Baligned_free(ptr))
1400
#define Xaligned_free(ptr) (Baligned_free(ptr))
1401
1401
1402
#ifdef __cplusplus
1402
#ifdef __cplusplus
1403
}
1403
}
1404
#endif
1404
#endif
1405
1405
1406
1406
1407
////////// More utility functions //////////
1407
////////// More utility functions //////////
1408
1408
1409
static inline void maybe_grow_buffer(char ** const buffer, int32_t * const buffersize, int32_t const newsize)
1409
static inline void maybe_grow_buffer(char ** const buffer, int32_t * const buffersize, int32_t const newsize)
1410
{
1410
{
1411
    if (newsize > *buffersize)
1411
    if (newsize > *buffersize)
1412
    {
1412
    {
1413
        *buffer = (char *)Xrealloc(*buffer, newsize);
1413
        *buffer = (char *)Xrealloc(*buffer, newsize);
1414
        *buffersize = newsize;
1414
        *buffersize = newsize;
1415
    }
1415
    }
1416
}
1416
}
1417
1417
1418
1418
1419
////////// Inlined external libraries //////////
1419
////////// Inlined external libraries //////////
1420
1420
1421
#ifndef LIBDIVIDE_BODY
1421
#ifndef LIBDIVIDE_BODY
1422
# define LIBDIVIDE_HEADER_ONLY
1422
# define LIBDIVIDE_HEADER_ONLY
1423
#endif
1423
#endif
1424
#define LIBDIVIDE_C_HEADERS
1424
#define LIBDIVIDE_C_HEADERS
1425
#define LIBDIVIDE_NONAMESPACE
1425
#define LIBDIVIDE_NONAMESPACE
1426
#define LIBDIVIDE_NOINLINE
1426
#define LIBDIVIDE_NOINLINE
1427
#include "fix16.h"
1427
#include "fix16.h"
1428
#include "libdivide.h"
1428
#include "libdivide.h"
1429
#include "clockticks.hpp"
1429
#include "clockticks.hpp"
1430
#include "debugbreak.h"
1430
#include "debugbreak.h"
1431
1431
1432
#include "zpl.h"
1432
#include "zpl.h"
1433
1433
1434
/* End dependence on compat.o object. */
1434
/* End dependence on compat.o object. */
1435
1435
1436
1436
1437
////////// EDuke32-specific features //////////
1437
////////// EDuke32-specific features //////////
1438
1438
1439
#ifndef TRUE
1439
#ifndef TRUE
1440
# define TRUE 1
1440
# define TRUE 1
1441
#endif
1441
#endif
1442
1442
1443
#ifndef FALSE
1443
#ifndef FALSE
1444
# define FALSE 0
1444
# define FALSE 0
1445
#endif
1445
#endif
1446
1446
1447
#define WITHKPLIB
1447
#define WITHKPLIB
1448
1448
1449
#if defined __ANDROID__ || defined EDUKE32_IOS
1449
#if defined __ANDROID__ || defined EDUKE32_IOS
1450
# define EDUKE32_TOUCH_DEVICES
1450
# define EDUKE32_TOUCH_DEVICES
1451
# define EDUKE32_GLES
1451
# define EDUKE32_GLES
1452
#endif
1452
#endif
1453
1453
1454
#if DEBUGGINGAIDS>=2
1454
#if DEBUGGINGAIDS>=2
1455
# define DEBUG_MAIN_ARRAYS
1455
# define DEBUG_MAIN_ARRAYS
1456
#endif
1456
#endif
1457
1457
1458
#if !defined DEBUG_MAIN_ARRAYS
1458
#if !defined DEBUG_MAIN_ARRAYS
1459
# define HAVE_CLIPSHAPE_FEATURE
1459
# define HAVE_CLIPSHAPE_FEATURE
1460
#endif
1460
#endif
1461
1461
1462
#endif // compat_h_
1462
#endif // compat_h_
1463
 
1463