From 9e22826830d6fa16d00b60cd602f03370f25edb3 Mon Sep 17 00:00:00 2001 From: Jesper Arvidsson Date: Sun, 24 May 2026 17:40:02 +0200 Subject: [PATCH 1/2] Add Adult Mask DL and system to load --- .../objects/object_link_boy/object_link_boy.h | 25 +++++++++++ .../Graphics/AgeDependentMasks.cpp | 41 +++++++++++++++++++ .../vanilla-behavior/GIVanillaBehavior.h | 9 ++++ .../actors/ovl_player_actor/z_player.c | 6 ++- 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp diff --git a/soh/assets/objects/object_link_boy/object_link_boy.h b/soh/assets/objects/object_link_boy/object_link_boy.h index a36662a804c..f1ed9c7a044 100644 --- a/soh/assets/objects/object_link_boy/object_link_boy.h +++ b/soh/assets/objects/object_link_boy/object_link_boy.h @@ -510,5 +510,30 @@ static const ALIGN_ASSET(2) char gLinkAdultVtx_0340A0[] = dgLinkAdultVtx_0340A0; #define dgLinkAdultVtx_02E7E0 "__OTR__objects/object_link_boy/gLinkAdultVtx_02E7E0" static const ALIGN_ASSET(2) char gLinkAdultVtx_02E7E0[] = dgLinkAdultVtx_02E7E0; +// Adult-fitted mask display lists (for use when adult Link wears child masks via the AdultMasks enhancement) +#define dgLinkAdultKeatonMaskDL "__OTR__objects/object_link_boy/gLinkAdultKeatonMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultKeatonMaskDL[] = dgLinkAdultKeatonMaskDL; + +#define dgLinkAdultSkullMaskDL "__OTR__objects/object_link_boy/gLinkAdultSkullMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultSkullMaskDL[] = dgLinkAdultSkullMaskDL; + +#define dgLinkAdultSpookyMaskDL "__OTR__objects/object_link_boy/gLinkAdultSpookyMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultSpookyMaskDL[] = dgLinkAdultSpookyMaskDL; + +#define dgLinkAdultBunnyHoodDL "__OTR__objects/object_link_boy/gLinkAdultBunnyHoodDL" +static const ALIGN_ASSET(2) char gLinkAdultBunnyHoodDL[] = dgLinkAdultBunnyHoodDL; + +#define dgLinkAdultGoronMaskDL "__OTR__objects/object_link_boy/gLinkAdultGoronMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultGoronMaskDL[] = dgLinkAdultGoronMaskDL; + +#define dgLinkAdultZoraMaskDL "__OTR__objects/object_link_boy/gLinkAdultZoraMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultZoraMaskDL[] = dgLinkAdultZoraMaskDL; + +#define dgLinkAdultGerudoMaskDL "__OTR__objects/object_link_boy/gLinkAdultGerudoMaskDL" +static const ALIGN_ASSET(2) char gLinkAdultGerudoMaskDL[] = dgLinkAdultGerudoMaskDL; + +#define dgLinkAdultMaskOfTruthDL "__OTR__objects/object_link_boy/gLinkAdultMaskOfTruthDL" +static const ALIGN_ASSET(2) char gLinkAdultMaskOfTruthDL[] = dgLinkAdultMaskOfTruthDL; + #endif // OBJECTS_OBJECT_LINK_BOY_H diff --git a/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp b/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp new file mode 100644 index 00000000000..7f14470855c --- /dev/null +++ b/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp @@ -0,0 +1,41 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/ShipInit.hpp" +#include "soh/ResourceManagerHelpers.h" + +extern "C" { +#include "macros.h" +#include "functions.h" +#include "objects/object_link_boy/object_link_boy.h" +extern SaveContext gSaveContext; +} + +static const char* sAdultMaskDLists[] = { + gLinkAdultKeatonMaskDL, + gLinkAdultSkullMaskDL, + gLinkAdultSpookyMaskDL, + gLinkAdultBunnyHoodDL, + gLinkAdultGoronMaskDL, + gLinkAdultZoraMaskDL, + gLinkAdultGerudoMaskDL, + gLinkAdultMaskOfTruthDL, +}; + +static void RegisterAgeDependentMasks() { + COND_VB_SHOULD(VB_DRAW_PLAYER_MASK, true, { + if (!LINK_IS_ADULT) return; + + PlayerMask currentMask = (PlayerMask)va_arg(args, int); + PlayState* play = va_arg(args, PlayState*); + + int maskIndex = currentMask - 1; + if (maskIndex < 0 || maskIndex >= 8) return; + + const char* adultDL = sAdultMaskDLists[maskIndex]; + if (!ResourceGetIsCustomByName(adultDL) && !ResourceMgr_FileExists(adultDL)) return; + + *should = false; + gSPDisplayList(play->state.gfxCtx->polyOpa.p++, (Gfx*)adultDL); + }); +} + +static RegisterShipInitFunc initFunc(RegisterAgeDependentMasks); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index d1ed4534100..e81793619c3 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -579,6 +579,15 @@ typedef enum { // - None VB_DRAW_ADDITIONAL_RETICLES, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `PlayerMask currentMask` + // - `*PlayState play` + VB_DRAW_PLAYER_MASK, + // #### `result` // In `Interface_DrawAmmoCount`: // ```c diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 7ffe8af7f43..c6b092ea646 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -12449,8 +12449,10 @@ void Player_DrawGameplay(PlayState* play, Player* this, s32 lod, Gfx* cullDList, MATRIX_TOMTX(bunnyEarMtx); } - if (this->currentMask != PLAYER_MASK_BUNNY || !CVarGetInteger(CVAR_ENHANCEMENT("HideBunnyHood"), 0)) { - gSPDisplayList(POLY_OPA_DISP++, sMaskDlists[this->currentMask - 1]); + if (GameInteractor_Should(VB_DRAW_PLAYER_MASK, true, this->currentMask, play)) { + if (this->currentMask != PLAYER_MASK_BUNNY || !CVarGetInteger(CVAR_ENHANCEMENT("HideBunnyHood"), 0)) { + gSPDisplayList(POLY_OPA_DISP++, sMaskDlists[this->currentMask - 1]); + } } if (CVarGetInteger(CVAR_GENERAL("FixIceTrapWithBunnyHood"), 1)) From 853dc15a25df24c0e78fbf6933b1df060467322f Mon Sep 17 00:00:00 2001 From: Jesper Arvidsson Date: Sun, 24 May 2026 17:47:37 +0200 Subject: [PATCH 2/2] clang --- .../Graphics/AgeDependentMasks.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp b/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp index 7f14470855c..104b5afbfd6 100644 --- a/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp +++ b/soh/soh/Enhancements/Graphics/AgeDependentMasks.cpp @@ -10,28 +10,25 @@ extern SaveContext gSaveContext; } static const char* sAdultMaskDLists[] = { - gLinkAdultKeatonMaskDL, - gLinkAdultSkullMaskDL, - gLinkAdultSpookyMaskDL, - gLinkAdultBunnyHoodDL, - gLinkAdultGoronMaskDL, - gLinkAdultZoraMaskDL, - gLinkAdultGerudoMaskDL, - gLinkAdultMaskOfTruthDL, + gLinkAdultKeatonMaskDL, gLinkAdultSkullMaskDL, gLinkAdultSpookyMaskDL, gLinkAdultBunnyHoodDL, + gLinkAdultGoronMaskDL, gLinkAdultZoraMaskDL, gLinkAdultGerudoMaskDL, gLinkAdultMaskOfTruthDL, }; static void RegisterAgeDependentMasks() { COND_VB_SHOULD(VB_DRAW_PLAYER_MASK, true, { - if (!LINK_IS_ADULT) return; + if (!LINK_IS_ADULT) + return; PlayerMask currentMask = (PlayerMask)va_arg(args, int); PlayState* play = va_arg(args, PlayState*); int maskIndex = currentMask - 1; - if (maskIndex < 0 || maskIndex >= 8) return; + if (maskIndex < 0 || maskIndex >= 8) + return; const char* adultDL = sAdultMaskDLists[maskIndex]; - if (!ResourceGetIsCustomByName(adultDL) && !ResourceMgr_FileExists(adultDL)) return; + if (!ResourceGetIsCustomByName(adultDL) && !ResourceMgr_FileExists(adultDL)) + return; *should = false; gSPDisplayList(play->state.gfxCtx->polyOpa.p++, (Gfx*)adultDL);