1 /*************************************************************************/
2 /* typedefs.h */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
10 /* */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the */
13 /* "Software"), to deal in the Software without restriction, including */
14 /* without limitation the rights to use, copy, modify, merge, publish, */
15 /* distribute, sublicense, and/or sell copies of the Software, and to */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions: */
18 /* */
19 /* The above copyright notice and this permission notice shall be */
20 /* included in all copies or substantial portions of the Software. */
21 /* */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 /*************************************************************************/
30 #ifndef TYPEDEFS_H
31 #define TYPEDEFS_H
32
33 #include <stddef.h>
34 /**
35 * Basic definitions and simple functions to be used everywhere..
36 */
37
38 #include "platform_config.h"
39
40 #ifndef _STR
41 #define _STR(m_x) #m_x
42 #define _MKSTR(m_x) _STR(m_x)
43 #endif
44
45 #ifndef _ALWAYS_INLINE_
46
47 #if defined(__GNUC__) && (__GNUC__ >= 4)
48 #define _ALWAYS_INLINE_ __attribute__((always_inline)) inline
49 #elif defined(__llvm__)
50 #define _ALWAYS_INLINE_ __attribute__((always_inline)) inline
51 #elif defined(_MSC_VER)
52 #define _ALWAYS_INLINE_ __forceinline
53 #else
54 #define _ALWAYS_INLINE_ inline
55 #endif
56
57 #endif
58
59 #ifndef _FORCE_INLINE_
60 #ifdef DEBUG_ENABLED
61 #define _FORCE_INLINE_ inline
62 #else
63 #define _FORCE_INLINE_ _ALWAYS_INLINE_
64 #endif
65 #endif
66
67 #ifndef DEFAULT_ALIGNMENT
68 #define DEFAULT_ALIGNMENT 1
69 #endif
70
71 //custom, gcc-safe offsetof, because gcc complains a lot.
72 template <class T>
_nullptr()73 T *_nullptr() {
74 T *t = NULL;
75 return t;
76 }
77
78 #define OFFSET_OF(st, m) \
79 ((size_t)((char *)&(_nullptr<st>()->m) - (char *)0))
80 /**
81 * Some platforms (devices) not define NULL
82 */
83
84 #ifndef NULL
85 #define NULL 0
86 #endif
87
88 /**
89 * Windows defines a lot of badly stuff we'll never ever use. undefine it.
90 */
91
92 #ifdef _WIN32
93 #undef min // override standard definition
94 #undef max // override standard definition
95 #undef ERROR // override (really stupid) wingdi.h standard definition
96 #undef DELETE // override (another really stupid) winnt.h standard definition
97 #undef MessageBox // override winuser.h standard definition
98 #undef MIN // override standard definition
99 #undef MAX // override standard definition
100 #undef CLAMP // override standard definition
101 #undef Error
102 #undef OK
103 #endif
104
105 #include "error_list.h"
106 #include "error_macros.h"
107
108 #include "int_types.h"
109
110 /** Generic ABS function, for math uses please use Math::abs */
111
112 #ifndef ABS
113 #define ABS(m_v) ((m_v < 0) ? (-(m_v)) : (m_v))
114 #endif
115
116 #ifndef SGN
117 #define SGN(m_v) ((m_v < 0) ? (-1.0) : (+1.0))
118 #endif
119
120 #ifndef MIN
121 #define MIN(m_a, m_b) (((m_a) < (m_b)) ? (m_a) : (m_b))
122 #endif
123
124 #ifndef MAX
125 #define MAX(m_a, m_b) (((m_a) > (m_b)) ? (m_a) : (m_b))
126 #endif
127
128 #ifndef CLAMP
129 #define CLAMP(m_a, m_min, m_max) (((m_a) < (m_min)) ? (m_min) : (((m_a) > (m_max)) ? m_max : m_a))
130 #endif
131
132 /** Generic swap template */
133 #ifndef SWAP
134
135 #define SWAP(m_x, m_y) __swap_tmpl(m_x, m_y)
136 template <class T>
__swap_tmpl(T & x,T & y)137 inline void __swap_tmpl(T &x, T &y) {
138
139 T aux = x;
140 x = y;
141 y = aux;
142 }
143
144 #endif //swap
145
146 /* clang-format off */
147 #define HEX2CHR(m_hex) \
148 ((m_hex >= '0' && m_hex <= '9') ? (m_hex - '0') : \
149 ((m_hex >= 'A' && m_hex <= 'F') ? (10 + m_hex - 'A') : \
150 ((m_hex >= 'a' && m_hex <= 'f') ? (10 + m_hex - 'a') : 0)))
151 /* clang-format on */
152
153 // Macro to check whether we are compiled by clang
154 // and we have a specific builtin
155 #if defined(__llvm__) && defined(__has_builtin)
156 #define _llvm_has_builtin(x) __has_builtin(x)
157 #else
158 #define _llvm_has_builtin(x) 0
159 #endif
160
161 #if (defined(__GNUC__) && (__GNUC__ >= 5)) || _llvm_has_builtin(__builtin_mul_overflow)
162 #define _mul_overflow __builtin_mul_overflow
163 #endif
164
165 #if (defined(__GNUC__) && (__GNUC__ >= 5)) || _llvm_has_builtin(__builtin_add_overflow)
166 #define _add_overflow __builtin_add_overflow
167 #endif
168
169 /** Function to find the next power of 2 to an integer */
170
next_power_of_2(unsigned int x)171 static _FORCE_INLINE_ unsigned int next_power_of_2(unsigned int x) {
172
173 --x;
174 x |= x >> 1;
175 x |= x >> 2;
176 x |= x >> 4;
177 x |= x >> 8;
178 x |= x >> 16;
179
180 return ++x;
181 }
182
previous_power_of_2(unsigned int x)183 static _FORCE_INLINE_ unsigned int previous_power_of_2(unsigned int x) {
184
185 x |= x >> 1;
186 x |= x >> 2;
187 x |= x >> 4;
188 x |= x >> 8;
189 x |= x >> 16;
190 return x - (x >> 1);
191 }
192
closest_power_of_2(unsigned int x)193 static _FORCE_INLINE_ unsigned int closest_power_of_2(unsigned int x) {
194
195 unsigned int nx = next_power_of_2(x);
196 unsigned int px = previous_power_of_2(x);
197 return (nx - x) > (x - px) ? px : nx;
198 }
199
200 // We need this definition inside the function below.
201 static inline int get_shift_from_power_of_2(unsigned int p_pixel);
202
203 template <class T>
nearest_power_of_2_templated(T x)204 static _FORCE_INLINE_ T nearest_power_of_2_templated(T x) {
205
206 --x;
207
208 // The number of operations on x is the base two logarithm
209 // of the p_number of bits in the type. Add three to account
210 // for sizeof(T) being in bytes.
211 size_t num = get_shift_from_power_of_2(sizeof(T)) + 3;
212
213 // If the compiler is smart, it unrolls this loop
214 // If its dumb, this is a bit slow.
215 for (size_t i = 0; i < num; i++)
216 x |= x >> (1 << i);
217
218 return ++x;
219 }
220
221 /** Function to find the nearest (bigger) power of 2 to an integer */
222
nearest_shift(unsigned int p_number)223 static inline unsigned int nearest_shift(unsigned int p_number) {
224
225 for (int i = 30; i >= 0; i--) {
226
227 if (p_number & (1 << i))
228 return i + 1;
229 }
230
231 return 0;
232 }
233
234 /** get a shift value from a power of 2 */
get_shift_from_power_of_2(unsigned int p_pixel)235 static inline int get_shift_from_power_of_2(unsigned int p_pixel) {
236 // return a GL_TEXTURE_SIZE_ENUM
237
238 for (unsigned int i = 0; i < 32; i++) {
239
240 if (p_pixel == (unsigned int)(1 << i))
241 return i;
242 }
243
244 return -1;
245 }
246
247 /** Swap 16 bits value for endianness */
BSWAP16(uint16_t x)248 static inline uint16_t BSWAP16(uint16_t x) {
249 return (x >> 8) | (x << 8);
250 }
251 /** Swap 32 bits value for endianness */
BSWAP32(uint32_t x)252 static inline uint32_t BSWAP32(uint32_t x) {
253 return ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24));
254 }
255 /** Swap 64 bits value for endianness */
256
BSWAP64(uint64_t x)257 static inline uint64_t BSWAP64(uint64_t x) {
258 x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
259 x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
260 x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8;
261 return x;
262 }
263
264 /** When compiling with RTTI, we can add an "extra"
265 * layer of safeness in many operations, so dynamic_cast
266 * is used besides casting by enum.
267 */
268
269 template <class T>
270 struct Comparator {
271
operatorComparator272 inline bool operator()(const T &p_a, const T &p_b) const { return (p_a < p_b); }
273 };
274
275 void _global_lock();
276 void _global_unlock();
277
278 struct _GlobalLock {
279
_GlobalLock_GlobalLock280 _GlobalLock() { _global_lock(); }
~_GlobalLock_GlobalLock281 ~_GlobalLock() { _global_unlock(); }
282 };
283
284 #define GLOBAL_LOCK_FUNCTION _GlobalLock _global_lock_;
285
286 #ifdef NO_SAFE_CAST
287 #define SAFE_CAST static_cast
288 #else
289 #define SAFE_CAST dynamic_cast
290 #endif
291
292 #define MT_SAFE
293
294 #define __STRX(m_index) #m_index
295 #define __STR(m_index) __STRX(m_index)
296
297 #endif /* typedefs.h */
298