-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathglobal.h
337 lines (274 loc) · 18 KB
/
global.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
#ifndef GUARD_GLOBAL_H
#define GUARD_GLOBAL_H
#include "config.h"
#include "gba/gba.h"
#if PLATFORM_GBA
#define ENABLE_AUDIO TRUE
#else
#define ENABLE_AUDIO TRUE
#define ENABLE_VRAM_VIEW !TRUE
#endif
#define CONST_DATA __attribute__((section(".data")))
// #include "types.h"
// #include "variables.h"
#if !PLATFORM_GBA
#ifdef _WIN32
void *Platform_malloc(int numBytes);
void Platform_free(void *ptr);
#define malloc(numBytes) Platform_malloc(numBytes)
#define calloc(count, size) Platform_malloc(count *size)
#define free(numBytes) Platform_free(numBytes)
#endif
#endif
#define SIO_MULTI_CNT ((volatile struct SioMultiCnt *)REG_ADDR_SIOCNT)
typedef void (*VoidFn)(void);
// helper macros
#if (PORTABLE)
#define BUG_FIX
#if !(defined NON_MATCHING)
#define NON_MATCHING 1
#endif
#elif (DEBUG)
#define NON_MATCHING 1
#endif
#ifdef NON_MATCHING
#define ASM_FUNC(path, decl)
#define TEMP_FIX 1
#else
#define ASM_FUNC(path, decl) \
NAKED decl { asm(".include " #path); }
#define TEMP_FIX 0
#endif
#ifdef NON_MATCHING
#define NONMATCH(path, decl) decl
#define END_NONMATCH
#else
#define NONMATCH(path, decl) \
NAKED decl \
{ \
asm(".include " #path); \
if (0)
#define END_NONMATCH }
#endif
/// IDE support
#if defined(__CYGWIN__) || defined(__INTELLISENSE__)
// We define these when using certain IDEs to fool preproc
#define _(x) (x)
#define __(x) (x)
#define INCBIN(...) \
{ \
0 \
}
#define INCBIN_U8 INCBIN
#define INCBIN_U16 INCBIN
#define INCBIN_U32 INCBIN
#define INCBIN_S8 INCBIN
#define INCBIN_S16 INCBIN
#define INCBIN_S32 INCBIN
#endif // IDE support
// Use STR(<macro>) to turn the macro's *content* into a string
#define STR_(x) #x
#define STR(x) STR_(x)
// NOTE: This has to be kept as-is.
// If casted it to be signed,
// dataIndex = (dataIndex + 1) % ARRAY_COUNT(data)
// wouldn't match.
#define ARRAY_COUNT(array) (sizeof(array) / sizeof((array)[0]))
// Converts a number to Q8.8 fixed-point format
#define Q_8_8(n) ((s16)((n)*256))
// Converts a number to Q16.16 fixed-point format (<< 0x10)
#define Q_16_16(n) ((s32)((n)*0x10000))
// Converts a number to Q4.12 fixed-point format
#define Q_4_12(n) ((s16)((n)*4096))
// Converts a number to Q2.14 fixed-point format
#define Q_2_14(n) ((s16)((n)*0x4000))
// Converts a number to Q20.12 fixed-point format
#define Q_20_12(n) ((s32)((n)*4096))
// Converts a number to Q24.8 fixed-point format
#define Q_24_8(n) ((s32)((n)*256))
#define Q_24_8_FRAC(n) ((u8)(n))
// This may be the "real" version as we are seeing better matches with
// it in some cases
#define Q_24_8_NEW(n) ((s32)((n) << 8))
// Converts a Q8.8 fixed-point format number to a regular integer
#define Q_8_8_TO_INT(n) ((int)((n) >> 8))
// Converts a Q4.12 fixed-point format number to a regular integer
#define Q_4_12_TO_INT(n) ((int)((n) >> 12))
// Converts a Q2.12 fixed-point format number to a regular integer
#define Q_2_14_TO_INT(n) ((int)((n) >> 14))
// Converts a Q24.8 fixed-point format number to a regular integer
#define Q_24_8_TO_INT(n) ((int)((n) >> 8))
// Converts a Q20.12 fixed-point format number to a regular integer
#define Q_20_12_TO_INT(n) ((int)((n) >> 12))
// Converts a Q16.16 fixed-point format number to a regular integer
#define Q_16_16_TO_INT(n) ((int)((n) >> 0x10))
// Converts a Q2.12 fixed-point format number to a Q24.8 fixed point number
#define Q_2_14_TO_Q_24_8(n) ((int)((n) >> 6))
// Multiplies two Q values
#define Q_MUL(qValA, qValB) ((qValA * qValB) >> 8)
#define Q_SQUARE(qVal) Q_MUL(qVal, qVal)
#define Q_DIV(qValA, qValB) Div((qValA << 8), qValB)
#define Q_DIV2(qValA, qValB) ((qValA << 8) / qValB)
#define Q_MUL_Q_F32(qVal, floatVal) Q_MUL(qVal, Q(floatVal))
/*
* Aliases for common macros
*/
// Converts a number to Q24.8 fixed-point format
#define Q(n) Q_24_8(n)
// Converts a number to Q24.8 fixed-point format
#define QS(n) Q_24_8_NEW(n)
// Converts a Q24.8 fixed-point format number to a regular integer
#define I(n) Q_24_8_TO_INT(n)
#define RED_VALUE(color) (((color) >> 0) & 0x1F)
#define GREEN_VALUE(color) (((color) >> 5) & 0x1F)
#define BLUE_VALUE(color) (((color) >> 10) & 0x1F)
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define CLAMP(value, min, max) \
({ \
s32 clamped; \
if ((value) < (min)) { \
clamped = (min); \
} else { \
clamped = (value) > (max) ? (max) : (value); \
} \
clamped; \
})
#define CLAMP_T(type, value, min, max) \
({ \
type clamped; \
if ((value) >= (min)) { \
clamped = (value) > (max) ? (max) : (value); \
} else { \
clamped = (min); \
} \
clamped; \
})
#define CLAMP_16(value, min, max) CLAMP_T(s16, value, min, max)
#define CLAMP_32(value, min, max) CLAMP_T(s32, value, min, max)
#define CLAMP_INLINE(var, min, max) \
({ \
if ((var) < (min)) { \
var = (min); \
} else if ((var) > (max)) { \
var = (max); \
} \
})
#define CLAMP_INLINE_NO_ELSE(var, min, max) \
({ \
if ((var) < (min)) { \
var = (min); \
} \
\
if ((var) > (max)) { \
var = (max); \
} \
})
#define CLAMP_INLINE2(var, min, max) \
({ \
if ((var) > (max)) { \
var = (max); \
} else if ((var) < (min)) { \
var = (min); \
} \
})
#define ABS(aValue) ((aValue) >= 0 ? (aValue) : -(aValue))
#define RECT_DISTANCE(aXA, aYA, aXB, aYB) (ABS((aXA) - (aXB)) + ABS((aYA) - (aYB)))
#define BitValue(y) (1 << (y))
#define CheckBit(x, y) ((x) & (BitValue(y)))
#define GetBit(x, y) (((x) >> (y)) & 1)
#define SetBit(x, y) (x) |= BitValue(y)
#define SetSoleBit(x, y) (x) = BitValue(y)
#define ClearBit(x, y) (x) &= ~BitValue(y)
// TODO: Use instrinsics for these, on platforms that support it!
// Like GetFirstSetBitIndex, but an external iterator can be passed.
#define GetFirstSetBitIndexExt(value, max, it) \
({ \
s32 res; \
\
for (it = 0; it < (max); it++) { \
if (GetBit(value, it)) { \
break; \
} \
} \
\
res = it; \
})
// Get the index to the first set bit in a given value.
#define GetFirstSetBitIndex(value, max) \
({ \
s16 bit; \
\
bit = GetFirstSetBitIndexExt(value, max, bit); \
})
// Like GetFirstSetBitIndex, but expects input value to only have 1 bit set.
#define GetSoleSetBitIndex(value, max) \
({ \
s16 bit; \
\
for (bit = 0; bit < (max); bit++) { \
if ((value) == (1 << bit)) { \
break; \
} \
} \
\
bit; \
})
// 60 is not exactly true as the GBA's FPS, but it's what they went
// with for the calculation
#define GBA_FRAMES_PER_SECOND 60
// TODO: fix casts here(?)
#define XOR_SWAP(a, b) \
a ^= (u8)b; \
b ^= (u8)a; \
a = ((u8)b ^ (u8)a);
// TODO: fix casts here
#define SWAP_AND_NEGATE(a, b) \
a ^= (u8)b; \
b ^= (u8)a; \
a = ((u8)b ^ (u8)a) * -1; \
b = (u8)b * -1;
#define NEGATE(var) \
({ \
s32 temp = var; \
var = -temp; \
})
#define DIRECT_NEGATE(var) (var = -var;)
#define HALVE(var) (var = (var >> 1))
typedef struct {
s16 x;
s16 y;
} Vec2_16;
typedef struct {
s32 x;
s32 y;
} Vec2_32;
typedef struct {
u8 reserved : 4;
u8 compressedType : 4;
u32 size : 24;
void *data;
} RLCompressed;
struct BlendRegs {
u16 bldCnt;
u16 bldAlpha;
u16 bldY;
};
// TODO: Should this be in a GBA-specific header file?
#define NUM_AFFINE_BACKGROUNDS 2
#define NUM_BACKGROUNDS 4
// Values to be passed top the affine registers
// (used by BG2/BG3 in affine screen modes)
typedef struct {
/* 0x00 */ u16 pa, pb, pc, pd;
/* 0x08 */ u32 x, y;
} BgAffineReg;
// TODO: Find better place for this
typedef void (*HBlankFunc)(int_vcount vcount);
typedef void (*IntrFunc)(void);
typedef void (*FuncType_030053A0)(void);
typedef bool32 (*VBlankFunc)(void);
extern void *iwram_end;
extern void *ewram_end;
extern void *rom_footer;
#endif // GUARD_GLOBAL_H