diff options
author | Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> | 2023-12-27 00:32:01 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-27 01:32:01 +0100 |
commit | f5ab6fb5e8be7b73e6003d4145081d5e0c0ce287 (patch) | |
tree | 90f2c6a4885dbd181799e2325cf33588697674e1 /primedev/core/structs.h | |
parent | bb8ed59f6891b1196c5f5bbe7346cd171c8215fa (diff) | |
download | NorthstarLauncher-f5ab6fb5e8be7b73e6003d4145081d5e0c0ce287.tar.gz NorthstarLauncher-f5ab6fb5e8be7b73e6003d4145081d5e0c0ce287.zip |
Folder restructuring from primedev (#624)v1.21.2-rc3v1.21.2
Copies of over the primedev folder structure for easier cherry-picking of further changes
Co-authored-by: F1F7Y <filip.bartos07@proton.me>
Diffstat (limited to 'primedev/core/structs.h')
-rw-r--r-- | primedev/core/structs.h | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/primedev/core/structs.h b/primedev/core/structs.h new file mode 100644 index 00000000..037233a6 --- /dev/null +++ b/primedev/core/structs.h @@ -0,0 +1,77 @@ +#pragma once +//clang-format off +// About this file: +// This file contains several macros used to define reversed structs +// The reason we use these macros is to make it easier to update existing structs +// when new fields are reversed +// This means we dont have to manually add padding, and recalculate when updating + +// Technical note: +// While functionally, these structs act like a regular struct, they are actually +// defined as unions with anonymous structs in them. +// This means that each field is essentially an offset into a union. +// We acknowledge that this goes against C++'s active-member guideline for unions +// However, this is not such a big deal here as these structs will not be constructed + +// Usage: +// To use these macros, define a struct like so: +/* +OFFSET_STRUCT(Name) +{ + STRUCT_SIZE(0x100) // Total in-memory struct size + FIELD(0x0, int field) // offset, signature +} +*/ + +#define OFFSET_STRUCT(name) union name +#define STRUCT_SIZE(size) char __size[size]; +#define STRUCT_FIELD_OFFSET(offset, signature) \ + struct \ + { \ + char CONCAT2(pad, __LINE__)[offset]; \ + signature; \ + }; + +// Special case for a 0-offset field +#define STRUCT_FIELD_NOOFFSET(offset, signature) signature; + +// Just puts two tokens next to each other, but +// allows us to force the preprocessor to do another pass +#define FX(f, x) f x + +// Macro used to detect if the given offset is 0 or not +#define TEST_0 , +// MSVC does no preprocessing of integer literals. +// On other compilers `0x0` gets processed into `0` +#define TEST_0x0 , + +// Concats the first and third argument and drops everything else +// Used with preprocessor expansion in later passes to move the third argument to the fourth and change the value +#define ZERO_P_I(a, b, c, ...) a##c + +// We use FX to prepare to use ZERO_P_I. +// The right block contains 3 arguments: +// NIF_ +// CONCAT2(TEST_, offset) +// 1 +// +// If offset is not 0 (or 0x0) the preprocessor replaces +// it with nothing and the third argument stays 1 +// +// If the offset is 0, TEST_0 expands to , and 1 becomes the fourth argument +// +// With those arguments we call ZERO_P_I and the first and third arugment get concat. +// We either end up with: +// NIF_ (if offset is 0) or +// NIF_1 (if offset is not 0) +#define IF_ZERO(m) FX(ZERO_P_I, (NIF_, CONCAT2(TEST_, m), 1)) + +// These macros are used to branch after we processed if the offset is zero or not +#define NIF_(t, ...) t +#define NIF_1(t, ...) __VA_ARGS__ + +// FIELD(S), generates an anonymous struct when a non 0 offset is given, otherwise just a signature +#define FIELD(offset, signature) IF_ZERO(offset)(STRUCT_FIELD_NOOFFSET, STRUCT_FIELD_OFFSET)(offset, signature) +#define FIELDS FIELD + +//clang-format on |