From fae74d4a5e91b350fe01bae57bd28c8a0b2d7106 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Wed, 21 Jan 2026 04:04:24 +0000 Subject: [PATCH] Kaleido Tracker - Add new Shuffles (#6184) Namely Swim, Crawl, Climb, Grab, Open Chests, and Bean Souls Also added a page up and page down feature since the list is getting large. Assigned it to C-Left and C-Right. I'd like to put C-Down as "Jump to End" but the way things currently are I can't set C-Up as "Jump to Start" so I'll leave that one out for now. --- soh/soh/Enhancements/kaleido.cpp | 105 +++++++++++++++++++++++++++---- soh/soh/Enhancements/kaleido.h | 6 +- 2 files changed, 95 insertions(+), 16 deletions(-) diff --git a/soh/soh/Enhancements/kaleido.cpp b/soh/soh/Enhancements/kaleido.cpp index 58f76fbff..e541be5a2 100644 --- a/soh/soh/Enhancements/kaleido.cpp +++ b/soh/soh/Enhancements/kaleido.cpp @@ -1,6 +1,7 @@ #include "kaleido.h" #include "objects/gameplay_keep/gameplay_keep.h" +#include "ship/utils/StringHelper.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/frame_interpolation.h" #include "soh/ShipInit.hpp" @@ -44,6 +45,11 @@ void KaleidoEntryIcon::LoadIconTex(std::vector* mEntryDl) { mIconResourceName, G_IM_FMT_RGBA, G_IM_SIZ_32b, mIconWidth, mIconHeight, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; mEntryDl->insert(mEntryDl->end(), std::begin(iconTexture), std::end(iconTexture)); + } else if (mIconSize == G_IM_SIZ_16b) { + Gfx iconTexture[] = { gsDPLoadTextureBlock( + mIconResourceName, G_IM_FMT_RGBA, G_IM_SIZ_16b, mIconWidth, mIconHeight, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; + mEntryDl->insert(mEntryDl->end(), std::begin(iconTexture), std::end(iconTexture)); } } } @@ -179,6 +185,50 @@ Kaleido::Kaleido() { Rando::StaticData::RetrieveItem(static_cast(rg)).GetName().english)); } } + // Default A button color stored for action shuffle (crawl, climb, etc.) + // TODO: find a way to update this so we can match Cosmetics Editor color, or just replace these icons + Color_RGBA8 aButtonColor = { 90, 90, 255, 255 }; + if (ctx->GetOption(RSK_SHUFFLE_CRAWL)) { + mEntries.push_back(std::make_shared(gButtonBackgroundTex, G_IM_FMT_IA, G_IM_SIZ_8b, 32, + 32, aButtonColor, FlagType::FLAG_RANDOMIZER_INF, + RAND_INF_CAN_CRAWL, "Crawl")); + } + if (ctx->GetOption(RSK_SHUFFLE_CLIMB)) { + mEntries.push_back(std::make_shared(gButtonBackgroundTex, G_IM_FMT_IA, G_IM_SIZ_8b, 32, + 32, aButtonColor, FlagType::FLAG_RANDOMIZER_INF, + RAND_INF_CAN_CLIMB, "Climb")); + } + if (ctx->GetOption(RSK_SHUFFLE_GRAB)) { + mEntries.push_back(std::make_shared(gButtonBackgroundTex, G_IM_FMT_IA, G_IM_SIZ_8b, 32, + 32, aButtonColor, FlagType::FLAG_RANDOMIZER_INF, + RAND_INF_CAN_GRAB, "Grab")); + } + if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST)) { + mEntries.push_back(std::make_shared( + gMapChestIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 8, Color_RGBA8{ 255, 255, 255, 255 }, + FlagType::FLAG_RANDOMIZER_INF, RAND_INF_CAN_OPEN_CHEST, "Open Chests")); + } + if (ctx->GetOption(RSK_SHUFFLE_SWIM)) { + mEntries.push_back(std::make_shared( + gItemIconScaleSilverTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, + FlagType::FLAG_RANDOMIZER_INF, RAND_INF_CAN_SWIM, "Swim")); + } + if (ctx->GetOption(RSK_SHUFFLE_BEAN_SOULS)) { + int rg = RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL; + for (int i = RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL; i <= RAND_INF_ZORAS_RIVER_BEAN_SOUL; i++, rg++) { + std::string beanSoulName = + Rando::StaticData::RetrieveItem(static_cast(rg)).GetName().english; + StringHelper::ReplaceOriginal(beanSoulName, " Bean Soul", ""); + mEntries.push_back(std::make_shared( + gItemIconMagicBeanTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, + FlagType::FLAG_RANDOMIZER_INF, i, std::move(beanSoulName))); + } + } + if (ctx->GetOption(RSK_ROCS_FEATHER)) { + mEntries.push_back(std::make_shared( + gRocsFeatherTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, + FlagType::FLAG_RANDOMIZER_INF, RAND_INF_OBTAINED_ROCS_FEATHER, "Roc's Feather")); + } } extern "C" { @@ -203,12 +253,16 @@ void Kaleido::Draw(PlayState* play) { Matrix_Translate(-108.f, 58.f, 0.0f, MTXMODE_APPLY); // Invert the matrix to render vertices with positive going down Matrix_Scale(1.0f, -1.0f, 1.0f, MTXMODE_APPLY); - bool dpad = CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0); if (((pauseCtx->unk_1E4 == 0) || (pauseCtx->unk_1E4 == 5) || (pauseCtx->unk_1E4 == 8)) && (pauseCtx->pageIndex == PAUSE_QUEST)) { - if (!((pauseCtx->state != 6) || ((pauseCtx->stickRelX == 0) && (pauseCtx->stickRelY == 0)))) { + u16 buttonsToCheck = BTN_CLEFT | BTN_CRIGHT; + if (CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0)) { + buttonsToCheck |= BTN_DUP | BTN_DDOWN | BTN_DLEFT | BTN_DRIGHT; + } + if (!((pauseCtx->state != 6) || ((pauseCtx->stickRelX == 0) && (pauseCtx->stickRelY == 0) && + !CHECK_BTN_ANY(input->press.button, buttonsToCheck)))) { if (pauseCtx->cursorSpecialPos == 0) { - if ((pauseCtx->stickRelY > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) { + if ((pauseCtx->stickRelY > 30) || CHECK_BTN_ALL(input->press.button, BTN_DUP)) { if (mCursorPos > 0) { mCursorPos--; Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, @@ -217,31 +271,56 @@ void Kaleido::Draw(PlayState* play) { if (mCursorPos < mTopIndex) { mTopIndex = mCursorPos; } - } else if ((pauseCtx->stickRelY < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) { - if (mCursorPos < mEntries.size() - 1) { + } else if ((pauseCtx->stickRelY < -30) || CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) { + if (mCursorPos < static_cast(mEntries.size() - 1)) { mCursorPos++; Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } - if (mCursorPos >= mTopIndex + mNumVisible && mTopIndex + mNumVisible < mEntries.size()) { + if (mCursorPos >= mTopIndex + mNumVisible && + mTopIndex + mNumVisible < static_cast(mEntries.size())) { mTopIndex = mCursorPos - mNumVisible + 1; } - } - if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { + } else if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT)) { + if (mCursorPos > 0) { + mCursorPos -= mNumVisible; + if (mCursorPos < 0) { + mCursorPos = 0; + } + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } + if (mCursorPos < mTopIndex) { + mTopIndex = mCursorPos; + } + } else if (CHECK_BTN_ALL(input->press.button, BTN_CRIGHT)) { + if (mCursorPos < static_cast(mEntries.size() - 1)) { + mCursorPos += mNumVisible; + if (mCursorPos > static_cast(mEntries.size() - 1)) { + mCursorPos = mEntries.size() - 1; + } + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } + if (mCursorPos >= mTopIndex + mNumVisible && + mTopIndex + mNumVisible < static_cast(mEntries.size())) { + mTopIndex = mCursorPos - mNumVisible + 1; + } + } else if ((pauseCtx->stickRelX < -30) || CHECK_BTN_ALL(input->press.button, BTN_DLEFT)) { KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_LEFT); pauseCtx->unk_1E4 = 0; - } else if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { + } else if ((pauseCtx->stickRelX > 30) || CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)) { KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_RIGHT); pauseCtx->unk_1E4 = 0; } } else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT) { - if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { + if ((pauseCtx->stickRelX > 30) || CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)) { pauseCtx->cursorSpecialPos = 0; Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_RIGHT) { - if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { + if ((pauseCtx->stickRelX < -30) || CHECK_BTN_ALL(input->press.button, BTN_DLEFT)) { pauseCtx->cursorSpecialPos = 0; Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); @@ -252,7 +331,7 @@ void Kaleido::Draw(PlayState* play) { } } int yOffset = 1; - for (size_t i = mTopIndex; i < (mTopIndex + mNumVisible) && i < mEntries.size(); i++) { + for (int i = mTopIndex; i < (mTopIndex + mNumVisible) && i < static_cast(mEntries.size()); i++) { auto& entry = mEntries[i]; entry->SetYOffset(yOffset); yOffset += 9; @@ -269,7 +348,7 @@ void Kaleido::Draw(PlayState* play) { } void Kaleido::Update(PlayState* play) { - for (size_t i = mTopIndex; i < (mTopIndex + mNumVisible) && i < mEntries.size(); i++) { + for (int i = mTopIndex; i < (mTopIndex + mNumVisible) && i < static_cast(mEntries.size()); i++) { const auto& entry = mEntries[i]; entry->Update(play); } diff --git a/soh/soh/Enhancements/kaleido.h b/soh/soh/Enhancements/kaleido.h index 93c542c4c..922a1dac3 100644 --- a/soh/soh/Enhancements/kaleido.h +++ b/soh/soh/Enhancements/kaleido.h @@ -163,9 +163,9 @@ class Kaleido { private: std::vector> mEntries; std::vector mEntryDl; - size_t mTopIndex = 0; - size_t mCursorPos = 0; - const size_t mNumVisible = 14; + int mTopIndex = 0; + int mCursorPos = 0; + const int mNumVisible = 14; }; } // namespace Rando