Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions include/pokemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,17 +335,33 @@ u8 GetGenderFromSpeciesAndPersonality(u16 species, u32 personality);
void SetMultiuseSpriteTemplateToPokemon(u16 speciesTag, u8 battlerPosition);
void SetMultiuseSpriteTemplateToTrainerBack(u16 trainerSpriteId, u8 battlerPosition);

/* GameFreak called Get(Box)MonData with either 2 or 3 arguments, for
* type safety we have a Get(Box)MonData macro which dispatches to
* either Get(Box)MonData2 or Get(Box)MonData3 based on the number of
* arguments. The two functions are aliases of each other, but they
* differ for matching purposes in the caller's codegen. */
#define GetMonData(...) CAT(GetMonData, NARG_8(__VA_ARGS__))(__VA_ARGS__)
#define GetBoxMonData(...) CAT(GetBoxMonData, NARG_8(__VA_ARGS__))(__VA_ARGS__)
u32 GetMonData3(struct Pokemon *mon, s32 field, u8 *data);
#ifndef UBFIX
#define DISPATCH_MATCH(FUNC, ...) CAT(FUNC, NARG_8(__VA_ARGS__))(__VA_ARGS__)

#define GetMonData(...) DISPATCH_MATCH(GetMonData, __VA_ARGS__)
#define GetBoxMonData(...) DISPATCH_MATCH(GetBoxMonData, __VA_ARGS__)

// agbcc still needs to know about the 2-argument aliases
u32 GetMonData2(struct Pokemon *mon, s32 field);
u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data);
u32 GetBoxMonData2(struct BoxPokemon *boxMon, s32 field);
#else
#define CHOOSE_MACRO(_1, _2, _3, NAME, ...) NAME
#define CALL_3(FUNC, arg1, arg2, arg3) (FUNC)(arg1, arg2, arg3)
#define CALL_2(FUNC, arg1, arg2) (FUNC)(arg1, arg2, NULL)

#define DISPATCH_UBFIX(FUNC, ...) CHOOSE_MACRO(__VA_ARGS__, CALL_3, CALL_2)(FUNC, __VA_ARGS__)

// Handle clean macros
#define GetMonData(...) DISPATCH_UBFIX(GetMonData, __VA_ARGS__)
#define GetBoxMonData(...) DISPATCH_UBFIX(GetBoxMonData, __VA_ARGS__)

// Intercept calls
#define GetMonData2(mon, field) (GetMonData)(mon, field, NULL)
#define GetBoxMonData2(boxMon, field) (GetBoxMonData)(boxMon, field, NULL)
#endif

u32 GetMonData(struct Pokemon *mon, s32 field, u8 *data);
u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data);

void SetMonData(struct Pokemon *mon, s32 field, const void *dataArg);
void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg);
Expand Down
16 changes: 13 additions & 3 deletions src/pokemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
#include "constants/battle_move_effects.h"
#include "constants/union_room.h"

#ifndef UBFIX
u32 GetMonData2(struct Pokemon *mon, s32 field) __attribute__((alias("GetMonData3")));
u32 GetBoxMonData2(struct BoxPokemon *boxMon, s32 field) __attribute__((alias("GetBoxMonData3")));
#endif

#define SPECIES_TO_HOENN(name) [SPECIES_##name - 1] = HOENN_DEX_##name
#define SPECIES_TO_NATIONAL(name) [SPECIES_##name - 1] = NATIONAL_DEX_##name
#define HOENN_TO_NATIONAL(name) [HOENN_DEX_##name - 1] = NATIONAL_DEX_##name
Expand Down Expand Up @@ -2899,7 +2904,11 @@ static union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 perso
* safety we have a GetMonData macro (in include/pokemon.h) which
* dispatches to either GetMonData2 or GetMonData3 based on the number
* of arguments. */
#ifndef UBFIX
u32 GetMonData3(struct Pokemon *mon, s32 field, u8 *data)
#else
u32 GetMonData(struct Pokemon *mon, s32 field, u8 *data)
#endif
{
u32 ret;

Expand Down Expand Up @@ -2967,13 +2976,16 @@ u32 GetMonData3(struct Pokemon *mon, s32 field, u8 *data)
return ret;
}

u32 GetMonData2(struct Pokemon *mon, s32 field) __attribute__((alias("GetMonData3")));

/* GameFreak called GetBoxMonData with either 2 or 3 arguments, for type
* safety we have a GetBoxMonData macro (in include/pokemon.h) which
* dispatches to either GetBoxMonData2 or GetBoxMonData3 based on the
* number of arguments. */
#ifndef UBFIX
u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data)
#else
u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data)
#endif
Comment on lines +2984 to +2988

@mrgriffin mrgriffin Jun 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly, these lines of code are different in pret/pokeemerald#2315 (at time of writing: in case of a force push see pret/pokeemerald@6f9c1a4).

(Admittedly, different in a way that I think is worse that what's here.)

{
s32 i;
u32 retVal = 0;
Expand Down Expand Up @@ -3329,8 +3341,6 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data)
return retVal;
}

u32 GetBoxMonData2(struct BoxPokemon *boxMon, s32 field) __attribute__((alias("GetBoxMonData3")));

#define SET8(lhs) (lhs) = *data
#define SET16(lhs) (lhs) = data[0] + (data[1] << 8)
#define SET32(lhs) (lhs) = data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24)
Expand Down