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