forked from UsernameFodder/pmdsky-debug
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpmdsky.h
131 lines (114 loc) · 5.54 KB
/
pmdsky.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
#ifndef HEADERS_PMDSKY_H_
#define HEADERS_PMDSKY_H_
#ifndef PMDSKY_UNSIZED_HEADERS
// ======== BEGIN NORMAL PREAMBLE ========
// This is the normal include preamble.
// It defines all the constructs needed for the headers to be self-contained.
// Try to define the ASSERT_SIZE macro
#ifdef __has_feature
#if __has_feature(c_static_assert)
// clang
#define ASSERT_SIZE(type, size) \
_Static_assert(sizeof(type) == size, "type '" #type "' must have size " #size)
#endif // __has_feature(c_static_assert)
#elif __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 5))
// gcc (_Static_assert support since gcc 4.6: https://gcc.gnu.org/wiki/C11Status)
#define ASSERT_SIZE(type, size) \
_Static_assert(sizeof(type) == size, "type '" #type "' must have size " #size)
#else
// _Static_assert is unsupported, so just skip assertions
#define ASSERT_SIZE(type, size)
#endif // ifdef __has_feature
// Make sure primitive types are sized as we expect
ASSERT_SIZE(char, 1);
ASSERT_SIZE(short, 2);
ASSERT_SIZE(int, 4);
// The following ensures we're compiling for a 32-bit architecture
ASSERT_SIZE(long, 4);
ASSERT_SIZE(void*, 4);
ASSERT_SIZE(long long, 8);
// Define fixed size types without including <stdint.h> (or similar) for compatibility
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
// Define the bool type to be 1 byte
typedef uint8_t bool;
// Define the wchar_t type to be 2 bytes. Use the built-in short type here because Ghidra's
// default parser configuration complains if we use int16_t
typedef short wchar_t;
// Based on the code for vsprintf(3), it seems like va_list is implemented in the ARM9 binary
// by just passing a pointer into the stack, so define va_list to be void*, rather than using
// whatever stdarg.h defines
typedef void* va_list;
// Ghidra-style "undefined*" types should be used to signify that a type is unknown
typedef uint8_t undefined1;
typedef uint16_t undefined2;
typedef uint32_t undefined4;
typedef undefined1 undefined;
#ifdef IMPLICIT_STRUCT_PACKING
// In implicit packing mode, all structs are packed by default.
// If padding is desired, it must be defined explicitly.
#pragma pack(1)
#endif
// A wrapper struct for an enum stored as an 8-bit integer.
// For some `enum foo_id`, ENUM_8_BIT(foo_id) will define `struct foo_id_8`.
// This should only be used within `#pragma pack(push, 1)`.
#define ENUM_8_BIT(tag) \
struct tag##_8 { \
enum tag val : 8; \
}; \
ASSERT_SIZE(struct tag##_8, 1)
// A wrapper struct for an enum stored as a 16-bit integer.
// For some `enum foo_id`, ENUM_16_BIT(foo_id) will define `struct foo_id_16`.
// This should only be used within `#pragma pack(push, 2)`.
#define ENUM_16_BIT(tag) \
struct tag##_16 { \
enum tag val : 16; \
}; \
ASSERT_SIZE(struct tag##_16, 2)
// ======== END NORMAL PREAMBLE ========
#else // #ifndef PMDSKY_UNSIZED_HEADERS
// ======== BEGIN UNSIZED PREAMBLE ========
// This is the unsized preamble.
// It's only meant for use by external applications that want to use the types defined by the
// pmdsky-debug headers, without caring about the specifics of struct sizing and memory layouts.
// The intent is to allow applications to do something like:
// ```
// #define PMDSKY_UNSIZED_HEADERS
// #include "pmdsky-debug/headers/pmdsky.h"
// #undef PMDSKY_UNSIZED_HEADERS
// ```
//
// If you don't know exactly what you're doing, you can probably safely ignore this part.
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <wchar.h>
// Stub this out since we don't care about sizes
#define ASSERT_SIZE(type, size)
// Ghidra-style "undefined*" types still need to be defined
typedef uint8_t undefined1;
typedef uint16_t undefined2;
typedef uint32_t undefined4;
typedef undefined1 undefined;
// The ENUM_*_BIT macros still need to be defined, but they don't need to be bitfields
#define ENUM_8_BIT(tag) \
struct tag##_8 { \
enum tag val; \
};
#define ENUM_16_BIT(tag) \
struct tag##_16 { \
enum tag val; \
};
// ======== END UNSIZED PREAMBLE ========
#endif // #ifndef PMDSKY_UNSIZED_HEADERS
// Now include the actual type definitions, function signatures, and global declarations
#include "types/types.h"
#include "functions/functions.h"
#include "data/data.h"
#endif