From 28afbec341619dc9e996a75c25456313e37b7266 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Tue, 23 Aug 2022 21:12:21 -0400 Subject: [PATCH 1/7] Adds support for custom drawing functions, and adds one for Small Keys and Boss Keys. --- soh/CMakeLists.txt | 2 + .../Enhancements/item-tables/ItemTableTypes.h | 17 ++- soh/soh/Enhancements/randomizer/draw.cpp | 114 ++++++++++++++++++ soh/soh/Enhancements/randomizer/draw.h | 12 ++ .../Enhancements/randomizer/randomizer.cpp | 6 + soh/src/code/z_en_item00.c | 12 +- soh/src/code/z_player_lib.c | 6 +- 7 files changed, 162 insertions(+), 7 deletions(-) create mode 100644 soh/soh/Enhancements/randomizer/draw.cpp create mode 100644 soh/soh/Enhancements/randomizer/draw.h diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index a8693eb35..67308ec1a 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -181,6 +181,7 @@ set(Header_Files__soh__Enhancements__randomizer "soh/Enhancements/randomizer/randomizer_item_tracker.h" "soh/Enhancements/randomizer/adult_trade_shuffle.h" "soh/Enhancements/randomizer/randomizer_check_objects.h" + "soh/Enhancements/randomizer/draw.h" ) source_group("Header Files\\soh\\Enhancements\\randomizer" FILES ${Header_Files__soh__Enhancements__randomizer}) @@ -288,6 +289,7 @@ set(Source_Files__soh__Enhancements__randomizer "soh/Enhancements/randomizer/randomizer_item_tracker.cpp" "soh/Enhancements/randomizer/adult_trade_shuffle.c" "soh/Enhancements/randomizer/randomizer_check_objects.cpp" + "soh/Enhancements/randomizer/draw.cpp" ) source_group("Source Files\\soh\\Enhancements\\randomizer" FILES ${Source_Files__soh__Enhancements__randomizer}) diff --git a/soh/soh/Enhancements/item-tables/ItemTableTypes.h b/soh/soh/Enhancements/item-tables/ItemTableTypes.h index 7e5f1a9a3..f10d94dc2 100644 --- a/soh/soh/Enhancements/item-tables/ItemTableTypes.h +++ b/soh/soh/Enhancements/item-tables/ItemTableTypes.h @@ -7,12 +7,20 @@ #define CHEST_ANIM_LONG 1 #define GET_ITEM(itemId, objectId, drawId, textId, field, chestAnim, modIndex, getItemId) \ - { itemId, field, (chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1), textId, objectId, modIndex, getItemId, drawId, true } + { itemId, field, (chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1), textId, objectId, modIndex, getItemId, drawId, true, NULL } #define GET_ITEM_NONE \ - { ITEM_NONE, 0, 0, 0, 0, 0, 0, 0, false } + { ITEM_NONE, 0, 0, 0, 0, 0, 0, 0, false, NULL } -typedef struct { +#define GET_ITEM_CUSTOM_DRAW(itemId, objectId, drawId, textId, field, chestAnim, modIndex, getItemId, drawFunc) \ + { itemId, field (chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1), textId, objectId, modIndex, getItemId, drawId, true, drawFunc } + +typedef struct GlobalContext GlobalContext; +typedef struct GetItemEntry GetItemEntry; + +typedef void (*CustomDrawFunc)(GlobalContext* globalCtx, GetItemEntry* getItemEntry); + +typedef struct GetItemEntry { /* 0x00 */ uint16_t itemId; /* 0x01 */ uint16_t field; // various bit-packed data /* 0x02 */ int16_t gi; // defines the draw id and chest opening animation @@ -22,4 +30,5 @@ typedef struct { /* 0x08 */ int16_t getItemId; /* 0x0A */ uint16_t gid; // Stores the GID value unmodified for future reference. /* 0x0C */ uint16_t collectable; // determines whether the item can be collected on the overworld. Will be true in most cases. -} GetItemEntry; // size = 0x0F + CustomDrawFunc drawFunc; +}; // size = 0x0F diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp new file mode 100644 index 000000000..fbf97c671 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -0,0 +1,114 @@ +#include "draw.h" +#include "z64.h" +#include "macros.h" +#include "functions.h" +#include "randomizerTypes.h" +#include +#include "objects/object_gi_key/object_gi_key.h" +#include "objects/object_gi_bosskey/object_gi_bosskey.h" + +extern "C" void Randomizer_DrawSmallKey(GlobalContext* globalCtx, GetItemEntry* getItemEntry) { + s32 pad; + + std::array color; + switch(getItemEntry->getItemId) { + case RG_FOREST_TEMPLE_SMALL_KEY: + color = {4, 195, 46}; + break; + case RG_FIRE_TEMPLE_SMALL_KEY: + color = {237, 95, 95}; + break; + case RG_WATER_TEMPLE_SMALL_KEY: + color = {85, 180, 223}; + break; + case RG_SPIRIT_TEMPLE_SMALL_KEY: + color = {222, 158, 47}; + break; + case RG_SHADOW_TEMPLE_SMALL_KEY: + color = {126, 16, 177}; + break; + case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY: + color = {221, 212, 60}; + break; + case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: + color = {227, 110, 255}; + break; + case RG_GANONS_CASTLE_SMALL_KEY: + color = {80, 80, 80}; + break; + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_80093D18(globalCtx->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + gsDPSetGrayscaleColor(POLY_OPA_DISP++, color[0], color[1], color[2], 255); + gsSPGrayscale(POLY_OPA_DISP++, true); + + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiSmallKeyDL); + + gsSPGrayscale(POLY_OPA_DISP++, false); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +extern "C" void Randomizer_DrawBossKey(GlobalContext* globalCtx, GetItemEntry* getItemEntry) { + s32 pad; + s16 color_slot; + color_slot = getItemEntry->getItemId - RG_FOREST_TEMPLE_BOSS_KEY; + s16 colors[6][3] = { + { 4, 195, 46 }, // Forest Temple + { 237, 95, 95 }, // Fire Temple + { 85, 180, 223 }, // Water Temple + { 222, 158, 47 }, // Spirit Temple + { 126, 16, 177 }, // Shadow Temple + { 210, 0, 0 } // Ganon's Castle + }; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_80093D18(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + if (color_slot == 5) { // Ganon's Boss Key + gsDPSetGrayscaleColor(POLY_OPA_DISP++, 80, 80, 80, 255); + gsSPGrayscale(POLY_OPA_DISP++, true); + } + + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiBossKeyDL); + + if (color_slot == 5) { // Ganon's Boss Key + gsSPGrayscale(POLY_OPA_DISP++, false); + } + + func_80093D84(globalCtx->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + if (color_slot >= 0) { + gsDPSetGrayscaleColor(POLY_XLU_DISP++, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], + 255); + gsSPGrayscale(POLY_XLU_DISP++, true); + } + + gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiBossKeyGemDL); + + if (color_slot >= 0) { + gsSPGrayscale(POLY_XLU_DISP++, false); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h new file mode 100644 index 000000000..a703fb600 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -0,0 +1,12 @@ +#ifndef RANDODRAW_H +#define RANDODRAW_H +#pragma once + +#include "../item-tables/ItemTableTypes.h" + +typedef struct GlobalContext GlobalContext; + +extern "C" void Randomizer_DrawSmallKey(GlobalContext* globalCtx, GetItemEntry* getItemEntry); +extern "C" void Randomizer_DrawBossKey(GlobalContext* globalCtx, GetItemEntry* getItemEntry); + +#endif \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 60c198ed4..dbb441702 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -20,6 +20,7 @@ #include #include "randomizer_check_objects.h" #include +#include "draw.h" using json = nlohmann::json; using namespace std::literals::string_literals; @@ -3889,6 +3890,11 @@ void InitRandoItemTable() { ItemTableManager::Instance->AddItemEntry(MOD_RANDOMIZER, extendedVanillaGetItemTable[i].getItemId, extendedVanillaGetItemTable[i]); } for (int i = 0; i < ARRAY_COUNT(randoGetItemTable); i++) { + if (randoGetItemTable[i].itemId >= RG_FOREST_TEMPLE_SMALL_KEY && randoGetItemTable[i].itemId <= RG_GANONS_CASTLE_SMALL_KEY) { + randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawSmallKey; + } else if (randoGetItemTable[i].itemId >= RG_FOREST_TEMPLE_BOSS_KEY && randoGetItemTable[i].itemId <= RG_GANONS_CASTLE_BOSS_KEY) { + randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawBossKey; + } ItemTableManager::Instance->AddItemEntry(MOD_RANDOMIZER, randoGetItemTable[i].itemId, randoGetItemTable[i]); } } diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index a50c74e87..60e33b0bd 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -1360,7 +1360,11 @@ void EnItem00_DrawCollectible(EnItem00* this, GlobalContext* globalCtx) { GetItemEntry randoGetItemEntry = Randomizer_GetRandomizedItem(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemEntry); - GetItem_Draw(globalCtx, randoGetItemEntry.gid); + if (randoGetItemEntry.drawFunc != NULL) { + randoGetItemEntry.drawFunc(globalCtx, &randoGetItemEntry); + } else { + GetItem_Draw(globalCtx, randoGetItemEntry.gid); + } } else { s32 texIndex = this->actor.params - 3; @@ -1419,7 +1423,11 @@ void EnItem00_DrawHeartPiece(EnItem00* this, GlobalContext* globalCtx) { GetItemEntry randoGetItemEntry = Randomizer_GetRandomizedItem(GI_HEART_PIECE, this->actor.id, this->ogParams, globalCtx->sceneNum); EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemEntry); - GetItem_Draw(globalCtx, randoGetItemEntry.gid); + if (randoGetItemEntry.drawFunc != NULL) { + randoGetItemEntry.drawFunc(globalCtx, &randoGetItemEntry); + } else { + GetItem_Draw(globalCtx, randoGetItemEntry.gid); + } } else { s32 pad; diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index 99425bd8d..f30c493da 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -1170,7 +1170,11 @@ void Player_DrawGetItemImpl(GlobalContext* globalCtx, Player* this, Vec3f* refPo Matrix_RotateZYX(0, globalCtx->gameplayFrames * 1000, 0, MTXMODE_APPLY); Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY); - GetItem_Draw(globalCtx, drawIdPlusOne - 1); + if(this->getItemEntry.drawFunc != NULL) { + this->getItemEntry.drawFunc(globalCtx, &this->getItemEntry); + } else { + GetItem_Draw(globalCtx, drawIdPlusOne - 1); + } CLOSE_DISPS(globalCtx->state.gfxCtx); } From c7b998b33b034270a29e21861984a9df4d2964bc Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Tue, 23 Aug 2022 23:48:14 -0400 Subject: [PATCH 2/7] Implements better way to use new draw functions and adds Double Defense colors. --- soh/include/functions.h | 1 + soh/soh/Enhancements/randomizer/draw.cpp | 74 ++++++++++--------- soh/soh/Enhancements/randomizer/draw.h | 1 + .../Enhancements/randomizer/randomizer.cpp | 2 + soh/src/code/z_draw.c | 12 +++ soh/src/code/z_en_item00.c | 18 ++--- .../actors/ovl_Demo_Effect/z_demo_effect.c | 4 + .../actors/ovl_En_Ex_Item/z_en_ex_item.c | 4 +- soh/src/overlays/actors/ovl_En_Si/z_en_si.c | 2 +- .../actors/ovl_Item_B_Heart/z_item_b_heart.c | 4 +- .../ovl_Item_Etcetera/z_item_etcetera.c | 7 +- .../actors/ovl_Item_Ocarina/z_item_ocarina.c | 2 +- 12 files changed, 75 insertions(+), 56 deletions(-) diff --git a/soh/include/functions.h b/soh/include/functions.h index a458505e7..d3c5cfe2b 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -859,6 +859,7 @@ void Cutscene_HandleEntranceTriggers(GlobalContext* globalCtx); void Cutscene_HandleConditionalTriggers(GlobalContext* globalCtx); void Cutscene_SetSegment(GlobalContext* globalCtx, void* segment); void GetItem_Draw(GlobalContext* globalCtx, s16 drawId); +void GetItemEntry_Draw(GlobalContext* globalCtx, GetItemEntry getItemEntry); void SoundSource_InitAll(GlobalContext* globalCtx); void SoundSource_UpdateAll(GlobalContext* globalCtx); void SoundSource_PlaySfxAtFixedWorldPos(GlobalContext* globalCtx, Vec3f* pos, s32 duration, u16 sfxId); diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index fbf97c671..05cbe0165 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -6,49 +6,31 @@ #include #include "objects/object_gi_key/object_gi_key.h" #include "objects/object_gi_bosskey/object_gi_bosskey.h" +#include "objects/object_gi_hearts/object_gi_hearts.h" extern "C" void Randomizer_DrawSmallKey(GlobalContext* globalCtx, GetItemEntry* getItemEntry) { s32 pad; - - std::array color; - switch(getItemEntry->getItemId) { - case RG_FOREST_TEMPLE_SMALL_KEY: - color = {4, 195, 46}; - break; - case RG_FIRE_TEMPLE_SMALL_KEY: - color = {237, 95, 95}; - break; - case RG_WATER_TEMPLE_SMALL_KEY: - color = {85, 180, 223}; - break; - case RG_SPIRIT_TEMPLE_SMALL_KEY: - color = {222, 158, 47}; - break; - case RG_SHADOW_TEMPLE_SMALL_KEY: - color = {126, 16, 177}; - break; - case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY: - color = {221, 212, 60}; - break; - case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: - color = {227, 110, 255}; - break; - case RG_GANONS_CASTLE_SMALL_KEY: - color = {80, 80, 80}; - break; - } + + s16 color_slot = getItemEntry->getItemId - RG_FOREST_TEMPLE_SMALL_KEY; + s16 colors[8][3] = { + { 4, 195, 46 }, // Forest Temple + { 237, 95, 95 }, // Fire Temple + { 85, 180, 223 }, // Water Temple + { 222, 158, 47 }, // Spirit Temple + { 126, 16, 177 }, // Shadow Temple + { 221, 212, 60 }, // Gerudo Training Grounds + { 227, 110, 255 }, // Bottom of the Well + { 80, 80, 80 } // Ganon's Castle + }; OPEN_DISPS(globalCtx->state.gfxCtx); func_80093D18(globalCtx->state.gfxCtx); - gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_MODELVIEW | G_MTX_LOAD); - gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); - gsDPSetGrayscaleColor(POLY_OPA_DISP++, color[0], color[1], color[2], 255); + gsDPSetGrayscaleColor(POLY_OPA_DISP++, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 255); gsSPGrayscale(POLY_OPA_DISP++, true); gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiSmallKeyDL); @@ -74,8 +56,6 @@ extern "C" void Randomizer_DrawBossKey(GlobalContext* globalCtx, GetItemEntry* g OPEN_DISPS(globalCtx->state.gfxCtx); func_80093D18(globalCtx->state.gfxCtx); - gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_MODELVIEW | G_MTX_LOAD); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); @@ -92,8 +72,6 @@ extern "C" void Randomizer_DrawBossKey(GlobalContext* globalCtx, GetItemEntry* g } func_80093D84(globalCtx->state.gfxCtx); - gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_MODELVIEW | G_MTX_LOAD); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); @@ -110,5 +88,29 @@ extern "C" void Randomizer_DrawBossKey(GlobalContext* globalCtx, GetItemEntry* g gsSPGrayscale(POLY_XLU_DISP++, false); } + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +extern "C" void Randomizer_DrawDoubleDefense(GlobalContext* globalCtx, GetItemEntry getItemEntry) { + s32 pad; + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_80093D84(globalCtx->state.gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); + + // if (drawId == doubleDef) { + gsDPSetGrayscaleColor(POLY_XLU_DISP++, 255, 255, 255, 255); + gsSPGrayscale(POLY_XLU_DISP++, true); + // } + + gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiHeartBorderDL); + + // if (drawId == doubleDef) { + gsSPGrayscale(POLY_XLU_DISP++, false); + // } + + gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiHeartContainerDL); + CLOSE_DISPS(globalCtx->state.gfxCtx); } \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index a703fb600..a38e99589 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -8,5 +8,6 @@ typedef struct GlobalContext GlobalContext; extern "C" void Randomizer_DrawSmallKey(GlobalContext* globalCtx, GetItemEntry* getItemEntry); extern "C" void Randomizer_DrawBossKey(GlobalContext* globalCtx, GetItemEntry* getItemEntry); +extern "C" void Randomizer_DrawDoubleDefense(GlobalContext* globalCtx, GetItemEntry getItemEntry); #endif \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index dbb441702..aa0427d7f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3894,6 +3894,8 @@ void InitRandoItemTable() { randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawSmallKey; } else if (randoGetItemTable[i].itemId >= RG_FOREST_TEMPLE_BOSS_KEY && randoGetItemTable[i].itemId <= RG_GANONS_CASTLE_BOSS_KEY) { randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawBossKey; + } else if (randoGetItemTable[i].itemId == RG_DOUBLE_DEFENSE) { + randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawDoubleDefense; } ItemTableManager::Instance->AddItemEntry(MOD_RANDOMIZER, randoGetItemTable[i].itemId, randoGetItemTable[i]); } diff --git a/soh/src/code/z_draw.c b/soh/src/code/z_draw.c index 60c3a7ee4..d85521efa 100644 --- a/soh/src/code/z_draw.c +++ b/soh/src/code/z_draw.c @@ -395,6 +395,18 @@ void GetItem_Draw(GlobalContext* globalCtx, s16 drawId) { sDrawItemTable[drawId].drawFunc(globalCtx, drawId); } +/** + * Draw "Get Item" Model from a `GetItemEntry` + * Uses the Custom Draw Function if it exists, or just calls `GetItem_Draw` + */ +void GetItemEntry_Draw(GlobalContext* globalCtx, GetItemEntry getItemEntry) { + if (getItemEntry.drawFunc != NULL) { + getItemEntry.drawFunc(globalCtx, &getItemEntry); + } else { + GetItem_Draw(globalCtx, getItemEntry.gid); + } +} + // All remaining functions in this file are draw functions referenced in the table and called by the function above /* 0x0178 */ u8 primXluColor[3]; diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 60e33b0bd..7843583c2 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -1272,7 +1272,7 @@ void EnItem00_CustomItemsParticles(Actor* Parent, GlobalContext* globalCtx, GetI color_slot = 0; break; case RG_DOUBLE_DEFENSE: - color_slot = 1; + color_slot = 8; break; default: return; @@ -1284,14 +1284,14 @@ void EnItem00_CustomItemsParticles(Actor* Parent, GlobalContext* globalCtx, GetI s16* colors[9][3] = { { 34, 255, 76 }, // Minuet and Magic Upgrades Colors - { 177, 35, 35 }, // Bolero and Double Defense Colors + { 177, 35, 35 }, // Bolero Colors { 115, 251, 253 }, // Serenade Color { 177, 122, 35 }, // Requiem Color { 177, 28, 212 }, // Nocturne Color { 255, 255, 92 }, // Prelude Color { 31, 152, 49 }, // Stick Upgrade Color { 222, 182, 20 }, // Nut Upgrade Color - { 255, 255, 255 } // White Color placeholder + { 255, 255, 255 } // Double Defense Color }; s16* colorsEnv[9][3] = { @@ -1360,11 +1360,7 @@ void EnItem00_DrawCollectible(EnItem00* this, GlobalContext* globalCtx) { GetItemEntry randoGetItemEntry = Randomizer_GetRandomizedItem(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemEntry); - if (randoGetItemEntry.drawFunc != NULL) { - randoGetItemEntry.drawFunc(globalCtx, &randoGetItemEntry); - } else { - GetItem_Draw(globalCtx, randoGetItemEntry.gid); - } + GetItemEntry_Draw(globalCtx, randoGetItemEntry); } else { s32 texIndex = this->actor.params - 3; @@ -1423,11 +1419,7 @@ void EnItem00_DrawHeartPiece(EnItem00* this, GlobalContext* globalCtx) { GetItemEntry randoGetItemEntry = Randomizer_GetRandomizedItem(GI_HEART_PIECE, this->actor.id, this->ogParams, globalCtx->sceneNum); EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemEntry); - if (randoGetItemEntry.drawFunc != NULL) { - randoGetItemEntry.drawFunc(globalCtx, &randoGetItemEntry); - } else { - GetItem_Draw(globalCtx, randoGetItemEntry.gid); - } + GetItemEntry_Draw(globalCtx, randoGetItemEntry); } else { s32 pad; diff --git a/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c b/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c index 8d81b41c4..12c42358b 100644 --- a/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c +++ b/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c @@ -2089,6 +2089,10 @@ void DemoEffect_DrawGetItem(Actor* thisx, GlobalContext* globalCtx) { if (gSaveContext.n64ddFlag && globalCtx->sceneNum == SCENE_BDAN) { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE); this->getItem.drawId = getItemEntry.gid; + func_8002EBCC(thisx, globalCtx, 0); + func_8002ED80(thisx, globalCtx, 0); + GetItemEntry_Draw(globalCtx, getItemEntry); + return; } func_8002EBCC(thisx, globalCtx, 0); func_8002ED80(thisx, globalCtx, 0); diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c index 0cbc370af..495f80270 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c @@ -524,6 +524,8 @@ void EnExItem_DrawItems(EnExItem* this, GlobalContext* globalCtx) { } EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItem); + GetItemEntry_Draw(globalCtx, randoGetItem); + return; } GetItem_Draw(globalCtx, this->giDrawId); @@ -536,7 +538,7 @@ void EnExItem_DrawHeartPiece(EnExItem* this, GlobalContext* globalCtx) { GetItemEntry randoGetItem = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE); EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItem); - GetItem_Draw(globalCtx, randoGetItem.gid); + GetItemEntry_Draw(globalCtx, randoGetItem); } else { GetItem_Draw(globalCtx, GID_HEART_PIECE); } diff --git a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c index a9c3cb258..36fc46abb 100644 --- a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c +++ b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c @@ -184,7 +184,7 @@ void EnSi_Draw(Actor* thisx, GlobalContext* globalCtx) { f32 mtxScale = 1.5f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); } - GetItem_Draw(globalCtx, getItem.gid); + GetItemEntry_Draw(globalCtx, getItem); } } diff --git a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c index 304c3053d..f4181146a 100644 --- a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c +++ b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c @@ -99,8 +99,8 @@ void ItemBHeart_Draw(Actor* thisx, GlobalContext* globalCtx) { } if (gSaveContext.n64ddFlag) { - GetItem_Draw(globalCtx, Randomizer_GetRandomizedItem(GI_HEART_CONTAINER_2, - this->actor.id,this->actor.params, globalCtx->sceneNum).gid); + GetItemEntry_Draw(globalCtx, Randomizer_GetRandomizedItem(GI_HEART_CONTAINER_2, + this->actor.id,this->actor.params, globalCtx->sceneNum)); } else { if (flag) { func_80093D84(globalCtx->state.gfxCtx); diff --git a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c index eb6efef7b..c8e57237f 100644 --- a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c +++ b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c @@ -233,7 +233,7 @@ void ItemEtcetera_DrawThroughLens(Actor* thisx, GlobalContext* globalCtx) { GetItemEntry randoGetItem = GetChestGameRandoGetItem(this->actor.room, this->giDrawId, globalCtx); EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItem); if (randoGetItem.itemId != ITEM_NONE) { - GetItem_Draw(globalCtx, randoGetItem.gid); + GetItemEntry_Draw(globalCtx, randoGetItem); return; } } @@ -257,7 +257,10 @@ void ItemEtcetera_Draw(Actor* thisx, GlobalContext* globalCtx) { EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItem); if (randoGetItem.itemId != RG_NONE) { - this->giDrawId = randoGetItem.gid; + func_8002EBCC(&this->actor, globalCtx, 0); + func_8002ED80(&this->actor, globalCtx, 0); + GetItemEntry_Draw(globalCtx, randoGetItem); + return; } } diff --git a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c index a8db425da..1cc8752cb 100644 --- a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c +++ b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c @@ -218,7 +218,7 @@ void ItemOcarina_Draw(Actor* thisx, GlobalContext* globalCtx) { if (gSaveContext.n64ddFlag) { GetItemEntry randoGetItem = Randomizer_GetItemFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT); EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItem); - GetItem_Draw(globalCtx, randoGetItem.gid); + GetItemEntry_Draw(globalCtx, randoGetItem); return; } From 6561073c7b98289e59397e7c3dd4819b621bd2cb Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Wed, 24 Aug 2022 00:07:16 -0400 Subject: [PATCH 3/7] Implements ImGui Checkbox to enable or disable color-coded-keys. --- libultraship/libultraship/ImGuiImpl.cpp | 3 +++ soh/src/code/z_draw.c | 2 +- soh/src/code/z_player_lib.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index cac675a93..8ba847ea3 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -1903,6 +1903,9 @@ namespace SohImGui { "(medallions/stones/songs). Note that these fanfares\n" "are longer than usual." ); + PaddedEnhancementCheckbox("Key Colors Match Dungeon", "gRandoMatchKeyColors", true, false); + Tooltip( + "Matches the color of small keys and boss keys to the dungeon they belong to. This helps identify keys from afar and adds a little bit of flair."); ImGui::EndMenu(); } diff --git a/soh/src/code/z_draw.c b/soh/src/code/z_draw.c index d85521efa..2751f4716 100644 --- a/soh/src/code/z_draw.c +++ b/soh/src/code/z_draw.c @@ -400,7 +400,7 @@ void GetItem_Draw(GlobalContext* globalCtx, s16 drawId) { * Uses the Custom Draw Function if it exists, or just calls `GetItem_Draw` */ void GetItemEntry_Draw(GlobalContext* globalCtx, GetItemEntry getItemEntry) { - if (getItemEntry.drawFunc != NULL) { + if (getItemEntry.drawFunc != NULL && CVar_GetS32("gRandoMatchKeyColors", 0)) { getItemEntry.drawFunc(globalCtx, &getItemEntry); } else { GetItem_Draw(globalCtx, getItemEntry.gid); diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index f30c493da..203585331 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -1170,7 +1170,7 @@ void Player_DrawGetItemImpl(GlobalContext* globalCtx, Player* this, Vec3f* refPo Matrix_RotateZYX(0, globalCtx->gameplayFrames * 1000, 0, MTXMODE_APPLY); Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY); - if(this->getItemEntry.drawFunc != NULL) { + if (this->getItemEntry.drawFunc != NULL && CVar_GetS32("gRandoMatchKeyColors", 0)) { this->getItemEntry.drawFunc(globalCtx, &this->getItemEntry); } else { GetItem_Draw(globalCtx, drawIdPlusOne - 1); From e3ae302a64fc33abffda83736eb6b26da1dd1c69 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Wed, 24 Aug 2022 00:17:47 -0400 Subject: [PATCH 4/7] Adds padding to a few checkboxes in rando menu that were missing it --- libultraship/libultraship/ImGuiImpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index 9b10e7a6d..e46e29aac 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -2000,13 +2000,13 @@ namespace SohImGui { if (ImGui::BeginMenu("Rando Enhancements")) { - EnhancementCheckbox("Quest Item Fanfares", "gRandoQuestItemFanfares"); + PaddedEnhancementCheckbox("Quest Item Fanfares", "gRandoQuestItemFanfares"); Tooltip( "Play unique fanfares when obtaining quest items\n" "(medallions/stones/songs). Note that these fanfares\n" "are longer than usual." ); - EnhancementCheckbox("Rando-Relevant Navi Hints", "gRandoRelevantNavi"); + PaddedEnhancementCheckbox("Rando-Relevant Navi Hints", "gRandoRelevantNavi"); Tooltip( "Replace Navi's overworld quest hints with rando-\n" "related gameplay hints.\n" From 821c7948d6584aa2278d098bc56c3a77d20b7311 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Wed, 24 Aug 2022 13:06:48 -0400 Subject: [PATCH 5/7] Cleanup --- soh/soh/Enhancements/randomizer/draw.cpp | 18 +++++------------- soh/soh/Enhancements/randomizer/draw.h | 2 +- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index 05cbe0165..e7b75ecd1 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -76,17 +76,13 @@ extern "C" void Randomizer_DrawBossKey(GlobalContext* globalCtx, GetItemEntry* g gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); - if (color_slot >= 0) { - gsDPSetGrayscaleColor(POLY_XLU_DISP++, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], - 255); - gsSPGrayscale(POLY_XLU_DISP++, true); - } + gsDPSetGrayscaleColor(POLY_XLU_DISP++, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], + 255); + gsSPGrayscale(POLY_XLU_DISP++, true); gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiBossKeyGemDL); - if (color_slot >= 0) { - gsSPGrayscale(POLY_XLU_DISP++, false); - } + gsSPGrayscale(POLY_XLU_DISP++, false); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -99,18 +95,14 @@ extern "C" void Randomizer_DrawDoubleDefense(GlobalContext* globalCtx, GetItemEn gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); - // if (drawId == doubleDef) { gsDPSetGrayscaleColor(POLY_XLU_DISP++, 255, 255, 255, 255); gsSPGrayscale(POLY_XLU_DISP++, true); - // } gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiHeartBorderDL); - // if (drawId == doubleDef) { gsSPGrayscale(POLY_XLU_DISP++, false); - // } gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiHeartContainerDL); CLOSE_DISPS(globalCtx->state.gfxCtx); -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index a38e99589..b1a93bd92 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -10,4 +10,4 @@ extern "C" void Randomizer_DrawSmallKey(GlobalContext* globalCtx, GetItemEntry* extern "C" void Randomizer_DrawBossKey(GlobalContext* globalCtx, GetItemEntry* getItemEntry); extern "C" void Randomizer_DrawDoubleDefense(GlobalContext* globalCtx, GetItemEntry getItemEntry); -#endif \ No newline at end of file +#endif From 02a8ba8bb9647d4f4b3932aaebe9af5ae8e7ec46 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Wed, 24 Aug 2022 13:16:14 -0400 Subject: [PATCH 6/7] Fixes incorrect key order in DrawSmallKeys. --- soh/soh/Enhancements/randomizer/draw.cpp | 5 +++-- soh/soh/Enhancements/randomizer/randomizer.cpp | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index e7b75ecd1..8e276d1a1 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -12,14 +12,15 @@ extern "C" void Randomizer_DrawSmallKey(GlobalContext* globalCtx, GetItemEntry* s32 pad; s16 color_slot = getItemEntry->getItemId - RG_FOREST_TEMPLE_SMALL_KEY; - s16 colors[8][3] = { + s16 colors[9][3] = { { 4, 195, 46 }, // Forest Temple { 237, 95, 95 }, // Fire Temple { 85, 180, 223 }, // Water Temple { 222, 158, 47 }, // Spirit Temple { 126, 16, 177 }, // Shadow Temple - { 221, 212, 60 }, // Gerudo Training Grounds { 227, 110, 255 }, // Bottom of the Well + { 221, 212, 60 }, // Gerudo Training Grounds + { 255, 255, 255 }, // Theive's Hideout (unused) { 80, 80, 80 } // Ganon's Castle }; diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 15523de07..e59b6f771 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4050,7 +4050,8 @@ void InitRandoItemTable() { ItemTableManager::Instance->AddItemEntry(MOD_RANDOMIZER, extendedVanillaGetItemTable[i].getItemId, extendedVanillaGetItemTable[i]); } for (int i = 0; i < ARRAY_COUNT(randoGetItemTable); i++) { - if (randoGetItemTable[i].itemId >= RG_FOREST_TEMPLE_SMALL_KEY && randoGetItemTable[i].itemId <= RG_GANONS_CASTLE_SMALL_KEY) { + if (randoGetItemTable[i].itemId >= RG_FOREST_TEMPLE_SMALL_KEY && randoGetItemTable[i].itemId <= RG_GANONS_CASTLE_SMALL_KEY + && randoGetItemTable[i].itemId != RG_GERUDO_FORTRESS_SMALL_KEY) { randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawSmallKey; } else if (randoGetItemTable[i].itemId >= RG_FOREST_TEMPLE_BOSS_KEY && randoGetItemTable[i].itemId <= RG_GANONS_CASTLE_BOSS_KEY) { randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawBossKey; From 37fe5491b2cd92665410077adafe6979b5051f2f Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Wed, 24 Aug 2022 13:55:03 -0400 Subject: [PATCH 7/7] Always color in Double Defense --- soh/src/code/z_draw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/soh/src/code/z_draw.c b/soh/src/code/z_draw.c index 2751f4716..c2af2b8a9 100644 --- a/soh/src/code/z_draw.c +++ b/soh/src/code/z_draw.c @@ -400,7 +400,9 @@ void GetItem_Draw(GlobalContext* globalCtx, s16 drawId) { * Uses the Custom Draw Function if it exists, or just calls `GetItem_Draw` */ void GetItemEntry_Draw(GlobalContext* globalCtx, GetItemEntry getItemEntry) { - if (getItemEntry.drawFunc != NULL && CVar_GetS32("gRandoMatchKeyColors", 0)) { + // RANDOTODO: Make this more flexible for easier toggling of individual item recolors in the future. + if (getItemEntry.drawFunc != NULL && + (CVar_GetS32("gRandoMatchKeyColors", 0) || getItemEntry.getItemId == RG_DOUBLE_DEFENSE)) { getItemEntry.drawFunc(globalCtx, &getItemEntry); } else { GetItem_Draw(globalCtx, getItemEntry.gid);