From f4e53c54b5bdd56c4abd2f3632c88c1747c9cb94 Mon Sep 17 00:00:00 2001 From: Sarge-117 Date: Mon, 29 Aug 2022 18:17:23 -0700 Subject: [PATCH 01/20] Correct German spellings, add 2 more hints --- .../Enhancements/randomizer/randomizer.cpp | 20 +++++++++++++------ soh/soh/Enhancements/randomizer/randomizer.h | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 8f4ef7d3b..d12db3552 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4189,7 +4189,7 @@ CustomMessageMinimal NaviMessages[NUM_NAVI_MESSAGES] = { "%cSi tu es coincé sur cette seed,&tu peux toujours jeter l'éponge&et regader le %wSpoiler log%c..." }, { "%cDid you know that the %yHover&Boots %ccan be used to cross&%wquicksand%c?", - "%cWusstest du, dass du mit den&%yGleitstiefeln %cTreibsand %wüberqueren&kannst%c?", + "%cWußtest du, daß du mit den&%yGleitstiefeln %cTreibsand %wüberqueren&kannst%c?", "%cEst-ce que tu savais que les %rBottes&des airs %cpouvaient être utilisées&pour traverser les %wsables mouvants%c?" }, { "%cYou can reach the back of %wImpa's&House %cby jumping from the&unfinished house with a %rcucco%c!", @@ -4197,15 +4197,15 @@ CustomMessageMinimal NaviMessages[NUM_NAVI_MESSAGES] = { "%cTu peux atteindre l'arrière de la&%wMaison d'Impa %cen sautant depuis la&maison en construction avec une&%rcocotte%c!" }, { "%cThe %ySpirit Trial %cin %pGanon's Castle&%chas a %whidden chest %csomewhere.&Did you already know that?", - "%cDie %yGeister-Prüfung %cin %pGanons&Schloss %chat irgendwo eine&%wversteckte Kiste%c. Weißt du schon&wo?", + "%cDie %yGeister-Prüfung %cin %pGanons&Schloß %chat irgendwo eine&%wversteckte Kiste%c. Weißt du schon&wo?", "%cL'%yÉpreuve de l'Esprit%c dans le %pChâteau&de Ganon %ca un coffre caché quelque&part. Je suppose que tu le savais&déjà?" }, { "%cYou know the %wBombchu Bowling&Alley%c? I heard %wonly two of the &prizes %care worthwhile. The rest &is junk!", - "%cKennst du die %wMinenbowlingbahn%c?&Ich habe gehört dass sich nur &%wzwei der Preise%c lohnen. Der Rest&ist Krimskrams!", + "%cKennst du die %wMinenbowlingbahn%c?&Ich habe gehört daß sich nur &%wzwei der Preise%c lohnen. Der Rest&ist Krimskrams!", "%cEst-ce que tu savais qu'au %wBowling&Teigneux%c, il n'y a que les %wdeux&premiers prix %cqui sont intéréssant?" }, { "%cHave you been using %wDeku Nuts&%cenough? I've seen them blow up&a %rBombchu%c!", - "%cBenutzt du auch genügend %wDeku&Nüsse%c? Ich habe mal gesehen dass&man damit %rKrabbelminen %cdetonieren&kann!", + "%cBenutzt du auch genügend %wDeku&Nüsse%c? Ich habe mal gesehen daß&man damit %rKrabbelminen %cdetonieren&kann!", "%cTu es sûr d'utiliser tes %wNoix Mojo &%ccorrectement? J'en ai déjà vu&exploser des %rChoux-Péteurs%c!" }, { "%cYou might end up with an %wextra&key %cfor the %bWater Temple %cor the&%rFire Temple%c. It's for your safety!", @@ -4221,7 +4221,7 @@ CustomMessageMinimal NaviMessages[NUM_NAVI_MESSAGES] = { "%cMême un adulte ne peut pas pousser&de grands blocs sans un petit %wgain&de force%c!" }, { "%cI've heard that %rFlare Dancer&%cis weak to the %wMaster Sword%c!&Have you tried it?", - "%cIch habe gehört dass der&%rFlammenderwisch %ceine Schwäche für&das %wMasterschwert %caufweist. Hast du&es schonmal versucht einzusetzen?", + "%cIch habe gehört daß der&%rFlammenderwisch %ceine Schwäche für&das %wMasterschwert %caufweist. Hast du&es schonmal versucht einzusetzen?", "%cJ'ai entendu dire que les %rDanse-&Flammes %csont faîbles face à l'%wÉpée de&Légende%c! Est-ce que tu as essayé?" }, { "%cDon't have a weapon to kill a&%rspider%c? Try throwing a %wpot&%cat it!", @@ -4229,8 +4229,16 @@ CustomMessageMinimal NaviMessages[NUM_NAVI_MESSAGES] = { "%cSi tu n'as pas d'arme pour tuer&une %raraignée%c, pourquoi n'essayerais&-tu pas de lui jetter une %wjarre&%cà la figure?" }, { "%cI hear the patch of %wsoft soil&%cin %bZora's River %cis the only one&that isn't home to a %rspider%c!", - "%cIch habe gehört dass die Stelle&%wfeuchten Bodens %cim %bZora-Fluss %cals&einzige keine %rSkulltula %cbeherbergt.", + "%cIch habe gehört daß die Stelle&%wfeuchten Bodens %cim %bZora-Fluß %cals&einzige keine %rSkulltula %cbeherbergt.", "%cJ'ai entendu dire que la %wterre meuble&%cqui se trouve à la %bRivière Zora %cest&la seule qui ne contienne pas&d'%raraignée%c." }, + + { "%cThe people of Hyrule sometimes&have %witems %cfor you, but they won't&like it if you're %wwearing a mask%c!", + "%cDie Bewohner Hyrules haben manchmal&%wGegenstände %cfür dich, aber Sie mögen&es nicht wenn du %wMasken trägst%c!", + "%cF16" }, + + { "%cIf you get trapped somewhere, you&might have to %wsave your game %cand&reset%c!", + "%cSolltest du irgendwo eingeschloßen&sein, mußt du vielleicht dein %wSpiel&speichern %cund neustarten!", + "%cF17" }, }; void CreateNaviRandoMessages() { diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 2c87a5b03..a9087933c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -8,7 +8,7 @@ #include #include -#define NUM_NAVI_MESSAGES 15 +#define NUM_NAVI_MESSAGES 17 class Randomizer { private: From b803c77f58c590ee401a896dcae0c972bfa0d748 Mon Sep 17 00:00:00 2001 From: Sarge-117 Date: Tue, 30 Aug 2022 14:22:02 -0700 Subject: [PATCH 02/20] Add French translation Thanks to PurpleHato --- soh/soh/Enhancements/randomizer/randomizer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index d12db3552..50863b459 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4234,11 +4234,11 @@ CustomMessageMinimal NaviMessages[NUM_NAVI_MESSAGES] = { { "%cThe people of Hyrule sometimes&have %witems %cfor you, but they won't&like it if you're %wwearing a mask%c!", "%cDie Bewohner Hyrules haben manchmal&%wGegenstände %cfür dich, aber Sie mögen&es nicht wenn du %wMasken trägst%c!", - "%cF16" }, + "%cIl se peut que les habitants d'Hyrule&aient des %wobjets %cpour toi. Par contre,&ils risquent de ne pas trop apprécier&le fait que tu %wportes un masque%c!" }, - { "%cIf you get trapped somewhere, you&might have to %wsave your game %cand&reset%c!", - "%cSolltest du irgendwo eingeschloßen&sein, mußt du vielleicht dein %wSpiel&speichern %cund neustarten!", - "%cF17" }, + { "%cIf you get trapped somewhere, you&might have to %wsave your game %cand&%wreset%c!", + "%cSolltest du irgendwo eingeschloßen&sein, mußt du vielleicht dein %wSpiel&speichern %cund %wneustarten%c!", + "%cSi tu es coincé quelque part, tu&devrais %wsauvegarder ta partie %cet&faire un %wreset%c!" }, }; void CreateNaviRandoMessages() { From 55fa913c782cc052145694fb4f550f74b6ec5fa6 Mon Sep 17 00:00:00 2001 From: Sarge-117 Date: Tue, 30 Aug 2022 15:24:44 -0700 Subject: [PATCH 03/20] Couple more Just need German for these Co-Authored-By: PurpleHato <47987542+PurpleHato@users.noreply.github.com> --- soh/soh/Enhancements/randomizer/randomizer.cpp | 8 ++++++++ soh/soh/Enhancements/randomizer/randomizer.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 0933fccc7..2dfaf97a9 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4368,6 +4368,14 @@ CustomMessageMinimal NaviMessages[NUM_NAVI_MESSAGES] = { { "%cIf you get trapped somewhere, you&might have to %wsave your game %cand&%wreset%c!", "%cSolltest du irgendwo eingeschloßen&sein, mußt du vielleicht dein %wSpiel&speichern %cund %wneustarten%c!", "%cSi tu es coincé quelque part, tu&devrais %wsauvegarder ta partie %cet&faire un %wreset%c!" }, + + { "%cSheik will meet you in a %rburning&village %conce you have %gForest%c,&%rFire%c, and %bWater %cMedallions!", + "%cG18", + "%cSheik t'attendra dans un %rvillage&en feu %clorsque tu auras récupéré&les médaillons de la %gForêt%c, du %rFeu&%cet de l'%bEau%c!" }, + + { "%cIf you don't have a %wsword %cas a&child, try buying %wDeku Sticks%c!&They're effective against your foes!", + "%cG19", + "%cSi tu n'as pas d'%wépée %cen tant&qu'enfant, pourquoi n'irais-tu pas&acheter quelques %wBâtons Mojo%c? Ils&sont efficaces contre tes ennemis!" } }; void CreateNaviRandoMessages() { diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index a9087933c..17fd39f3d 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -8,7 +8,7 @@ #include #include -#define NUM_NAVI_MESSAGES 17 +#define NUM_NAVI_MESSAGES 19 class Randomizer { private: From 75e5330263d1e250a562de414ea81a7214cdf9b2 Mon Sep 17 00:00:00 2001 From: Sarge-117 Date: Wed, 31 Aug 2022 17:23:16 -0700 Subject: [PATCH 04/20] Add German --- soh/soh/Enhancements/randomizer/randomizer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 2dfaf97a9..605cfc374 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4370,11 +4370,11 @@ CustomMessageMinimal NaviMessages[NUM_NAVI_MESSAGES] = { "%cSi tu es coincé quelque part, tu&devrais %wsauvegarder ta partie %cet&faire un %wreset%c!" }, { "%cSheik will meet you in a %rburning&village %conce you have %gForest%c,&%rFire%c, and %bWater %cMedallions!", - "%cG18", + "%cSheik wird dich in einem %rbrennenden&Dorf %ctreffen sobald du das Amulett&des %gWaldes%c, %rFeuers %cund %bWassers&%cbesitzt.", "%cSheik t'attendra dans un %rvillage&en feu %clorsque tu auras récupéré&les médaillons de la %gForêt%c, du %rFeu&%cet de l'%bEau%c!" }, { "%cIf you don't have a %wsword %cas a&child, try buying %wDeku Sticks%c!&They're effective against your foes!", - "%cG19", + "%cSolltest du als Kind kein %wSchwert&%cbesitzen, empfehle ich %wDeku Stäbe&%czu kaufen! Diese sind effektiv gegen&Widersacher!", "%cSi tu n'as pas d'%wépée %cen tant&qu'enfant, pourquoi n'irais-tu pas&acheter quelques %wBâtons Mojo%c? Ils&sont efficaces contre tes ennemis!" } }; From 64aca784507fdcebd81e216ea3489739550d6a1a Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Fri, 2 Sep 2022 13:19:12 -0400 Subject: [PATCH 05/20] Fixes Switch/Wii U crashes with Wonder Rupees and Bottleable Entities (#1360) * Reorders switch statement to prevent some code that shouldn't execute. * Potentially fixes bottleable entities crash * Solves lack of ItemEntry for GI_MAX * Adds comment clarifying new GetItemEntry --- soh/soh/OTRGlobals.cpp | 3 ++- soh/soh/OTRGlobals.h | 1 - soh/soh/z_play_otr.cpp | 1 - soh/src/code/z_en_item00.c | 10 +++++----- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index cdab324d4..66aa22868 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -289,6 +289,7 @@ extern "C" void VanillaItemTable_Init() { GET_ITEM(ITEM_BULLET_BAG_50, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG_50, 0x6C, 0x80, CHEST_ANIM_LONG, MOD_NONE, GI_BULLET_BAG_50), GET_ITEM_NONE, GET_ITEM_NONE, + GET_ITEM_NONE // GI_MAX - if you need to add to this table insert it before this entry. }; ItemTableManager::Instance->AddItemTable(MOD_NONE); for (uint8_t i = 0; i < ARRAY_COUNT(getItemTable); i++) { @@ -1613,7 +1614,7 @@ extern "C" CustomMessageEntry Randomizer_GetHintFromCheck(RandomizerCheck check) } extern "C" GetItemEntry ItemTable_Retrieve(int16_t getItemID) { - GetItemEntry giEntry = ItemTableManager::Instance->RetrieveItemEntry(OTRGlobals::Instance->getItemModIndex, getItemID); + GetItemEntry giEntry = ItemTableManager::Instance->RetrieveItemEntry(MOD_NONE, getItemID); return giEntry; } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 089394e33..4858c41b2 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -21,7 +21,6 @@ public: std::shared_ptr context; std::shared_ptr gSaveStateMgr; std::shared_ptr gRandomizer; - uint16_t getItemModIndex; OTRGlobals(); ~OTRGlobals(); diff --git a/soh/soh/z_play_otr.cpp b/soh/soh/z_play_otr.cpp index d0137644c..1a07ceb7e 100644 --- a/soh/soh/z_play_otr.cpp +++ b/soh/soh/z_play_otr.cpp @@ -60,7 +60,6 @@ void OTRGameplay_InitScene(GlobalContext* globalCtx, s32 spawn) { globalCtx->cUpElfMsgs = nullptr; globalCtx->setupPathList = nullptr; globalCtx->numSetupActors = 0; - OTRGlobals::Instance->getItemModIndex = MOD_NONE; Object_InitBank(globalCtx, &globalCtx->objectCtx); LightContext_Init(globalCtx, &globalCtx->lightCtx); TransitionActor_InitContext(&globalCtx->state, &globalCtx->transiActorCtx); diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 54beafdab..899984b89 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -515,13 +515,13 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) { } if (!Actor_HasParent(&this->actor, globalCtx)) { - if (!gSaveContext.n64ddFlag) { - if (getItemId != GI_NONE) { + if (getItemId != GI_NONE) { + if (!gSaveContext.n64ddFlag) { func_8002F554(&this->actor, globalCtx, getItemId); + } else { + getItem = Randomizer_GetRandomizedItem(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); + GiveItemEntryFromActorWithFixedRange(&this->actor, globalCtx, getItem); } - } else { - getItem = Randomizer_GetRandomizedItem(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); - GiveItemEntryFromActorWithFixedRange(&this->actor, globalCtx, getItem); } } From 0ce0ab1260dd24ac6168d1cdd28d60f21554cd86 Mon Sep 17 00:00:00 2001 From: David Chavez Date: Sat, 3 Sep 2022 06:00:04 +0200 Subject: [PATCH 06/20] Phase 1: Separate ImGui Drawing From LUS (#1310) * Update LUS imported paths * Introduce GameMenuBar * Fix imports after LUS import paths change * Move Randomizer * Replace needs_save * Migrate Developer Tools * Migrate Cheats * Migrate Enhancements * Separate UIWidgets * Add missing Hooks.cpp file * Migrate Settings * Remove UI methods from LUS * Cleanup imports and exposed properties * Cleanup more methods * Fix project generation * Fix CI compilation * Remove resolved TODO --- libultraship/libultraship/CMakeLists.txt | 1 + libultraship/libultraship/GameOverlay.cpp | 18 +- libultraship/libultraship/ImGuiImpl.cpp | 2119 ++--------------- libultraship/libultraship/ImGuiImpl.h | 87 +- .../include/spdlog/sinks/sohconsole_sink.h | 6 +- libultraship/libultraship/Window.cpp | 2 +- soh/CMakeLists.txt | 14 +- soh/include/global.h | 2 +- soh/include/macros.h | 2 +- soh/include/z64.h | 2 +- soh/include/z64audio.h | 6 +- soh/include/z64effect.h | 2 +- soh/include/z64light.h | 2 +- soh/include/z64transition.h | 2 +- .../controls/GameControlEditor.cpp | 50 +- .../cosmetics/CosmeticsEditor.cpp | 201 +- .../Enhancements/cosmetics/CosmeticsEditor.h | 4 +- soh/soh/Enhancements/debugconsole.cpp | 108 +- .../Enhancements/debugger/ImGuiHelpers.cpp | 22 - soh/soh/Enhancements/debugger/ImGuiHelpers.h | 8 - soh/soh/Enhancements/debugger/actorViewer.cpp | 16 +- soh/soh/Enhancements/debugger/colViewer.cpp | 50 +- .../Enhancements/debugger/debugSaveEditor.cpp | 158 +- soh/soh/Enhancements/gameconsole.h | 4 +- .../randomizer/3drando/entrance.cpp | 2 +- .../Enhancements/randomizer/3drando/fill.cpp | 2 +- .../Enhancements/randomizer/3drando/hints.cpp | 2 +- .../randomizer/3drando/item_location.cpp | 4 +- .../randomizer/3drando/item_pool.cpp | 2 +- .../Enhancements/randomizer/3drando/menu.cpp | 6 +- .../randomizer/3drando/rando_main.cpp | 8 +- .../randomizer/3drando/spoiler_log.cpp | 6 +- .../Enhancements/randomizer/randomizer.cpp | 222 +- .../randomizer/randomizer_item_tracker.cpp | 33 +- soh/soh/Enhancements/savestates.cpp | 14 +- soh/soh/GameMenuBar.cpp | 1367 +++++++++++ soh/soh/GameMenuBar.hpp | 27 + soh/soh/OTRGlobals.cpp | 52 +- soh/soh/OTRGlobals.h | 2 +- soh/soh/SaveManager.cpp | 4 +- soh/soh/SaveManager.h | 2 +- soh/soh/UIWidgets.cpp | 523 ++++ soh/soh/UIWidgets.hpp | 49 + soh/soh/frame_interpolation.cpp | 2 +- soh/soh/z_message_OTR.cpp | 12 +- soh/soh/z_play_otr.cpp | 12 +- soh/soh/z_scene_otr.cpp | 20 +- soh/src/code/audio_playback.c | 2 +- soh/src/code/audio_synthesis.c | 2 +- soh/src/code/code_800F9280.c | 4 +- soh/src/code/z_play.c | 2 +- .../overlays/gamestates/ovl_title/z_title.c | 2 +- 52 files changed, 2719 insertions(+), 2552 deletions(-) delete mode 100644 soh/soh/Enhancements/debugger/ImGuiHelpers.cpp delete mode 100644 soh/soh/Enhancements/debugger/ImGuiHelpers.h create mode 100644 soh/soh/GameMenuBar.cpp create mode 100644 soh/soh/GameMenuBar.hpp create mode 100644 soh/soh/UIWidgets.cpp create mode 100644 soh/soh/UIWidgets.hpp diff --git a/libultraship/libultraship/CMakeLists.txt b/libultraship/libultraship/CMakeLists.txt index aec229bfb..d2b35a1f8 100644 --- a/libultraship/libultraship/CMakeLists.txt +++ b/libultraship/libultraship/CMakeLists.txt @@ -121,6 +121,7 @@ set(Source_Files__CustomImpl source_group("Source Files\\CustomImpl" FILES ${Source_Files__CustomImpl}) set(Source_Files__CustomImpl__Hooks + "Hooks.cpp" "Hooks.h" ) source_group("Source Files\\CustomImpl\\Hooks" FILES ${Source_Files__CustomImpl__Hooks}) diff --git a/libultraship/libultraship/GameOverlay.cpp b/libultraship/libultraship/GameOverlay.cpp index b5225e22e..a331c5cf6 100644 --- a/libultraship/libultraship/GameOverlay.cpp +++ b/libultraship/libultraship/GameOverlay.cpp @@ -16,28 +16,28 @@ namespace Ship { if (CVar_Get(args[2].c_str()) != nullptr) { const char* key = args[2].c_str(); - GameOverlay* overlay = SohImGui::overlay; + GameOverlay* overlay = SohImGui::GetGameOverlay(); if (args[1] == "add") { if (!overlay->RegisteredOverlays.contains(key)) { overlay->RegisteredOverlays[key] = new Overlay({ OverlayType::TEXT, ImStrdup(key), -1.0f }); - SohImGui::console->SendInfoMessage("Added overlay: %s", key); + SohImGui::GetConsole()->SendInfoMessage("Added overlay: %s", key); } else { - SohImGui::console->SendErrorMessage("Overlay already exists: %s", key); + SohImGui::GetConsole()->SendErrorMessage("Overlay already exists: %s", key); } } else if (args[1] == "remove") { if (overlay->RegisteredOverlays.contains(key)) { overlay->RegisteredOverlays.erase(key); - SohImGui::console->SendInfoMessage("Removed overlay: %s", key); + SohImGui::GetConsole()->SendInfoMessage("Removed overlay: %s", key); } else { - SohImGui::console->SendErrorMessage("Overlay not found: %s", key); + SohImGui::GetConsole()->SendErrorMessage("Overlay not found: %s", key); } } } else { - SohImGui::console->SendErrorMessage("CVar {} does not exist", args[2].c_str()); + SohImGui::GetConsole()->SendErrorMessage("CVar {} does not exist", args[2].c_str()); } return CMD_SUCCESS; @@ -124,7 +124,7 @@ namespace Ship { else text_display_end = text_end; - GameOverlay* overlay = SohImGui::overlay; + GameOverlay* overlay = SohImGui::GetGameOverlay(); ImFont* font = overlay->CurrentFont == "Default" ? g.Font : overlay->Fonts[overlay->CurrentFont]; const float font_size = font->FontSize; @@ -157,7 +157,7 @@ namespace Ship { } } - SohImGui::console->AddCommand("overlay", { OverlayCommand, "Draw an overlay using a cvar value" }); + SohImGui::GetConsole()->AddCommand("overlay", { OverlayCommand, "Draw an overlay using a cvar value" }); } void GameOverlay::DrawSettings() { @@ -167,7 +167,7 @@ namespace Ship { if (ImGui::Selectable(name.c_str(), name == this->CurrentFont)) { this->CurrentFont = name; CVar_SetString("gOverlayFont", ImStrdup(name.c_str())); - SohImGui::needs_save = true; + SohImGui::RequestCvarSaveOnNextTick(); } } diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index ed3287a5c..a8901b5a6 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -7,13 +7,6 @@ #include #include -#include -#include -#include -#include -#include -#include "../../soh/include/z64audio.h" -#include "Archive.h" #include "Console.h" #include "Hooks.h" #define IMGUI_DEFINE_MATH_OPERATORS @@ -27,7 +20,6 @@ #include "Lib/stb/stb_image.h" #include "Lib/Fast3D/gfx_rendering_api.h" #include "Lib/spdlog/include/spdlog/common.h" -#include "UltraController.h" #ifdef __WIIU__ #include // GX2SetViewport / GX2SetScissor @@ -69,12 +61,8 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPAR using namespace Ship; bool oldCursorState = true; -#define EXPERIMENTAL() \ - ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 50, 50, 255)); \ - InsertPadding(3.0f); \ - ImGui::Text("Experimental"); \ - ImGui::PopStyleColor(); \ - PaddedSeparator(false, true); +#define BindButton(btn, status) ImGui::Image(GetTextureByID(DefaultAssets[btn]->textureId), ImVec2(16.0f * scale, 16.0f * scale), ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, (status) ? 255 : 0)); + #define TOGGLE_BTN ImGuiKey_F1 #define TOGGLE_PAD_BTN ImGuiKey_GamepadBack #define HOOK(b) if(b) needs_save = true; @@ -83,21 +71,6 @@ OSContPad* pads; std::map DefaultAssets; std::vector emptyArgs; -bool isBetaQuestEnabled = false; - -enum SeqPlayers { - /* 0 */ SEQ_BGM_MAIN, - /* 1 */ SEQ_FANFARE, - /* 2 */ SEQ_SFX, - /* 3 */ SEQ_BGM_SUB, - /* 4 */ SEQ_MAX -}; - -extern "C" { - void enableBetaQuest() { isBetaQuestEnabled = true; } - void disableBetaQuest() { isBetaQuestEnabled = false; } -} - namespace SohImGui { WindowImpl impl; @@ -106,7 +79,10 @@ namespace SohImGui { GameOverlay* overlay = new GameOverlay; InputEditor* controller = new InputEditor; static ImVector s_GroupPanelLabelStack; - bool p_open = false; + + std::function clientDrawMenu; + std::function clientSetupHooks; + bool needs_save = false; int lastBackendID = 0; bool statsWindowOpen; @@ -132,32 +108,12 @@ namespace SohImGui { #endif }; - - const char* powers[9] = { - "Vanilla (1x)", - "Double (2x)", - "Quadruple (4x)", - "Octuple (8x)", - "Hexadecuple (16x)", - "Duotrigintuple (32x)", - "Quattuorsexagintuple (64x)", - "Octoviginticentuple (128x)", - "Hexaquinquagintiducentuple (256x)" - }; - std::map> hiddenwindowCategories; std::map> windowCategories; std::map customWindows; - void UpdateAudio() { - Audio_SetGameVolume(SEQ_BGM_MAIN, CVar_GetFloat("gMainMusicVolume", 1)); - Audio_SetGameVolume(SEQ_BGM_SUB, CVar_GetFloat("gSubMusicVolume", 1)); - Audio_SetGameVolume(SEQ_FANFARE, CVar_GetFloat("gSFXMusicVolume", 1)); - Audio_SetGameVolume(SEQ_SFX, CVar_GetFloat("gFanfareVolume", 1)); - } - void InitSettings() { - Ship::RegisterHook(UpdateAudio); + clientSetupHooks(); Ship::RegisterHook([] { gfx_get_current_rendering_api()->set_texture_filter((FilteringMode)CVar_GetS32("gTextureFilter", FILTER_THREE_POINT)); if (CVar_GetS32("gConsoleEnabled", 0)) { @@ -171,8 +127,6 @@ namespace SohImGui { } else { controller->Close(); } - - UpdateAudio(); }); } @@ -191,16 +145,6 @@ namespace SohImGui { return 0; } - int ClampFloatToInt(float value, int min, int max) { - return fmin(fmax(value, min), max); - } - - void Tooltip(const char* text) { - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("%s", BreakTooltip(text, 60).c_str()); - } - } - void ImGuiWMInit() { switch (impl.backend) { #ifdef __WIIU__ @@ -352,26 +296,6 @@ namespace SohImGui { } } - void ShowCursor(bool hide, Dialogues d) { - if (d == Dialogues::dLoadSettings) { - Window::GetInstance()->ShowCursor(hide); - return; - } - - if (d == Dialogues::dConsole && CVar_GetS32("gOpenMenuBar", 0)) { - return; - } - if (!Window::GetInstance()->IsFullscreen()) { - oldCursorState = false; - return; - } - - if (oldCursorState != hide) { - oldCursorState = hide; - Window::GetInstance()->ShowCursor(hide); - } - } - void LoadTexture(const std::string& name, const std::string& path) { GfxRenderingAPI* api = gfx_get_current_rendering_api(); const auto res = Window::GetInstance()->GetResourceManager()->LoadFile(path); @@ -392,65 +316,7 @@ namespace SohImGui { stbi_image_free(img_data); } - void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha) - { - Color_RGBA8 defaultColors; - defaultColors.r = default_colors.x; - defaultColors.g = default_colors.y; - defaultColors.b = default_colors.z; - defaultColors.a = default_colors.w; - - Color_RGBA8 cvarColor = CVar_GetRGBA(cvarname, defaultColors); - - ColorArray.x = cvarColor.r / 255.0; - ColorArray.y = cvarColor.g / 255.0; - ColorArray.z = cvarColor.b / 255.0; - ColorArray.w = cvarColor.a / 255.0; - } - - void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint) { - GfxRenderingAPI* api = gfx_get_current_rendering_api(); - const auto res = static_cast(Window::GetInstance()->GetResourceManager()->LoadResource(path).get()); - - std::vector texBuffer; - texBuffer.reserve(res->width * res->height * 4); - - switch (res->texType) { - case Ship::TextureType::RGBA32bpp: - texBuffer.assign(res->imageData, res->imageData + (res->width * res->height * 4)); - break; - case Ship::TextureType::GrayscaleAlpha8bpp: - for (int32_t i = 0; i < res->width * res->height; i++) { - uint8_t ia = res->imageData[i]; - uint8_t color = ((ia >> 4) & 0xF) * 255 / 15; - uint8_t alpha = (ia & 0xF) * 255 / 15; - texBuffer.push_back(color); - texBuffer.push_back(color); - texBuffer.push_back(color); - texBuffer.push_back(alpha); - } - break; - default: - // TODO convert other image types - SPDLOG_WARN("SohImGui::LoadResource: Attempting to load unsupporting image type %s", path.c_str()); - return; - } - - for (size_t pixel = 0; pixel < texBuffer.size() / 4; pixel++) { - texBuffer[pixel * 4 + 0] *= tint.x; - texBuffer[pixel * 4 + 1] *= tint.y; - texBuffer[pixel * 4 + 2] *= tint.z; - texBuffer[pixel * 4 + 3] *= tint.w; - } - - const auto asset = new GameAsset{ api->new_texture() }; - - api->select_texture(0, asset->textureId); - api->set_sampler_parameters(0, false, 0, 0); - api->upload_texture(texBuffer.data(), res->width, res->height); - - DefaultAssets[name] = asset; - } + // MARK: - Public API void Init(WindowImpl window_impl) { CVar_Load(); @@ -549,427 +415,6 @@ namespace SohImGui { ImGuiProcessEvent(event); } -#define BindButton(btn, status) ImGui::Image(GetTextureByID(DefaultAssets[btn]->textureId), ImVec2(16.0f * scale, 16.0f * scale), ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, (status) ? 255 : 0)); - - void BindAudioSlider(const char* name, const char* key, float defaultValue, SeqPlayers playerId) - { - float value = CVar_GetFloat(key, defaultValue); - - ImGui::Text(name, static_cast(100 * value)); - if (ImGui::SliderFloat((std::string("##") + key).c_str(), &value, 0.0f, 1.0f, "")) { - const float volume = floorf(value * 100) / 100; - CVar_SetFloat(key, volume); - needs_save = true; - Audio_SetGameVolume(playerId, volume); - } - } - - void EnhancementCombobox(const char* name, const char* ComboArray[], size_t arraySize, uint8_t FirstTimeValue = 0) { - if (FirstTimeValue <= 0) { - FirstTimeValue = 0; - } - uint8_t selected = CVar_GetS32(name, FirstTimeValue); - uint8_t DefaultValue = selected; - std::string comboName = std::string("##") + std::string(name); - if (ImGui::BeginCombo(comboName.c_str(), ComboArray[DefaultValue])) { - for (uint8_t i = 0; i < arraySize; i++) { - if (strlen(ComboArray[i]) > 1) { - if (ImGui::Selectable(ComboArray[i], i == selected)) { - CVar_SetS32(name, i); - selected = i; - needs_save = true; - } - } - } - ImGui::EndCombo(); - } - } - - void EnhancementRadioButton(const char* text, const char* cvarName, int id) { - /*Usage : - EnhancementRadioButton("My Visible Name","gMyCVarName", MyID); - First arg is the visible name of the Radio button - Second is the cvar name where MyID will be saved. - Note: the CVar name should be the same to each Buddies. - Example : - EnhancementRadioButton("English", "gLanguages", 0); - EnhancementRadioButton("German", "gLanguages", 1); - EnhancementRadioButton("French", "gLanguages", 2); - */ - std::string make_invisible = "##"; - make_invisible += text; - make_invisible += cvarName; - - int val = CVar_GetS32(cvarName, 0); - if (ImGui::RadioButton(make_invisible.c_str(), id == val)) { - CVar_SetS32(cvarName, id); - needs_save = true; - } - ImGui::SameLine(); - ImGui::Text("%s", text); - } - - void RenderCross(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz) - { - float thickness = ImMax(sz / 5.0f, 1.0f); - sz -= thickness * 0.5f; - pos += ImVec2(thickness * 0.25f, thickness * 0.25f); - - draw_list->PathLineTo(ImVec2(pos.x, pos.y)); - draw_list->PathLineTo(ImVec2(pos.x + sz, pos.y + sz)); - draw_list->PathStroke(col, 0, thickness); - - draw_list->PathLineTo(ImVec2(pos.x + sz, pos.y)); - draw_list->PathLineTo(ImVec2(pos.x, pos.y + sz)); - draw_list->PathStroke(col, 0, thickness); - } - - bool CustomCheckbox(const char* label, bool* v, bool disabled, ImGuiCheckboxGraphics disabledGraphic) { - ImGuiWindow* window = ImGui::GetCurrentWindow(); - if (window->SkipItems) - return false; - - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); - - const float square_sz = ImGui::GetFrameHeight(); - const ImVec2 pos = window->DC.CursorPos; - const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f)); - ImGui::ItemSize(total_bb, style.FramePadding.y); - if (!ImGui::ItemAdd(total_bb, id)) - { - IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0)); - return false; - } - - bool hovered, held; - bool pressed = ImGui::ButtonBehavior(total_bb, id, &hovered, &held); - if (pressed) - { - *v = !(*v); - ImGui::MarkItemEdited(id); - } - - const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz)); - ImGui::RenderNavHighlight(total_bb, id); - ImGui::RenderFrame(check_bb.Min, check_bb.Max, ImGui::GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); - ImU32 check_col = ImGui::GetColorU32(ImGuiCol_CheckMark); - ImU32 cross_col = ImGui::GetColorU32(ImVec4(0.50f, 0.50f, 0.50f, 1.00f)); - bool mixed_value = (g.LastItemData.InFlags & ImGuiItemFlags_MixedValue) != 0; - if (mixed_value) - { - // Undocumented tristate/mixed/indeterminate checkbox (#2644) - // This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox) - ImVec2 pad(ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)), ImMax(1.0f, IM_FLOOR(square_sz / 3.6f))); - window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding); - } - else if ((!disabled && *v) || (disabled && disabledGraphic == ImGuiCheckboxGraphics::Checkmark)) - { - const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f)); - ImGui::RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f); - } - else if (disabled && disabledGraphic == ImGuiCheckboxGraphics::Cross) { - const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f)); - RenderCross(window->DrawList, check_bb.Min + ImVec2(pad, pad), cross_col, square_sz - pad * 2.0f); - } - - ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y); - if (g.LogEnabled) - ImGui::LogRenderedText(&label_pos, mixed_value ? "[~]" : *v ? "[x]" : "[ ]"); - if (label_size.x > 0.0f) - ImGui::RenderText(label_pos, label); - - IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0)); - return pressed; - } - - void EnhancementCheckbox(const char* text, const char* cvarName, bool disabled, const char* disabledTooltipText, ImGuiCheckboxGraphics disabledGraphic) - { - if (disabled) { - ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); - ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); - } - bool val = (bool)CVar_GetS32(cvarName, 0); - if (CustomCheckbox(text, &val, disabled, disabledGraphic)) { - CVar_SetS32(cvarName, val); - needs_save = true; - } - - if (disabled) { - ImGui::PopStyleVar(1); - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && disabledTooltipText != "") { - ImGui::SetTooltip("%s", disabledTooltipText); - } - ImGui::PopItemFlag(); - } - } - - void EnhancementButton(const char* text, const char* cvarName) - { - bool val = (bool)CVar_GetS32(cvarName, 0); - if (ImGui::Button(text)) { - CVar_SetS32(cvarName, !val); - CVar_SetS32(cvarName, !val); - needs_save = true; - } - } - - void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue, bool PlusMinusButton) - { - int val = CVar_GetS32(cvarName, defaultValue); - ImGui::Text(text, val); - if(PlusMinusButton) { - std::string MinusBTNName = " - ##"; - MinusBTNName += cvarName; - if (ImGui::Button(MinusBTNName.c_str())) { - val--; - CVar_SetS32(cvarName, val); - needs_save = true; - } - ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); - } - - if (ImGui::SliderInt(id, &val, min, max, format)) - { - CVar_SetS32(cvarName, val); - needs_save = true; - } - - if(PlusMinusButton) { - std::string PlusBTNName = " + ##"; - PlusBTNName += cvarName; - ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); - if (ImGui::Button(PlusBTNName.c_str())) { - val++; - CVar_SetS32(cvarName, val); - needs_save = true; - } - } - - if (val < min) - { - val = min; - CVar_SetS32(cvarName, val); - needs_save = true; - } - - if (val > max) - { - val = max; - CVar_SetS32(cvarName, val); - needs_save = true; - } - } - - void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton) - { - float val = CVar_GetFloat(cvarName, defaultValue); - - if (!isPercentage) - ImGui::Text(text, val); - else - ImGui::Text(text, static_cast(100 * val)); - - InsertPadding(); - - if(PlusMinusButton) { - std::string MinusBTNName = " - ##"; - MinusBTNName += cvarName; - if (ImGui::Button(MinusBTNName.c_str())) { - if (!isPercentage) - val -= 0.1f; - else - val -= 0.01f; - CVar_SetFloat(cvarName, val); - needs_save = true; - } - ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); - } - if (PlusMinusButton) { - #ifdef __WIIU__ - ImGui::PushItemWidth(ImGui::GetWindowSize().x - 79.0f * 2); - #else - ImGui::PushItemWidth(ImGui::GetWindowSize().x - 79.0f); - #endif - } - if (ImGui::SliderFloat(id, &val, min, max, format)) - { - CVar_SetFloat(cvarName, val); - needs_save = true; - } - if (PlusMinusButton) { - ImGui::PopItemWidth(); - } - if(PlusMinusButton) { - std::string PlusBTNName = " + ##"; - PlusBTNName += cvarName; - ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); - if (ImGui::Button(PlusBTNName.c_str())) { - if (!isPercentage) - val += 0.1f; - else - val += 0.01f; - CVar_SetFloat(cvarName, val); - needs_save = true; - } - } - - if (val < min) - { - val = min; - CVar_SetFloat(cvarName, val); - needs_save = true; - } - - if (val > max) - { - val = max; - CVar_SetFloat(cvarName, val); - needs_save = true; - } - } - - void EnhancementCombo(const std::string& name, const char* cvarName, const std::vector& items, int defaultValue) { - - if (ImGui::BeginCombo(name.c_str(), items[static_cast(CVar_GetS32(cvarName, defaultValue))].c_str())) { - for (int settingIndex = 0; settingIndex < (int) items.size(); settingIndex++) { - if (ImGui::Selectable(items[settingIndex].c_str())) { - CVar_SetS32(cvarName, settingIndex); - needs_save = true; - - } - } - ImGui::EndCombo(); - } - } - - void RandomizeColor(const char* cvarName, ImVec4* colors) { - Color_RGBA8 NewColors = {0,0,0,255}; - std::string Cvar_RBM = cvarName; - Cvar_RBM += "RBM"; - std::string MakeInvisible = "##"; - MakeInvisible += cvarName; - MakeInvisible += "Random"; - std::string FullName = "Random"; - FullName += MakeInvisible; - if (ImGui::Button(FullName.c_str())) { - s16 RND_R = rand() % (255 - 0); - s16 RND_G = rand() % (255 - 0); - s16 RND_B = rand() % (255 - 0); - colors->x = (float)RND_R / 255; - colors->y = (float)RND_G / 255; - colors->z = (float)RND_B / 255; - NewColors.r = ClampFloatToInt(colors->x * 255, 0, 255); - NewColors.g = ClampFloatToInt(colors->y * 255, 0, 255); - NewColors.b = ClampFloatToInt(colors->z * 255, 0, 255); - CVar_SetRGBA(cvarName, NewColors); - CVar_SetS32(Cvar_RBM.c_str(), 0); //On click disable rainbow mode. - needs_save = true; - } - Tooltip("Chooses a random color\nOverwrites previously chosen color"); - } - - void RainbowColor(const char* cvarName, ImVec4* colors) { - std::string Cvar_RBM = cvarName; - Cvar_RBM += "RBM"; - std::string MakeInvisible = "Rainbow"; - MakeInvisible += "##"; - MakeInvisible += cvarName; - MakeInvisible += "Rainbow"; - - EnhancementCheckbox(MakeInvisible.c_str(), Cvar_RBM.c_str()); - Tooltip("Cycles through colors on a timer\nOverwrites previously chosen color"); - } - - void ResetColor(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha) { - std::string Cvar_RBM = cvarName; - Cvar_RBM += "RBM"; - std::string MakeInvisible = "Reset"; - MakeInvisible += "##"; - MakeInvisible += cvarName; - MakeInvisible += "Reset"; - if (ImGui::Button(MakeInvisible.c_str())) { - colors->x = defaultcolors.x; - colors->y = defaultcolors.y; - colors->z = defaultcolors.z; - if (has_alpha) { colors->w = defaultcolors.w; }; - - Color_RGBA8 colorsRGBA; - colorsRGBA.r = defaultcolors.x; - colorsRGBA.g = defaultcolors.y; - colorsRGBA.b = defaultcolors.z; - if (has_alpha) { colorsRGBA.a = defaultcolors.w; }; - - CVar_SetRGBA(cvarName, colorsRGBA); - CVar_SetS32(Cvar_RBM.c_str(), 0); //On click disable rainbow mode. - needs_save = true; - } - Tooltip("Revert colors to the game's original colors (GameCube version)\nOverwrites previously chosen color"); - } - - void EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow, bool has_alpha, bool TitleSameLine) { - LoadPickersColors(ColorRGBA, cvarName, default_colors, has_alpha); - - ImGuiColorEditFlags flags = ImGuiColorEditFlags_None; - - if (!TitleSameLine) { - ImGui::Text("%s", text); - flags = ImGuiColorEditFlags_NoLabel; - } - - ImGui::PushID(cvarName); - - if (!has_alpha) { - if (ImGui::ColorEdit3(text, (float*)&ColorRGBA, flags)) - { - Color_RGBA8 colors; - colors.r = ColorRGBA.x * 255.0; - colors.g = ColorRGBA.y * 255.0; - colors.b = ColorRGBA.z * 255.0; - colors.a = ColorRGBA.w * 255.0; - - CVar_SetRGBA(cvarName, colors); - needs_save = true; - } - } - else - { - if (ImGui::ColorEdit4(text, (float*)&ColorRGBA, flags)) - { - Color_RGBA8 colors; - colors.r = ColorRGBA.x / 255; - colors.g = ColorRGBA.y / 255; - colors.b = ColorRGBA.z / 255; - colors.a = ColorRGBA.w / 255; - - CVar_SetRGBA(cvarName, colors); - needs_save = true; - } - } - - ImGui::PopID(); - - //ImGui::SameLine(); // Removing that one to gain some width spacing on the HUD editor - ImGui::PushItemWidth(-FLT_MIN); - ResetColor(cvarName, &ColorRGBA, default_colors, has_alpha); - ImGui::SameLine(); - RandomizeColor(cvarName, &ColorRGBA); - if (allow_rainbow) { - if (ImGui::GetContentRegionAvail().x > 185) { - ImGui::SameLine(); - } - RainbowColor(cvarName, &ColorRGBA); - } - ImGui::NewLine(); - ImGui::PopItemWidth(); - } - void DrawMainMenuAndCalculateGameSize(void) { console->Update(); ImGuiBackendNewFrame(); @@ -1028,13 +473,13 @@ namespace SohImGui { if ((ImGui::IsKeyDown(ImGuiKey_LeftSuper) || ImGui::IsKeyDown(ImGuiKey_RightSuper)) && ImGui::IsKeyPressed(ImGuiKey_R, false)) { - console->Dispatch("reset"); + DispatchConsoleCommand("reset"); } #else if ((ImGui::IsKeyDown(ImGuiKey_LeftCtrl) || ImGui::IsKeyDown(ImGuiKey_RightCtrl)) && ImGui::IsKeyPressed(ImGuiKey_R, false)) { - console->Dispatch("reset"); + DispatchConsoleCommand("reset"); } #endif @@ -1074,921 +519,7 @@ namespace SohImGui { ImGui::SetCursorPosY(0.0f); - if (ImGui::BeginMenu("Settings")) - { - if (ImGui::BeginMenu("Audio")) { - EnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true); - InsertPadding(); - BindAudioSlider("Main Music Volume: %d %%", "gMainMusicVolume", 1.0f, SEQ_BGM_MAIN); - InsertPadding(); - BindAudioSlider("Sub Music Volume: %d %%", "gSubMusicVolume", 1.0f, SEQ_BGM_SUB); - InsertPadding(); - BindAudioSlider("Sound Effects Volume: %d %%", "gSFXMusicVolume", 1.0f, SEQ_SFX); - InsertPadding(); - BindAudioSlider("Fanfare Volume: %d %%", "gFanfareVolume", 1.0f, SEQ_FANFARE); - - ImGui::EndMenu(); - } - - InsertPadding(); - - if (ImGui::BeginMenu("Controller")) { - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2 (12.0f, 6.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0)); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); - ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); - if (ImGui::Button(GetWindowButtonText("Controller Configuration", CVar_GetS32("gControllerConfigurationEnabled", 0)).c_str())) - { - bool currentValue = CVar_GetS32("gControllerConfigurationEnabled", 0); - CVar_SetS32("gControllerConfigurationEnabled", !currentValue); - needs_save = true; - if (CVar_GetS32("gControllerConfigurationEnabled", 0)) { - controller->Open(); - } else { - controller->Close(); - } - } - ImGui::PopStyleColor(1); - ImGui::PopStyleVar(3); - #ifndef __SWITCH__ - PaddedEnhancementCheckbox("Use Controller Navigation", "gControlNav", true, false); - Tooltip("Allows controller navigation of the menu bar\nD-pad to move between items, A to select, and X to grab focus on the menu bar"); - #endif - PaddedEnhancementCheckbox("Show Inputs", "gInputEnabled", true, false); - Tooltip("Shows currently pressed inputs on the bottom right of the screen"); - InsertPadding(); - ImGui::PushItemWidth(ImGui::GetWindowSize().x - 20.0f); - EnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f, false); - Tooltip("Sets the on screen size of the displayed inputs from the Show Inputs setting"); - ImGui::PopItemWidth(); - - ImGui::EndMenu(); - } - - InsertPadding(); - - if (ImGui::BeginMenu("Graphics")) { - #ifndef __APPLE__ - EnhancementSliderFloat("Internal Resolution: %d %%", "##IMul", "gInternalResolution", 0.5f, 2.0f, "", 1.0f, true, true); - Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but effective form of anti-aliasing"); - gfx_current_dimensions.internal_mul = CVar_GetFloat("gInternalResolution", 1); - #endif - #ifndef __WIIU__ - PaddedEnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, "", 1, false, true, false); - Tooltip("Activates multi-sample anti-aliasing when above 1x up to 8x for 8 samples for every pixel"); - gfx_msaa_level = CVar_GetS32("gMSAAValue", 1); - #endif - - if (impl.backend == Backend::DX11) - { - const char* cvar = "gExtraLatencyThreshold"; - int val = CVar_GetS32(cvar, 80); - val = MAX(MIN(val, 360), 0); - int fps = val; - - InsertPadding(); - - if (fps == 0) - { - ImGui::Text("Jitter fix: Off"); - } - else - { - ImGui::Text("Jitter fix: >= %d FPS", fps); - } - - std::string MinusBTNELT = " - ##ExtraLatencyThreshold"; - std::string PlusBTNELT = " + ##ExtraLatencyThreshold"; - if (ImGui::Button(MinusBTNELT.c_str())) { - val--; - CVar_SetS32(cvar, val); - needs_save = true; - } - ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); - ImGui::PushItemWidth(ImGui::GetWindowSize().x - 79.0f); - if (ImGui::SliderInt("##ExtraLatencyThreshold", &val, 0, 360, "", ImGuiSliderFlags_AlwaysClamp)) - { - CVar_SetS32(cvar, val); - needs_save = true; - } - ImGui::PopItemWidth(); - Tooltip("When Interpolation FPS setting is at least this threshold, add one frame of input lag (e.g. 16.6 ms for 60 FPS) in order to avoid jitter. This setting allows the CPU to work on one frame while GPU works on the previous frame.\nThis setting should be used when your computer is too slow to do CPU + GPU work in time."); - - ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); - if (ImGui::Button(PlusBTNELT.c_str())) { - val++; - CVar_SetS32(cvar, val); - needs_save = true; - } - - InsertPadding(); - } - - ImGui::Text("Renderer API (Needs reload)"); - if (ImGui::BeginCombo("##RApi", backends[lastBackendID].second)) { - for (uint8_t i = 0; i < sizeof(backends) / sizeof(backends[0]); i++) { - if (ImGui::Selectable(backends[i].second, i == lastBackendID)) { - pConf->setString("Window.GfxBackend", backends[i].first); - lastBackendID = i; - } - } - ImGui::EndCombo(); - } - - EXPERIMENTAL(); - - ImGui::Text("Texture Filter (Needs reload)"); - EnhancementCombobox("gTextureFilter", filters, 3, 0); - - InsertPadding(); - - overlay->DrawSettings(); - - ImGui::EndMenu(); - } - - InsertPadding(); - - if (ImGui::BeginMenu("Languages")) { - EnhancementRadioButton("English", "gLanguages", 0); - EnhancementRadioButton("German", "gLanguages", 1); - EnhancementRadioButton("French", "gLanguages", 2); - ImGui::EndMenu(); - } - ImGui::EndMenu(); - } - - ImGui::SetCursorPosY(0.0f); - - if (ImGui::BeginMenu("Enhancements")) - { - - const char* enhancementPresets[4] = { "Default", "Vanilla Plus", "Enhanced", "Randomizer"}; - PaddedText("Enhancement Presets", false, true); - SohImGui::EnhancementCombobox("gSelectEnhancementPresets", enhancementPresets, 4, 0); - Tooltip( - "Default - Set all enhancements to their default values. The true vanilla SoH experience.\n" - "\n" - "Vanilla Plus - Adds Quality of Life features that enhance your experience, but don't alter gameplay. Recommended for a first playthrough of OoT.\n" - "\n" - "Enhanced - The \"Vanilla Plus\" preset, but with more quality of life enhancements that might alter gameplay slightly. Recommended for returning players.\n" - "\n" - "Randomizer - The \"Enhanced\" preset, plus any other enhancements that are recommended for playing Randomizer." - ); - - InsertPadding(); - - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f)); - if (ImGui::Button("Apply Preset")) { - applyEnhancementPresets(); - needs_save = true; - } - ImGui::PopStyleVar(1); - - PaddedSeparator(); - - if (ImGui::BeginMenu("Controls")) { - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0)); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); - ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); - float availableWidth = ImGui::GetContentRegionAvail().x; - if (ImGui::Button( - GetWindowButtonText("Customize Game Controls", CVar_GetS32("gGameControlEditorEnabled", 0)).c_str(), - ImVec2(availableWidth, 0) - )) { - bool currentValue = CVar_GetS32("gGameControlEditorEnabled", 0); - CVar_SetS32("gGameControlEditorEnabled", !currentValue); - needs_save = true; - customWindows["Game Control Editor"].enabled = CVar_GetS32("gGameControlEditorEnabled", 0); - } - ImGui::PopStyleVar(3); - ImGui::PopStyleColor(1); - - // TODO mutual exclusions -- There should be some system to prevent conclifting enhancements from being selected - PaddedEnhancementCheckbox("D-pad Support on Pause and File Select", "gDpadPauseName"); - Tooltip("Enables Pause and File Select screen navigation with the D-pad\nIf used with D-pad as Equip Items, you must hold C-Up to equip instead of navigate"); - PaddedEnhancementCheckbox("D-pad Support in Text Choice", "gDpadText", true, false); - PaddedEnhancementCheckbox("D-pad Support for Browsing Shop Items", "gDpadShop", true, false); - PaddedEnhancementCheckbox("D-pad as Equip Items", "gDpadEquips", true, false); - Tooltip("Allows the D-pad to be used as extra C buttons"); - PaddedEnhancementCheckbox("Allow the cursor to be on any slot", "gPauseAnyCursor", true, false); - Tooltip("Allows the cursor on the pause menu to be over any slot\nSimilar to Rando and Spaceworld 97"); - PaddedEnhancementCheckbox("Prevent Dropped Ocarina Inputs", "gDpadNoDropOcarinaInput", true, false); - Tooltip("Prevent dropping inputs when playing the ocarina quickly"); - PaddedEnhancementCheckbox("Answer Navi Prompt with L Button", "gNaviOnL", true, false); - Tooltip("Speak to Navi with L but enter first-person camera with C-Up"); - ImGui::EndMenu(); - } - - InsertPadding(); - - if (ImGui::BeginMenu("Gameplay")) - { - if (ImGui::BeginMenu("Time Savers")) - { - PaddedEnhancementSliderInt("Text Speed: %dx", "##TEXTSPEED", "gTextSpeed", 1, 5, "", 1, false, false, true); - PaddedEnhancementSliderInt("King Zora Speed: %dx", "##MWEEPSPEED", "gMweepSpeed", 1, 5, "", 1, false, false, true); - EnhancementSliderInt("Biggoron Forge Time: %d days", "##FORGETIME", "gForgeTime", 0, 3, "", 3); - Tooltip("Allows you to change the number of days it takes for Biggoron to forge the Biggoron Sword"); - PaddedEnhancementSliderInt("Vine/Ladder Climb speed +%d", "##CLIMBSPEED", "gClimbSpeed", 0, 12, "", 0, false, false, true); - PaddedEnhancementSliderInt("Block pushing speed +%d", "##BLOCKSPEED", "gFasterBlockPush", 0, 5, "", 0, false, false, true); - PaddedEnhancementCheckbox("Faster Heavy Block Lift", "gFasterHeavyBlockLift", true, false); - Tooltip("Speeds up lifting silver rocks and obelisks"); - PaddedEnhancementCheckbox("No Forced Navi", "gNoForcedNavi", true, false); - Tooltip("Prevent forced Navi conversations"); - PaddedEnhancementCheckbox("No Skulltula Freeze", "gSkulltulaFreeze", true, false); - Tooltip("Stops the game from freezing the player when picking up Gold Skulltulas"); - PaddedEnhancementCheckbox("MM Bunny Hood", "gMMBunnyHood", true, false); - Tooltip("Wearing the Bunny Hood grants a speed increase like in Majora's Mask"); - PaddedEnhancementCheckbox("Fast Chests", "gFastChests", true, false); - Tooltip("Kick open every chest"); - PaddedEnhancementCheckbox("Skip Pickup Messages", "gFastDrops", true, false); - Tooltip("Skip pickup messages for new consumable items and bottle swipes"); - PaddedEnhancementCheckbox("Better Owl", "gBetterOwl", true, false); - Tooltip("The default response to Kaepora Gaebora is always that you understood what he said"); - PaddedEnhancementCheckbox("Fast Ocarina Playback", "gFastOcarinaPlayback", true, false); - Tooltip("Skip the part where the Ocarina playback is called when you play a song"); - PaddedEnhancementCheckbox("Skip Scarecrow Song", "gSkipScarecrow", true, false); - Tooltip("Pierre appears when Ocarina is pulled out. Requires learning scarecrow song."); - PaddedEnhancementCheckbox("Instant Putaway", "gInstantPutaway", true, false); - Tooltip("Allow Link to put items away without having to wait around"); - PaddedEnhancementCheckbox("Instant Boomerang Recall", "gFastBoomerang", true, false); - Tooltip("Instantly return the boomerang to Link by pressing its item button while it's in the air"); - PaddedEnhancementCheckbox("Mask Select in Inventory", "gMaskSelect", true, false); - Tooltip("After completing the mask trading sub-quest, press A and any direction on the mask slot to change masks"); - PaddedEnhancementCheckbox("Remember Save Location", "gRememberSaveLocation", true, false); - Tooltip("When loading a save, places Link at the last entrance he went through.\n" - "This doesn't work if the save was made in a grotto."); - ImGui::EndMenu(); - } - - InsertPadding(); - - if (ImGui::BeginMenu("Difficulty Options")) - { - ImGui::Text("Damage Multiplier"); - EnhancementCombobox("gDamageMul", powers, 9, 0); - Tooltip( - "Modifies all sources of damage not affected by other sliders\n\ - 2x: Can survive all common attacks from the start of the game\n\ - 4x: Dies in 1 hit to any substantial attack from the start of the game\n\ - 8x: Can only survive trivial damage from the start of the game\n\ - 16x: Can survive all common attacks with max health without double defense\n\ - 32x: Can survive all common attacks with max health and double defense\n\ - 64x: Can survive trivial damage with max health without double defense\n\ - 128x: Can survive trivial damage with max health and double defense\n\ - 256x: Cannot survive damage" - ); - PaddedText("Fall Damage Multiplier", true, false); - EnhancementCombobox("gFallDamageMul", powers, 8, 0); - Tooltip( - "Modifies all fall damage\n\ - 2x: Can survive all fall damage from the start of the game\n\ - 4x: Can only survive short fall damage from the start of the game\n\ - 8x: Cannot survive any fall damage from the start of the game\n\ - 16x: Can survive all fall damage with max health without double defense\n\ - 32x: Can survive all fall damage with max health and double defense\n\ - 64x: Can survive short fall damage with double defense\n\ - 128x: Cannot survive fall damage" - ); - PaddedText("Void Damage Multiplier", true, false); - EnhancementCombobox("gVoidDamageMul", powers, 7, 0); - Tooltip( - "Modifies damage taken after falling into a void\n\ - 2x: Can survive void damage from the start of the game\n\ - 4x: Cannot survive void damage from the start of the game\n\ - 8x: Can survive void damage twice with max health without double defense\n\ - 16x: Can survive void damage with max health without double defense\n\ - 32x: Can survive void damage with max health and double defense\n\ - 64x: Cannot survive void damage" - ); - PaddedEnhancementCheckbox("No Random Drops", "gNoRandomDrops", true, false); - Tooltip("Disables random drops, except from the Goron Pot, Dampe, and bosses"); - PaddedEnhancementCheckbox("Enable Bombchu Drops", "gBombchuDrops", true, false); - Tooltip("Bombchus will sometimes drop in place of bombs"); - PaddedEnhancementCheckbox("No Heart Drops", "gNoHeartDrops", true, false); - Tooltip("Disables heart drops, but not heart placements, like from a Deku Scrub running off\nThis simulates Hero Mode from other games in the series"); - PaddedEnhancementCheckbox("Always Win Goron Pot", "gGoronPot", true, false); - Tooltip("Always get the heart piece/purple rupee from the spinning Goron pot"); - InsertPadding(); - - if (ImGui::BeginMenu("Potion Values")) - { - EnhancementCheckbox("Change Red Potion Effect", "gRedPotionEffect"); - Tooltip("Enable the following changes to the amount of health restored by Red Potions"); - EnhancementSliderInt("Red Potion Health: %d", "##REDPOTIONHEALTH", "gRedPotionHealth", 1, 100, "", 0, true); - Tooltip("Changes the amount of health restored by Red Potions"); - EnhancementCheckbox("Red Potion Percent Restore", "gRedPercentRestore"); - Tooltip("Toggles from Red Potions restoring a fixed amount of health to a percent of the player's current max health"); - - ImGui::Separator(); - - EnhancementCheckbox("Change Green Potion Effect", "gGreenPotionEffect"); - Tooltip("Enable the following changes to the amount of mana restored by Green Potions"); - EnhancementSliderInt("Green Potion Mana: %d", "##GREENPOTIONMANA", "gGreenPotionMana", 1, 100, "", 0, true); - Tooltip("Changes the amount of mana restored by Green Potions, base max mana is 48, max upgraded mana is 96"); - EnhancementCheckbox("Green Potion Percent Restore", "gGreenPercentRestore"); - Tooltip("Toggles from Green Potions restoring a fixed amount of mana to a percent of the player's current max mana"); - - ImGui::Separator(); - - EnhancementCheckbox("Change Blue Potion Effects", "gBluePotionEffects"); - Tooltip("Enable the following changes to the amount of health and mana restored by Blue Potions"); - EnhancementSliderInt("Blue Potion Health: %d", "##BLUEPOTIONHEALTH", "gBluePotionHealth", 1, 100, "", 0, true); - Tooltip("Changes the amount of health restored by Blue Potions"); - EnhancementCheckbox("Blue Potion Health Percent Restore", "gBlueHealthPercentRestore"); - Tooltip("Toggles from Blue Potions restoring a fixed amount of health to a percent of the player's current max health"); - - ImGui::Separator(); - - EnhancementSliderInt("Blue Potion Mana: %d", "##BLUEPOTIONMANA", "gBluePotionMana", 1, 100, "", 0, true); - Tooltip("Changes the amount of mana restored by Blue Potions, base max mana is 48, max upgraded mana is 96"); - EnhancementCheckbox("Blue Potion Mana Percent Restore", "gBlueManaPercentRestore"); - Tooltip("Toggles from Blue Potions restoring a fixed amount of mana to a percent of the player's current max mana"); - - ImGui::Separator(); - - EnhancementCheckbox("Change Milk Effect", "gMilkEffect"); - Tooltip("Enable the following changes to the amount of health restored by Milk"); - EnhancementSliderInt("Milk Health: %d", "##MILKHEALTH", "gMilkHealth", 1, 100, "", 0, true); - Tooltip("Changes the amount of health restored by Milk"); - EnhancementCheckbox("Milk Percent Restore", "gMilkPercentRestore"); - Tooltip("Toggles from Milk restoring a fixed amount of health to a percent of the player's current max health"); - - ImGui::Separator(); - - EnhancementCheckbox("Separate Half Milk Effect", "gSeparateHalfMilkEffect"); - Tooltip("Enable the following changes to the amount of health restored by Half Milk\nIf this is disabled, Half Milk will behave the same as Full Milk."); - EnhancementSliderInt("Half Milk Health: %d", "##HALFMILKHEALTH", "gHalfMilkHealth", 1, 100, "", 0, true); - Tooltip("Changes the amount of health restored by Half Milk"); - EnhancementCheckbox("Half Milk Percent Restore", "gHalfMilkPercentRestore"); - Tooltip("Toggles from Half Milk restoring a fixed amount of health to a percent of the player's current max health"); - - ImGui::Separator(); - - EnhancementCheckbox("Change Fairy Effect", "gFairyEffect"); - Tooltip("Enable the following changes to the amount of health restored by Fairies"); - EnhancementSliderInt("Fairy: %d", "##FAIRYHEALTH", "gFairyHealth", 1, 100, "", 0, true); - Tooltip("Changes the amount of health restored by Fairies"); - EnhancementCheckbox("Fairy Percent Restore", "gFairyPercentRestore"); - Tooltip("Toggles from Fairies restoring a fixed amount of health to a percent of the player's current max health"); - - ImGui::Separator(); - - EnhancementCheckbox("Change Fairy Revive Effect", "gFairyReviveEffect"); - Tooltip("Enable the following changes to the amount of health restored by Fairy Revivals"); - EnhancementSliderInt("Fairy Revival: %d", "##FAIRYREVIVEHEALTH", "gFairyReviveHealth", 1, 100, "", 0, true); - Tooltip("Changes the amount of health restored by Fairy Revivals"); - EnhancementCheckbox("Fairy Revive Percent Restore", "gFairyRevivePercentRestore"); - Tooltip("Toggles from Fairy Revivals restoring a fixed amount of health to a percent of the player's current max health"); - - ImGui::EndMenu(); - } - - InsertPadding(); - - if (ImGui::BeginMenu("Fishing")) { - EnhancementCheckbox("Instant Fishing", "gInstantFishing"); - Tooltip("All fish will be caught instantly"); - PaddedEnhancementCheckbox("Guarantee Bite", "gGuaranteeFishingBite", true, false); - Tooltip("When a line is stable, guarantee bite. Otherwise use default logic"); - PaddedEnhancementSliderInt("Child Minimum Weight: %d", "##cMinimumWeight", "gChildMinimumWeightFish", 6, 10, "", 10, false, true, false); - Tooltip("The minimum weight for the unique fishing reward as a child"); - PaddedEnhancementSliderInt("Adult Minimum Weight: %d", "##aMinimumWeight", "gAdultMinimumWeightFish", 8, 13, "", 13, false, true, false); - Tooltip("The minimum weight for the unique fishing reward as an adult"); - ImGui::EndMenu(); - } - - ImGui::EndMenu(); - } - - InsertPadding(); - - if (ImGui::BeginMenu("Reduced Clutter")) - { - EnhancementCheckbox("Mute Low HP Alarm", "gLowHpAlarm"); - Tooltip("Disable the low HP beeping sound"); - PaddedEnhancementCheckbox("Minimal UI", "gMinimalUI", true, false); - Tooltip("Hides most of the UI when not needed\nNote: Doesn't activate until after loading a new scene"); - PaddedEnhancementCheckbox("Disable Navi Call Audio", "gDisableNaviCallAudio", true, false); - Tooltip("Disables the voice audio when Navi calls you"); - - ImGui::EndMenu(); - } - - InsertPadding(); - - EnhancementCheckbox("Visual Stone of Agony", "gVisualAgony"); - Tooltip("Displays an icon and plays a sound when Stone of Agony should be activated, for those without rumble"); - PaddedEnhancementCheckbox("Assignable Tunics and Boots", "gAssignableTunicsAndBoots", true, false); - Tooltip("Allows equipping the tunic and boots to c-buttons"); - PaddedEnhancementCheckbox("Equipment Toggle", "gEquipmentCanBeRemoved", true, false); - Tooltip("Allows equipment to be removed by toggling it off on\nthe equipment subscreen."); - PaddedEnhancementCheckbox("Link's Cow in Both Time Periods", "gCowOfTime", true, false); - Tooltip("Allows the Lon Lon Ranch obstacle course reward to be shared across time periods"); - PaddedEnhancementCheckbox("Enable visible guard vision", "gGuardVision", true, false); - PaddedEnhancementCheckbox("Enable passage of time on file select", "gTimeFlowFileSelect", true, false); - PaddedEnhancementCheckbox("Count Golden Skulltulas", "gInjectSkulltulaCount", true, false); - Tooltip("Injects Golden Skulltula total count in pickup messages"); - PaddedEnhancementCheckbox("Pull grave during the day", "gDayGravePull", true, false); - Tooltip("Allows graves to be pulled when child during the day"); - ImGui::EndMenu(); - } - - InsertPadding(); - - if (ImGui::BeginMenu("Graphics")) - { - if (ImGui::BeginMenu("Animated Link in Pause Menu")) { - ImGui::Text("Rotation"); - EnhancementRadioButton("Disabled", "gPauseLiveLinkRotation", 0); - EnhancementRadioButton("Rotate Link with D-pad", "gPauseLiveLinkRotation", 1); - Tooltip("Allow you to rotate Link on the Equipment menu with the D-pad\nUse D-pad Up or D-pad Down to reset Link's rotation"); - EnhancementRadioButton("Rotate Link with C-buttons", "gPauseLiveLinkRotation", 2); - Tooltip("Allow you to rotate Link on the Equipment menu with the C-buttons\nUse C-Up or C-Down to reset Link's rotation"); - EnhancementRadioButton("Rotate Link with Right Stick", "gPauseLiveLinkRotation", 3); - Tooltip("Allow you to rotate Link on the Equipment menu with the Right Stick\nYou can zoom in by pointing up and reset Link's rotation by pointing down"); - if (CVar_GetS32("gPauseLiveLinkRotation", 0) != 0) { - EnhancementSliderInt("Rotation Speed: %d", "##MinRotationSpeed", "gPauseLiveLinkRotationSpeed", 1, 20, ""); - } - PaddedSeparator(); - ImGui::Text("Static loop"); - EnhancementRadioButton("Disabled", "gPauseLiveLink", 0); - EnhancementRadioButton("Idle (standing)", "gPauseLiveLink", 1); - EnhancementRadioButton("Idle (look around)", "gPauseLiveLink", 2); - EnhancementRadioButton("Idle (belt)", "gPauseLiveLink", 3); - EnhancementRadioButton("Idle (shield)", "gPauseLiveLink", 4); - EnhancementRadioButton("Idle (test sword)", "gPauseLiveLink", 5); - EnhancementRadioButton("Idle (yawn)", "gPauseLiveLink", 6); - EnhancementRadioButton("Battle Stance", "gPauseLiveLink", 7); - EnhancementRadioButton("Walking (no shield)", "gPauseLiveLink", 8); - EnhancementRadioButton("Walking (holding shield)", "gPauseLiveLink", 9); - EnhancementRadioButton("Running (no shield)", "gPauseLiveLink", 10); - EnhancementRadioButton("Running (holding shield)", "gPauseLiveLink", 11); - EnhancementRadioButton("Hand on hip", "gPauseLiveLink", 12); - EnhancementRadioButton("Spin attack charge", "gPauseLiveLink", 13); - EnhancementRadioButton("Look at hand", "gPauseLiveLink", 14); - PaddedSeparator(); - ImGui::Text("Randomize"); - EnhancementRadioButton("Random", "gPauseLiveLink", 15); - Tooltip("Randomize the animation played each time you open the menu"); - EnhancementRadioButton("Random cycle", "gPauseLiveLink", 16); - Tooltip("Randomize the animation played on the menu after a certain time"); - EnhancementRadioButton("Random cycle (Idle)", "gPauseLiveLink", 17); - Tooltip("Randomize the animation played on the menu after a certain time (Idle animations only)"); - if (CVar_GetS32("gPauseLiveLink", 0) >= 16) { - EnhancementSliderInt("Frame to wait: %d", "##MinFrameCount", "gMinFrameCount", 1, 1000, "", 0, true); - } - - ImGui::EndMenu(); - } - PaddedEnhancementCheckbox("N64 Mode", "gN64Mode", true, false); - Tooltip("Sets aspect ratio to 4:3 and lowers resolution to 240p, the N64's native resolution"); - PaddedEnhancementCheckbox("Enable 3D Dropped items/projectiles", "gNewDrops", true, false); - Tooltip("Change most 2D items and projectiles on the overworld to their 3D versions"); - PaddedEnhancementCheckbox("Disable Black Bar Letterboxes", "gDisableBlackBars", true, false); - Tooltip("Disables Black Bar Letterboxes during cutscenes and Z-targeting\nNote: there may be minor visual glitches that were covered up by the black bars\nPlease disable this setting before reporting a bug"); - PaddedEnhancementCheckbox("Dynamic Wallet Icon", "gDynamicWalletIcon", true, false); - Tooltip("Changes the rupee in the wallet icon to match the wallet size you currently have"); - PaddedEnhancementCheckbox("Always show dungeon entrances", "gAlwaysShowDungeonMinimapIcon", true, false); - Tooltip("Always shows dungeon entrance icons on the minimap"); - - ImGui::EndMenu(); - } - - InsertPadding(); - - if (ImGui::BeginMenu("Fixes")) - { - EnhancementCheckbox("Fix L&R Pause menu", "gUniformLR"); - Tooltip("Makes the L and R buttons in the pause menu the same color"); - PaddedEnhancementCheckbox("Fix L&Z Page switch in Pause menu", "gNGCKaleidoSwitcher", true, false); - Tooltip("Makes L and R switch pages like on the GameCube\nZ opens the Debug Menu instead"); - PaddedEnhancementCheckbox("Fix Dungeon entrances", "gFixDungeonMinimapIcon", true, false); - Tooltip("Removes the dungeon entrance icon on the top-left corner of the screen when no dungeon is present on the current map"); - PaddedEnhancementCheckbox("Fix Two Handed idle animations", "gTwoHandedIdle", true, false); - Tooltip("Re-enables the two-handed idle animation, a seemingly finished animation that was disabled on accident in the original game"); - PaddedEnhancementCheckbox("Fix the Gravedigging Tour Glitch", "gGravediggingTourFix", true, false); - Tooltip("Fixes a bug where the Gravedigging Tour Heart Piece disappears if the area reloads"); - PaddedEnhancementCheckbox("Fix Deku Nut upgrade", "gDekuNutUpgradeFix", true, false); - Tooltip("Prevents the Forest Stage Deku Nut upgrade from becoming unobtainable after receiving the Poacher's Saw"); - PaddedEnhancementCheckbox("Fix Navi text HUD position", "gNaviTextFix", true, false); - Tooltip("Correctly centers the Navi text prompt on the HUD's C-Up button"); - PaddedEnhancementCheckbox("Fix Anubis fireballs", "gAnubisFix", true, false); - Tooltip("Make Anubis fireballs do fire damage when reflected back at them with the Mirror Shield"); - PaddedEnhancementCheckbox("Fix Megaton Hammer crouch stab", "gCrouchStabHammerFix", true, false); - Tooltip("Make the Megaton Hammer's crouch stab able to destroy rocks without first swinging it normally"); - if (CVar_GetS32("gCrouchStabHammerFix", 0) == 0) { - CVar_SetS32("gCrouchStabFix", 0); - } else { - PaddedEnhancementCheckbox("Remove power crouch stab", "gCrouchStabFix", true, false); - Tooltip("Make crouch stabbing always do the same damage as a regular slash"); - } - - ImGui::EndMenu(); - } - - InsertPadding(); - - if (ImGui::BeginMenu("Restoration")) - { - EnhancementCheckbox("Red Ganon blood", "gRedGanonBlood"); - Tooltip("Restore the original red blood from NTSC 1.0/1.1. Disable for green blood"); - PaddedEnhancementCheckbox("Fish while hovering", "gHoverFishing", true, false); - Tooltip("Restore a bug from NTSC 1.0 that allows casting the Fishing Rod while using the Hover Boots"); - PaddedEnhancementCheckbox("N64 Weird Frames", "gN64WeirdFrames", true, false); - Tooltip("Restores N64 Weird Frames allowing weirdshots to behave the same as N64"); - PaddedEnhancementCheckbox("Bombchus out of bounds", "gBombchusOOB", true, false); - Tooltip("Allows bombchus to explode out of bounds\nSimilar to GameCube and Wii VC"); - PaddedEnhancementCheckbox("Restore old Gold Skulltula cutscene", "gGsCutscene", true, false); - - ImGui::EndMenu(); - } - - PaddedEnhancementCheckbox("Autosave", "gAutosave", true, false); - Tooltip("Automatically save the game every time a new area is entered or item is obtained\n" - "To disable saving when obtaining an item, manually set gAutosaveAllItems and gAutosaveMajorItems to 0\n" - "gAutosaveAllItems takes priority over gAutosaveMajorItems if both are set to 1\n" - "gAutosaveMajorItems excludes rupees and health/magic/ammo refills (but includes bombchus)"); - - InsertPadding(); - - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0)); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); - ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); - static ImVec2 buttonSize(200.0f, 0.0f); - if (ImGui::Button(GetWindowButtonText("Cosmetics Editor", CVar_GetS32("gCosmeticsEditorEnabled", 0)).c_str(), buttonSize)) - { - bool currentValue = CVar_GetS32("gCosmeticsEditorEnabled", 0); - CVar_SetS32("gCosmeticsEditorEnabled", !currentValue); - needs_save = true; - customWindows["Cosmetics Editor"].enabled = CVar_GetS32("gCosmeticsEditorEnabled", 0); - } - ImGui::PopStyleVar(3); - ImGui::PopStyleColor(1); - - EXPERIMENTAL(); - - const char* fps_cvar = "gInterpolationFPS"; - { - #if defined(__SWITCH__) || defined(__WIIU__) - int minFps = 20; - int maxFps = 60; - #else - int minFps = 20; - int maxFps = 360; - #endif - - int val = CVar_GetS32(fps_cvar, minFps); - val = MAX(MIN(val, maxFps), 20); - - #ifdef __WIIU__ - // only support divisors of 60 on the Wii U - val = 60 / (60 / val); - #endif - - int fps = val; - - if (fps == 20) - { - ImGui::Text("Frame interpolation: Off"); - } - else - { - ImGui::Text("Frame interpolation: %d FPS", fps); - } - - std::string MinusBTNFPSI = " - ##FPSInterpolation"; - std::string PlusBTNFPSI = " + ##FPSInterpolation"; - if (ImGui::Button(MinusBTNFPSI.c_str())) { - #ifdef __WIIU__ - if (val >= 60) val = 30; - else val = 20; - #else - val--; - #endif - CVar_SetS32(fps_cvar, val); - needs_save = true; - } - ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); - #ifdef __WIIU__ - ImGui::PushItemWidth(ImGui::GetWindowSize().x - 79.0f * 2); - #else - ImGui::PushItemWidth(ImGui::GetWindowSize().x - 79.0f); - #endif - if (ImGui::SliderInt("##FPSInterpolation", &val, minFps, maxFps, "", ImGuiSliderFlags_AlwaysClamp)) - { - #ifdef __WIIU__ - // only support divisors of 60 on the Wii U - val = 60 / (60 / val); - #endif - if (val > 360) - { - val = 360; - } - else if (val < 20) - { - val = 20; - } - - CVar_SetS32(fps_cvar, val); - needs_save = true; - } - ImGui::PopItemWidth(); - Tooltip("Interpolate extra frames to get smoother graphics\n" - "Set to match your monitor's refresh rate, or a divisor of it\n" - "A higher target FPS than your monitor's refresh rate will just waste resources, " - "and might give a worse result.\n" - "For consistent input lag, set this value and your monitor's refresh rate to a multiple of 20\n" - "Ctrl+Click for keyboard input"); - - ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); - if (ImGui::Button(PlusBTNFPSI.c_str())) { - #ifdef __WIIU__ - if (val <= 20) val = 30; - else val = 60; - #else - val++; - #endif - CVar_SetS32(fps_cvar, val); - needs_save = true; - } - } - - if (impl.backend == Backend::DX11) - { - InsertPadding(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f)); - if (ImGui::Button("Match Refresh Rate")) - { - int hz = roundf(gfx_get_detected_hz()); - if (hz >= 20 && hz <= 360) - { - CVar_SetS32(fps_cvar, hz); - needs_save = true; - } - } - ImGui::PopStyleVar(1); - InsertPadding(); - } - EnhancementCheckbox("Disable LOD", "gDisableLOD"); - Tooltip("Turns off the Level of Detail setting, making models use their higher-poly variants at any distance"); - PaddedEnhancementCheckbox("Disable Draw Distance", "gDisableDrawDistance", true, false); - Tooltip("Turns off the objects draw distance, making objects being visible from a longer range"); - if (CVar_GetS32("gDisableDrawDistance", 0) == 0) { - CVar_SetS32("gDisableKokiriDrawDistance", 0); - } else if (CVar_GetS32("gDisableDrawDistance", 0) == 1) { - PaddedEnhancementCheckbox("Kokiri Draw Distance", "gDisableKokiriDrawDistance", true, false); - Tooltip("The Kokiri are mystical beings that fade into view when approached\nEnabling this will remove their draw distance"); - } - PaddedEnhancementCheckbox("Skip Text", "gSkipText", true, false); - Tooltip("Holding down B skips text\nKnown to cause a cutscene softlock in Water Temple\nSoftlock can be fixed by pressing D-Right in Debug mode"); - PaddedEnhancementCheckbox("Free Camera", "gFreeCamera", true, false); - Tooltip("Enables camera control\nNote: You must remap C buttons off of the right stick in the controller config menu, and map the camera stick to the right stick."); - - #ifdef __SWITCH__ - InsertPadding(); - int slot = CVar_GetS32("gSwitchPerfMode", (int)SwitchProfiles::STOCK); - ImGui::Text("Switch performance mode"); - if (ImGui::BeginCombo("##perf", SWITCH_CPU_PROFILES[slot])) { - for (int sId = 0; sId <= SwitchProfiles::POWERSAVINGM3; sId++) { - if (ImGui::Selectable(SWITCH_CPU_PROFILES[sId], sId == slot)) { - SPDLOG_INFO("Profile:: %s", SWITCH_CPU_PROFILES[sId]); - CVar_SetS32("gSwitchPerfMode", sId); - Switch::ApplyOverclock(); - needs_save = true; - } - - } - ImGui::EndCombo(); - } - #endif - - ImGui::EndMenu(); - } - - ImGui::SetCursorPosY(0.0f); - - if (ImGui::BeginMenu("Cheats")) - { - if (ImGui::BeginMenu("Infinite...")) { - EnhancementCheckbox("Money", "gInfiniteMoney"); - PaddedEnhancementCheckbox("Health", "gInfiniteHealth", true, false); - PaddedEnhancementCheckbox("Ammo", "gInfiniteAmmo", true, false); - PaddedEnhancementCheckbox("Magic", "gInfiniteMagic", true, false); - PaddedEnhancementCheckbox("Nayru's Love", "gInfiniteNayru", true, false); - PaddedEnhancementCheckbox("Epona Boost", "gInfiniteEpona", true, false); - - ImGui::EndMenu(); - } - - PaddedEnhancementCheckbox("No Clip", "gNoClip", true, false); - Tooltip("Allows you to walk through walls"); - PaddedEnhancementCheckbox("Climb Everything", "gClimbEverything", true, false); - Tooltip("Makes every surface in the game climbable"); - PaddedEnhancementCheckbox("Moon Jump on L", "gMoonJumpOnL", true, false); - Tooltip("Holding L makes you float into the air"); - PaddedEnhancementCheckbox("Super Tunic", "gSuperTunic", true, false); - Tooltip("Makes every tunic have the effects of every other tunic"); - PaddedEnhancementCheckbox("Easy ISG", "gEzISG", true, false); - Tooltip("Passive Infinite Sword Glitch\nIt makes your sword's swing effect and hitbox stay active indefinitely"); - PaddedEnhancementCheckbox("Unrestricted Items", "gNoRestrictItems", true, false); - Tooltip("Allows you to use any item at any location"); - PaddedEnhancementCheckbox("Freeze Time", "gFreezeTime", true, false); - Tooltip("Freezes the time of day"); - PaddedEnhancementCheckbox("Drops Don't Despawn", "gDropsDontDie", true, false); - Tooltip("Drops from enemies, grass, etc. don't disappear after a set amount of time"); - PaddedEnhancementCheckbox("Fireproof Deku Shield", "gFireproofDekuShield", true, false); - Tooltip("Prevents the Deku Shield from burning on contact with fire"); - PaddedEnhancementCheckbox("Shield with Two-Handed Weapons", "gShieldTwoHanded", true, false); - Tooltip("This allows you to put up your shield with any two-handed weapon in hand except for Deku Sticks"); - PaddedEnhancementCheckbox("Time Sync", "gTimeSync", true, false); - Tooltip("This syncs the ingame time with the real world time"); - - { - static int32_t betaQuestEnabled = CVar_GetS32("gEnableBetaQuest", 0); - static int32_t lastBetaQuestEnabled = betaQuestEnabled; - static int32_t betaQuestWorld = CVar_GetS32("gBetaQuestWorld", 0xFFEF); - static int32_t lastBetaQuestWorld = betaQuestWorld; - - if (!isBetaQuestEnabled) { - ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); - ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); - } - - PaddedEnhancementCheckbox("Enable Beta Quest", "gEnableBetaQuest", true, false); - Tooltip("Turns on OoT Beta Quest. *WARNING* This will reset your game."); - betaQuestEnabled = CVar_GetS32("gEnableBetaQuest", 0); - if (betaQuestEnabled) { - if (betaQuestEnabled != lastBetaQuestEnabled) { - betaQuestWorld = 0; - } - - ImGui::Text("Beta Quest World: %d", betaQuestWorld); - - if (ImGui::Button(" - ##BetaQuest")) { - betaQuestWorld--; - } - ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); - - ImGui::SliderInt("##BetaQuest", &betaQuestWorld, 0, 8, "", ImGuiSliderFlags_AlwaysClamp); - Tooltip("Set the Beta Quest world to explore. *WARNING* Changing this will reset your game.\nCtrl+Click to type in a value."); - - ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); - if (ImGui::Button(" + ##BetaQuest")) { - betaQuestWorld++; - } - - if (betaQuestWorld > 8) { - betaQuestWorld = 8; - } - else if (betaQuestWorld < 0) { - betaQuestWorld = 0; - } - } - else { - lastBetaQuestWorld = betaQuestWorld = 0xFFEF; - CVar_SetS32("gBetaQuestWorld", betaQuestWorld); - } - if (betaQuestEnabled != lastBetaQuestEnabled || betaQuestWorld != lastBetaQuestWorld) - { - // Reset the game if the beta quest state or world changed because beta quest happens on redirecting the title screen cutscene. - lastBetaQuestEnabled = betaQuestEnabled; - lastBetaQuestWorld = betaQuestWorld; - CVar_SetS32("gEnableBetaQuest", betaQuestEnabled); - CVar_SetS32("gBetaQuestWorld", betaQuestWorld); - - console->Dispatch("reset"); - - needs_save = true; - } - - if (!isBetaQuestEnabled) { - ImGui::PopItemFlag(); - ImGui::PopStyleVar(1); - } - } - - ImGui::EndMenu(); - } - - ImGui::SetCursorPosY(0.0f); - - if (ImGui::BeginMenu("Developer Tools")) - { - EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled"); - Tooltip("Enables Debug Mode, allowing you to select maps with L + R + Z, noclip with L + D-pad Right, and open the debug menu with L on the pause screen"); - PaddedEnhancementCheckbox("OoT Skulltula Debug", "gSkulltulaDebugEnabled", true, false); - Tooltip("Enables Skulltula Debug, when moving the cursor in the menu above various map icons (boss key, compass, map screen locations, etc) will set the GS bits in that area.\nUSE WITH CAUTION AS IT DOES NOT UPDATE THE GS COUNT."); - PaddedEnhancementCheckbox("Fast File Select", "gSkipLogoTitle", true, false); - Tooltip("Load the game to the selected menu or file\n\"Zelda Map Select\" require debug mode else you will fallback to File choose menu\nUsing a file number that don't have save will create a save file only if you toggle on \"Create a new save if none ?\" else it will bring you to the File choose menu"); - if (CVar_GetS32("gSkipLogoTitle", 0)) { - const char* FastFileSelect[5] = { - "File N.1", - "File N.2", - "File N.3", - "File select", - "Zelda Map Select (require OoT Debug Mode)" - }; - ImGui::Text("Loading :"); - EnhancementCombobox("gSaveFileID", FastFileSelect, 5, 0); - PaddedEnhancementCheckbox("Create a new save if none", "gCreateNewSave", true, false); - Tooltip("Enable the creation of a new save file if none exist in the File number selected\nNo file name will be assigned please do in Save editor once you see the first text else your save file name will be named \"00000000\"\nIf disabled you will fall back in File select menu"); - }; - PaddedSeparator(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0,0)); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); - ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); - static ImVec2 buttonSize(160.0f, 0.0f); - if (ImGui::Button(GetWindowButtonText("Stats", CVar_GetS32("gStatsEnabled", 0)).c_str(), buttonSize)) - { - bool currentValue = CVar_GetS32("gStatsEnabled", 0); - CVar_SetS32("gStatsEnabled", !currentValue); - statsWindowOpen = true; - needs_save = true; - } - Tooltip("Shows the stats window, with your FPS and frametimes, and the OS you're playing on"); - InsertPadding(); - if (ImGui::Button(GetWindowButtonText("Console", CVar_GetS32("gConsoleEnabled", 0)).c_str(), buttonSize)) - { - bool currentValue = CVar_GetS32("gConsoleEnabled", 0); - CVar_SetS32("gConsoleEnabled", !currentValue); - needs_save = true; - if(CVar_GetS32("gConsoleEnabled", 0)){ - console->Open(); - } else { - console->Close(); - } - } - Tooltip("Enables the console window, allowing you to input commands, type help for some examples"); - InsertPadding(); - if (ImGui::Button(GetWindowButtonText("Save Editor", CVar_GetS32("gSaveEditorEnabled", 0)).c_str(), buttonSize)) - { - bool currentValue = CVar_GetS32("gSaveEditorEnabled", 0); - CVar_SetS32("gSaveEditorEnabled", !currentValue); - needs_save = true; - customWindows["Save Editor"].enabled = CVar_GetS32("gSaveEditorEnabled", 0); - } - InsertPadding(); - if (ImGui::Button(GetWindowButtonText("Collision Viewer", CVar_GetS32("gCollisionViewerEnabled", 0)).c_str(), buttonSize)) - { - bool currentValue = CVar_GetS32("gCollisionViewerEnabled", 0); - CVar_SetS32("gCollisionViewerEnabled", !currentValue); - needs_save = true; - customWindows["Collision Viewer"].enabled = CVar_GetS32("gCollisionViewerEnabled", 0); - } - InsertPadding(); - if (ImGui::Button(GetWindowButtonText("Actor Viewer", CVar_GetS32("gActorViewerEnabled", 0)).c_str(), buttonSize)) - { - bool currentValue = CVar_GetS32("gActorViewerEnabled", 0); - CVar_SetS32("gActorViewerEnabled", !currentValue); - needs_save = true; - customWindows["Actor Viewer"].enabled = CVar_GetS32("gActorViewerEnabled", 0); - } - ImGui::PopStyleVar(3); - ImGui::PopStyleColor(1); - - ImGui::EndMenu(); - } - - ImGui::SetCursorPosY(0.0f); - - if (ImGui::BeginMenu("Randomizer")) - { - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0)); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); - ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); - static ImVec2 buttonSize(200.0f, 0.0f); - if (ImGui::Button(GetWindowButtonText("Randomizer Settings", CVar_GetS32("gRandomizerSettingsEnabled", 0)).c_str(), buttonSize)) - { - bool currentValue = CVar_GetS32("gRandomizerSettingsEnabled", 0); - CVar_SetS32("gRandomizerSettingsEnabled", !currentValue); - needs_save = true; - customWindows["Randomizer Settings"].enabled = CVar_GetS32("gRandomizerSettingsEnabled", 0); - } - InsertPadding(); - if (ImGui::Button(GetWindowButtonText("Item Tracker", CVar_GetS32("gItemTrackerEnabled", 0)).c_str(), buttonSize)) - { - bool currentValue = CVar_GetS32("gItemTrackerEnabled", 0); - CVar_SetS32("gItemTrackerEnabled", !currentValue); - needs_save = true; - customWindows["Item Tracker"].enabled = CVar_GetS32("gItemTrackerEnabled", 0); - } - ImGui::PopStyleVar(3); - ImGui::PopStyleColor(1); - - ImGui::EndMenu(); - } + clientDrawMenu(); ImGui::PopStyleVar(1); ImGui::EndMenuBar(); @@ -2015,19 +546,19 @@ namespace SohImGui { ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); ImGui::Begin("Debug Stats", &statsWindowOpen, ImGuiWindowFlags_NoFocusOnAppearing); -#if defined(_WIN32) + #if defined(_WIN32) ImGui::Text("Platform: Windows"); -#elif defined(__APPLE__) + #elif defined(__APPLE__) ImGui::Text("Platform: macOS"); -#elif defined(__SWITCH__) + #elif defined(__SWITCH__) ImGui::Text("Platform: Nintendo Switch"); -#elif defined(__WIIU__) + #elif defined(__WIIU__) ImGui::Text("Platform: Nintendo Wii U"); -#elif defined(__linux__) + #elif defined(__linux__) ImGui::Text("Platform: Linux"); -#else + #else ImGui::Text("Platform: Unknown"); -#endif + #endif ImGui::Text("Status: %.3f ms/frame (%.1f FPS)", 1000.0f / framerate, framerate); ImGui::End(); ImGui::PopStyleColor(); @@ -2078,6 +609,14 @@ namespace SohImGui { overlay->Draw(); } + void RegisterMenuDrawMethod(std::function drawMethod) { + clientDrawMenu = drawMethod; + } + + void AddSetupHooksDelegate(std::function setupHooksMethod) { + clientSetupHooks = setupHooksMethod; + } + void DrawFramebufferAndGameInput(void) { const ImVec2 main_pos = ImGui::GetWindowPos(); ImVec2 size = ImGui::GetContentRegionAvail(); @@ -2146,360 +685,6 @@ namespace SohImGui { } } - void applyEnhancementPresets(void) { - - switch (CVar_GetS32("gSelectEnhancementPresets", 0)) { - // Default - case 0: - applyEnhancementPresetDefault(); - break; - - // Vanilla Plus - case 1: - applyEnhancementPresetDefault(); - applyEnhancementPresetVanillaPlus(); - break; - - // Enhanced - case 2: - applyEnhancementPresetDefault(); - applyEnhancementPresetVanillaPlus(); - applyEnhancementPresetEnhanced(); - break; - - // Randomizer - case 3: - applyEnhancementPresetDefault(); - applyEnhancementPresetVanillaPlus(); - applyEnhancementPresetEnhanced(); - applyEnhancementPresetRandomizer(); - break; - } - } - - void applyEnhancementPresetDefault(void) { - // D-pad Support on Pause and File Select - CVar_SetS32("gDpadPauseName", 0); - // D-pad Support in Ocarina and Text Choice - CVar_SetS32("gDpadOcarinaText", 0); - // D-pad Support for Browsing Shop Items - CVar_SetS32("gDpadShop", 0); - // D-pad as Equip Items - CVar_SetS32("gDpadEquips", 0); - // Allow the cursor to be on any slot - CVar_SetS32("gPauseAnyCursor", 0); - // Prevent Dropped Ocarina Inputs - CVar_SetS32("gDpadNoDropOcarinaInput", 0); - // Answer Navi Prompt with L Button - CVar_SetS32("gNaviOnL", 0); - - // Text Speed (1 to 5) - CVar_SetS32("gTextSpeed", 1); - // King Zora Speed (1 to 5) - CVar_SetS32("gMweepSpeed", 1); - // Biggoron Forge Time (0 to 3) - CVar_SetS32("gForgeTime", 3); - // Vine/Ladder Climb speed (+0 to +12) - CVar_SetS32("gClimbSpeed", 0); - // Faster Block Push (+0 to +5) - CVar_SetS32("gFasterBlockPush", 0); - // Faster Heavy Block Lift - CVar_SetS32("gFasterHeavyBlockLift", 0); - // No Forced Navi - CVar_SetS32("gNoForcedNavi", 0); - // No Skulltula Freeze - CVar_SetS32("gSkulltulaFreeze", 0); - // MM Bunny Hood - CVar_SetS32("gMMBunnyHood", 0); - // Fast Chests - CVar_SetS32("gFastChests", 0); - // Fast Drops - CVar_SetS32("gFastDrops", 0); - // Better Owl - CVar_SetS32("gBetterOwl", 0); - // Fast Ocarina Playback - CVar_SetS32("gFastOcarinaPlayback", 0); - // Instant Putaway - CVar_SetS32("gInstantPutaway", 0); - // Instant Boomerang Recall - CVar_SetS32("gFastBoomerang", 0); - // Mask Select in Inventory - CVar_SetS32("gMaskSelect", 0); - // Remember Save Location - CVar_SetS32("gRememberSaveLocation", 0); - - // Damage Multiplier (0 to 8) - CVar_SetS32("gDamageMul", 0); - // Fall Damage Multiplier (0 to 7) - CVar_SetS32("gFallDamageMul", 0); - // Void Damage Multiplier (0 to 6) - CVar_SetS32("gVoidDamageMul", 0); - // No Random Drops - CVar_SetS32("gNoRandomDrops", 0); - // No Heart Drops - CVar_SetS32("gNoHeartDrops", 0); - // Enable Bombchu Drops - CVar_SetS32("gBombchuDrops", 0); - // Always Win Goron Pot - CVar_SetS32("gGoronPot", 0); - - // Change Red Potion Effect - CVar_SetS32("gRedPotionEffect", 0); - // Red Potion Health (1 to 100) - CVar_SetS32("gRedPotionHealth", 1); - // Red Potion Percent Restore - CVar_SetS32("gRedPercentRestore", 0); - // Change Green Potion Effect - CVar_SetS32("gGreenPotionEffect", 0); - // Green Potion Mana (1 to 100) - CVar_SetS32("gGreenPotionMana", 1); - // Green Potion Percent Restore - CVar_SetS32("gGreenPercentRestore", 0); - // Change Blue Potion Effects - CVar_SetS32("gBluePotionEffects", 0); - // Blue Potion Health (1 to 100) - CVar_SetS32("gBluePotionHealth", 1); - // Blue Potion Health Percent Restore - CVar_SetS32("gBlueHealthPercentRestore", 0); - // Blue Potion Mana (1 to 100) - CVar_SetS32("gBluePotionMana", 1); - // Blue Potion Mana Percent Restore - CVar_SetS32("gBlueManaPercentRestore", 0); - // Change Milk Effect - CVar_SetS32("gMilkEffect", 0); - // Milk Health (1 to 100) - CVar_SetS32("gMilkHealth", 1); - // Milk Percent Restore - CVar_SetS32("gMilkPercentRestore", 0); - // Separate Half Milk Effect - CVar_SetS32("gSeparateHalfMilkEffect", 0); - // Half Milk Health (1 to 100) - CVar_SetS32("gHalfMilkHealth", 0); - // Half Milk Percent Restore - CVar_SetS32("gHalfMilkPercentRestore", 0); - // Change Fairy Effect - CVar_SetS32("gFairyEffect", 0); - // Fairy (1 to 100) - CVar_SetS32("gFairyHealth", 1); - // Fairy Percent Restore - CVar_SetS32("gFairyPercentRestore", 0); - // Change Fairy Revive Effect - CVar_SetS32("gFairyReviveEffect", 0); - // Fairy Revival (1 to 100) - CVar_SetS32("gFairyReviveHealth", 1); - // Fairy Revive Percent Restore - CVar_SetS32("gFairyRevivePercentRestore", 0); - - // Instant Fishing - CVar_SetS32("gInstantFishing", 0); - // Guarantee Bite - CVar_SetS32("gGuaranteeFishingBite", 0); - // Child Minimum Weight (6 to 10) - CVar_SetS32("gChildMinimumWeightFish", 10); - // Adult Minimum Weight (8 to 13) - CVar_SetS32("gAdultMinimumWeightFish", 13); - - // Mute Low HP Alarm - CVar_SetS32("gLowHpAlarm", 0); - // Minimal UI - CVar_SetS32("gMinimalUI", 0); - // Disable Navi Call Audio - CVar_SetS32("gDisableNaviCallAudio", 0); - - // Visual Stone of Agony - CVar_SetS32("gVisualAgony", 0); - // Assignable Tunics and Boots - CVar_SetS32("gAssignableTunicsAndBoots", 0); - // Equipment Toggle - CVar_SetS32("gEquipmentCanBeRemoved", 0); - // Link's Cow in Both Time Periods - CVar_SetS32("gCowOfTime", 0); - // Enable visible guard vision - CVar_SetS32("gGuardVision", 0); - // Enable passage of time on file select - CVar_SetS32("gTimeFlowFileSelect", 0); - // Count Golden Skulltulas - CVar_SetS32("gInjectSkulltulaCount", 0); - // Pull grave during the day - CVar_SetS32("gDayGravePull", 0); - - // Rotate link (0 to 2) - CVar_SetS32("gPauseLiveLinkRotation", 0); - // Pause link animation (0 to 16) - CVar_SetS32("gPauseLiveLink", 0); - // Frames to wait - CVar_SetS32("gMinFrameCount", 1); - - // N64 Mode - CVar_SetS32("gN64Mode", 0); - // Enable 3D Dropped items/projectiles - CVar_SetS32("gNewDrops", 0); - // Disable Black Bar Letterboxes - CVar_SetS32("gDisableBlackBars", 0); - // Dynamic Wallet Icon - CVar_SetS32("gDynamicWalletIcon", 0); - // Always show dungeon entrances - CVar_SetS32("gAlwaysShowDungeonMinimapIcon", 0); - - // Fix L&R Pause menu - CVar_SetS32("gUniformLR", 0); - // Fix L&Z Page switch in Pause menu - CVar_SetS32("gNGCKaleidoSwitcher", 0); - // Fix Dungeon entrances - CVar_SetS32("gFixDungeonMinimapIcon", 0); - // Fix Two Handed idle animations - CVar_SetS32("gTwoHandedIdle", 0); - // Fix the Gravedigging Tour Glitch - CVar_SetS32("gGravediggingTourFix", 0); - // Fix Deku Nut upgrade - CVar_SetS32("gDekuNutUpgradeFix", 0); - // Fix Navi text HUD position - CVar_SetS32("gNaviTextFix", 0); - // Fix Anubis fireballs - CVar_SetS32("gAnubisFix", 0); - // Fix Megaton Hammer crouch stab - CVar_SetS32("gCrouchStabHammerFix", 0); - // Fix all crouch stab - CVar_SetS32("gCrouchStabFix", 0); - - // Red Ganon blood - CVar_SetS32("gRedGanonBlood", 0); - // Fish while hovering - CVar_SetS32("gHoverFishing", 0); - // N64 Weird Frames - CVar_SetS32("gN64WeirdFrames", 0); - // Bombchus out of bounds - CVar_SetS32("gBombchusOOB", 0); - - CVar_SetS32("gGsCutscene", 0); - // Autosave - CVar_SetS32("gAutosave", 0); - } - - void applyEnhancementPresetVanillaPlus(void) { - // D-pad Support in Ocarina and Text Choice - CVar_SetS32("gDpadOcarinaText", 1); - // D-pad Support for Browsing Shop Items - CVar_SetS32("gDpadShop", 1); - // D-pad as Equip Items - CVar_SetS32("gDpadEquips", 1); - // Prevent Dropped Ocarina Inputs - CVar_SetS32("gDpadNoDropOcarinaInput", 1); - - // Text Speed (1 to 5) - CVar_SetS32("gTextSpeed", 5); - // King Zora Speed (1 to 5) - CVar_SetS32("gMweepSpeed", 2); - // Faster Block Push (+0 to +5) - CVar_SetS32("gFasterBlockPush", 5); - // Better Owl - CVar_SetS32("gBetterOwl", 1); - - // Assignable Tunics and Boots - CVar_SetS32("gAssignableTunicsAndBoots", 1); - // Enable passage of time on file select - CVar_SetS32("gTimeFlowFileSelect", 1); - // Count Golden Skulltulas - CVar_SetS32("gInjectSkulltulaCount", 1); - - // Pause link animation (0 to 16) - CVar_SetS32("gPauseLiveLink", 1); - - // Dynamic Wallet Icon - CVar_SetS32("gDynamicWalletIcon", 1); - // Always show dungeon entrances - CVar_SetS32("gAlwaysShowDungeonMinimapIcon", 1); - - // Fix L&R Pause menu - CVar_SetS32("gUniformLR", 1); - // Fix Dungeon entrances - CVar_SetS32("gFixDungeonMinimapIcon", 1); - // Fix Two Handed idle animations - CVar_SetS32("gTwoHandedIdle", 1); - // Fix the Gravedigging Tour Glitch - CVar_SetS32("gGravediggingTourFix", 1); - // Fix Deku Nut upgrade - CVar_SetS32("gDekuNutUpgradeFix", 1); - - // Red Ganon blood - CVar_SetS32("gRedGanonBlood", 1); - // Fish while hovering - CVar_SetS32("gHoverFishing", 1); - // N64 Weird Frames - CVar_SetS32("gN64WeirdFrames", 1); - // Bombchus out of bounds - CVar_SetS32("gBombchusOOB", 1); - } - - void applyEnhancementPresetEnhanced(void) { - // King Zora Speed (1 to 5) - CVar_SetS32("gMweepSpeed", 5); - // Biggoron Forge Time (0 to 3) - CVar_SetS32("gForgeTime", 0); - // Vine/Ladder Climb speed (+0 to +12) - CVar_SetS32("gClimbSpeed", 1); - // Faster Heavy Block Lift - CVar_SetS32("gFasterHeavyBlockLift", 1); - // No Forced Navi - CVar_SetS32("gNoForcedNavi", 1); - // No Skulltula Freeze - CVar_SetS32("gSkulltulaFreeze", 1); - // MM Bunny Hood - CVar_SetS32("gMMBunnyHood", 1); - // Fast Chests - CVar_SetS32("gFastChests", 1); - // Fast Drops - CVar_SetS32("gFastDrops", 1); - // Fast Ocarina Playback - CVar_SetS32("gFastOcarinaPlayback", 1); - // Instant Putaway - CVar_SetS32("gInstantPutaway", 1); - // Instant Boomerang Recall - CVar_SetS32("gFastBoomerang", 1); - // Mask Select in Inventory - CVar_SetS32("gMaskSelect", 1); - - // Disable Navi Call Audio - CVar_SetS32("gDisableNaviCallAudio", 1); - - // Equipment Toggle - CVar_SetS32("gEquipmentCanBeRemoved", 1); - // Count Golden Skulltulas - CVar_SetS32("gInjectSkulltulaCount", 1); - - // Enable 3D Dropped items/projectiles - CVar_SetS32("gNewDrops", 1); - - // Fix Anubis fireballs - CVar_SetS32("gAnubisFix", 1); - } - - void applyEnhancementPresetRandomizer(void) { - // Allow the cursor to be on any slot - CVar_SetS32("gPauseAnyCursor", 1); - - // Instant Fishing - CVar_SetS32("gInstantFishing", 1); - // Guarantee Bite - CVar_SetS32("gGuaranteeFishingBite", 1); - // Child Minimum Weight (6 to 10) - CVar_SetS32("gChildMinimumWeightFish", 6); - // Adult Minimum Weight (8 to 13) - CVar_SetS32("gAdultMinimumWeightFish", 8); - - // Visual Stone of Agony - CVar_SetS32("gVisualAgony", 1); - // Pull grave during the day - CVar_SetS32("gDayGravePull", 1); - // Pull out Ocarina to Summon Scarecrow - CVar_SetS32("gSkipScarecrow", 0); - - // Pause link animation (0 to 16) - CVar_SetS32("gPauseLiveLink", 16); - // Frames to wait - CVar_SetS32("gMinFrameCount", 200); - } - void Render() { ImGui::Render(); ImGuiRenderDrawData(ImGui::GetDrawData()); @@ -2526,8 +711,41 @@ namespace SohImGui { } } - void BindCmd(const std::string& cmd, CommandEntry entry) { - console->AddCommand(cmd, entry); + void DrawSettings() { + overlay->DrawSettings(); + } + + Backend WindowBackend() { + return impl.backend; + } + + float WindowRefreshRate() { + return gfx_get_detected_hz(); + } + + std::pair* GetAvailableRenderingBackends() { + return backends; + } + + std::pair GetCurrentRenderingBackend() { + return backends[lastBackendID]; + } + + void SetCurrentRenderingBackend(uint8_t index, std::pair backend) { + Window::GetInstance()->GetConfig()->setString("Window.GfxBackend", backend.first); + lastBackendID = index; + } + + const char** GetSupportedTextureFilters() { + return filters; + } + + void SetResolutionMultiplier(float multiplier) { + gfx_current_dimensions.internal_mul = multiplier; + } + + void SetMSAALevel(uint32_t value) { + gfx_msaa_level = value; } void AddWindow(const std::string& category, const std::string& name, WindowDrawFunc drawFunc, bool isEnabled, bool isHidden) { @@ -2548,30 +766,135 @@ namespace SohImGui { } } + void EnableWindow(const std::string& name, bool isEnabled) { + customWindows[name].enabled = isEnabled; + } + + Ship::GameOverlay* GetGameOverlay() { + return overlay; + } + + Ship::InputEditor* GetInputEditor() { + return controller; + } + + void ToggleInputEditorWindow(bool isOpen) { + if (isOpen) + controller->Open(); + else + controller->Close(); + } + + void ToggleStatisticsWindow(bool isOpen) { + statsWindowOpen = isOpen; + } + + std::shared_ptr GetConsole() { + return console; + } + + void ToggleConsoleWindow(bool isOpen) { + if (isOpen) + console->Open(); + else + console->Close(); + } + + void DispatchConsoleCommand(const std::string& line) { + console->Dispatch(line); + } + + void RequestCvarSaveOnNextTick() { + needs_save = true; + } + ImTextureID GetTextureByName(const std::string& name) { return GetTextureByID(DefaultAssets[name]->textureId); } ImTextureID GetTextureByID(int id) { -#ifdef ENABLE_DX11 + #ifdef ENABLE_DX11 if (impl.backend == Backend::DX11) { ImTextureID gfx_d3d11_get_texture_by_id(int id); return gfx_d3d11_get_texture_by_id(id); } -#endif -#ifdef __WIIU__ + #endif + #ifdef __WIIU__ if (impl.backend == Backend::GX2) { return gfx_gx2_texture_for_imgui(id); } -#endif + #endif return reinterpret_cast(id); } - void BeginGroupPanel(const char* name, const ImVec2& size) - { + void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint) { + GfxRenderingAPI* api = gfx_get_current_rendering_api(); + const auto res = static_cast(Window::GetInstance()->GetResourceManager()->LoadResource(path).get()); + + std::vector texBuffer; + texBuffer.reserve(res->width * res->height * 4); + + switch (res->texType) { + case Ship::TextureType::RGBA32bpp: + texBuffer.assign(res->imageData, res->imageData + (res->width * res->height * 4)); + break; + case Ship::TextureType::GrayscaleAlpha8bpp: + for (int32_t i = 0; i < res->width * res->height; i++) { + uint8_t ia = res->imageData[i]; + uint8_t color = ((ia >> 4) & 0xF) * 255 / 15; + uint8_t alpha = (ia & 0xF) * 255 / 15; + texBuffer.push_back(color); + texBuffer.push_back(color); + texBuffer.push_back(color); + texBuffer.push_back(alpha); + } + break; + default: + // TODO convert other image types + SPDLOG_WARN("SohImGui::LoadResource: Attempting to load unsupporting image type %s", path.c_str()); + return; + } + + for (size_t pixel = 0; pixel < texBuffer.size() / 4; pixel++) { + texBuffer[pixel * 4 + 0] *= tint.x; + texBuffer[pixel * 4 + 1] *= tint.y; + texBuffer[pixel * 4 + 2] *= tint.z; + texBuffer[pixel * 4 + 3] *= tint.w; + } + + const auto asset = new GameAsset{ api->new_texture() }; + + api->select_texture(0, asset->textureId); + api->set_sampler_parameters(0, false, 0, 0); + api->upload_texture(texBuffer.data(), res->width, res->height); + + DefaultAssets[name] = asset; + } + + void ShowCursor(bool hide, Dialogues d) { + if (d == Dialogues::dLoadSettings) { + Window::GetInstance()->ShowCursor(hide); + return; + } + + if (d == Dialogues::dConsole && CVar_GetS32("gOpenMenuBar", 0)) { + return; + } + if (!Window::GetInstance()->IsFullscreen()) { + oldCursorState = false; + return; + } + + if (oldCursorState != hide) { + oldCursorState = hide; + Window::GetInstance()->ShowCursor(hide); + } + } + + void BeginGroupPanel(const char* name, const ImVec2& size) { ImGui::BeginGroup(); // auto cursorPos = ImGui::GetCursorScreenPos(); @@ -2605,13 +928,13 @@ namespace SohImGui { ImGui::PopStyleVar(2); -#if IMGUI_VERSION_NUM >= 17301 + #if IMGUI_VERSION_NUM >= 17301 ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f; ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f; ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f; -#else + #else ImGui::GetCurrentWindow()->ContentsRegionRect.Max.x -= frameHeight * 0.5f; -#endif + #endif ImGui::GetCurrentWindow()->Size.x -= frameHeight; auto itemWidth = ImGui::CalcItemWidth(); @@ -2676,101 +999,17 @@ namespace SohImGui { ImGui::PopStyleVar(2); -#if IMGUI_VERSION_NUM >= 17301 + #if IMGUI_VERSION_NUM >= 17301 ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f; ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f; ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f; -#else + #else ImGui::GetCurrentWindow()->ContentsRegionRect.Max.x += frameHeight * 0.5f; -#endif + #endif ImGui::GetCurrentWindow()->Size.x += frameHeight; - InsertPadding(); + ImGui::Dummy(ImVec2(0.0f, 0.0f)); ImGui::EndGroup(); } - - // Automatically add newlines to break up tooltips longer than a specified number of characters - // Manually included newlines will still be respected and reset the line length - // Default line length is 60 characters - std::string BreakTooltip(const char* text, int lineLength) { - std::string newText(text); - const int tipLength = newText.length(); - int lastSpace = -1; - int currentLineLength = 0; - for (int currentCharacter = 0; currentCharacter < tipLength; currentCharacter++) { - if (newText[currentCharacter] == '\n') { - currentLineLength = 0; - lastSpace = -1; - continue; - } - else if (newText[currentCharacter] == ' ') { - lastSpace = currentCharacter; - } - - if ((currentLineLength >= lineLength) && (lastSpace >= 0)) { - newText[lastSpace] = '\n'; - currentLineLength = currentCharacter - lastSpace - 1; - lastSpace = -1; - } - currentLineLength++; - } - return newText; - } - - std::string BreakTooltip(const std::string& text, int lineLength) { - return BreakTooltip(text.c_str(), lineLength); - } - - void InsertPadding(float extraVerticalPadding) { - ImGui::Dummy(ImVec2(0.0f, extraVerticalPadding)); - } - - void PaddedSeparator(bool padTop, bool padBottom, float extraVerticalTopPadding, float extraVerticalBottomPadding) { - if (padTop) { - ImGui::Dummy(ImVec2(0.0f, extraVerticalTopPadding)); - } - ImGui::Separator(); - if (padBottom) { - ImGui::Dummy(ImVec2(0.0f, extraVerticalBottomPadding)); - } - } - - void PaddedEnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue, bool PlusMinusButton, bool padTop, bool padBottom) { - if (padTop) { - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - } - EnhancementSliderInt(text, id, cvarName, min, max, format, defaultValue, PlusMinusButton); - if (padBottom) { - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - } - } - - void PaddedEnhancementCheckbox(const char* text, const char* cvarName, bool padTop, bool padBottom, bool disabled, const char* disabledTooltipText, ImGuiCheckboxGraphics disabledGraphic) { - if (padTop) { - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - } - EnhancementCheckbox(text, cvarName, disabled, disabledTooltipText, disabledGraphic); - if (padBottom) { - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - } - } - - void PaddedText(const char* text, bool padTop, bool padBottom) { - if (padTop) { - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - } - ImGui::Text("%s", text); - if (padBottom) { - ImGui::Dummy(ImVec2(0.0f, 0.0f)); - } - } - - std::string GetWindowButtonText(const char* text, bool menuOpen) { - char buttonText[100] = ""; - if(menuOpen) { strcat(buttonText,"> "); } - strcat(buttonText, text); - if (!menuOpen) { strcat(buttonText, " "); } - return buttonText; - } } diff --git a/libultraship/libultraship/ImGuiImpl.h b/libultraship/libultraship/ImGuiImpl.h index 733e9d1cf..cd035ae8a 100644 --- a/libultraship/libultraship/ImGuiImpl.h +++ b/libultraship/libultraship/ImGuiImpl.h @@ -1,14 +1,5 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - void enableBetaQuest(); - void disableBetaQuest(); -#ifdef __cplusplus -} -#endif - #ifdef __cplusplus #include "GameOverlay.h" #include "Lib/ImGui/imgui.h" @@ -34,14 +25,6 @@ namespace SohImGui { dLoadSettings, }; - // Enumeration for disabled checkbox graphics - enum class ImGuiCheckboxGraphics - { - Cross, - Checkmark, - None - }; - typedef struct { Backend backend; union { @@ -76,8 +59,6 @@ namespace SohImGui { } gx2; } EventImpl; - extern WindowImpl impl; - using WindowDrawFunc = void(*)(bool& enabled); typedef struct { @@ -85,55 +66,49 @@ namespace SohImGui { WindowDrawFunc drawFunc; } CustomWindow; - extern std::shared_ptr console; - extern Ship::InputEditor* controller; - extern Ship::GameOverlay* overlay; - extern bool needs_save; void Init(WindowImpl window_impl); void Update(EventImpl event); - void Tooltip(const char* text); - - void EnhancementRadioButton(const char* text, const char* cvarName, int id); - void EnhancementCheckbox(const char* text, const char* cvarName, bool disabled = false, const char* disabledTooltipText = "", ImGuiCheckboxGraphics disabledGraphic = ImGuiCheckboxGraphics::Cross); - void EnhancementButton(const char* text, const char* cvarName); - void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = false); - void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton = false); - void EnhancementCombobox(const char* name, const char* ComboArray[], size_t arraySize, uint8_t FirstTimeValue); - void EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow = true, bool has_alpha=false, bool TitleSameLine=false); - void EnhancementCombo(const std::string& name, const char* cvarName, const std::vector& items, int defaultValue = 0); - - void applyEnhancementPresets(void); - void applyEnhancementPresetDefault(void); - void applyEnhancementPresetVanillaPlus(void); - void applyEnhancementPresetEnhanced(void); - void applyEnhancementPresetRandomizer(void); void DrawMainMenuAndCalculateGameSize(void); + void RegisterMenuDrawMethod(std::function drawMethod); + void AddSetupHooksDelegate(std::function setupHooksMethod); void DrawFramebufferAndGameInput(void); void Render(void); void CancelFrame(void); - void ShowCursor(bool hide, Dialogues w); - void BindCmd(const std::string& cmd, Ship::CommandEntry entry); - void AddWindow(const std::string& category, const std::string& name, WindowDrawFunc drawFunc, bool isEnabled=false, bool isHidden=false); - void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint = ImVec4(1, 1, 1, 1)); - void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha=false); - int ClampFloatToInt(float value, int min, int max); - void RandomizeColor(const char* cvarName, ImVec4* colors); - void RainbowColor(const char* cvarName, ImVec4* colors); - void ResetColor(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha); + void DrawSettings(); + + Backend WindowBackend(); + float WindowRefreshRate(); + std::pair* GetAvailableRenderingBackends(); + std::pair GetCurrentRenderingBackend(); + void SetCurrentRenderingBackend(uint8_t index, std::pair); + const char** GetSupportedTextureFilters(); + void SetResolutionMultiplier(float multiplier); + void SetMSAALevel(uint32_t value); + + void AddWindow(const std::string& category, const std::string& name, WindowDrawFunc drawFunc, bool isEnabled = false, bool isHidden = false); + void EnableWindow(const std::string& name, bool isEnabled = true); + + Ship::GameOverlay* GetGameOverlay(); + + Ship::InputEditor* GetInputEditor(); + void ToggleInputEditorWindow(bool isOpen = true); + void ToggleStatisticsWindow(bool isOpen = true); + + std::shared_ptr GetConsole(); + void ToggleConsoleWindow(bool isOpen = true); + void DispatchConsoleCommand(const std::string& line); + + void RequestCvarSaveOnNextTick(); + ImTextureID GetTextureByID(int id); ImTextureID GetTextureByName(const std::string& name); + void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint = ImVec4(1, 1, 1, 1)); + + void ShowCursor(bool hide, Dialogues w); void BeginGroupPanel(const char* name, const ImVec2 & size = ImVec2(0.0f, 0.0f)); void EndGroupPanel(float minHeight = 0.0f); - std::string BreakTooltip(const char* text, int lineLength = 60); - std::string BreakTooltip(const std::string& text, int lineLength = 60); - void InsertPadding(float extraVerticalPadding = 0.0f); - void PaddedSeparator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f, float extraVerticalBottomPadding = 0.0f); - void PaddedEnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = false, bool padTop = true, bool padBottom = true); - void PaddedEnhancementCheckbox(const char* text, const char* cvarName, bool padTop = true, bool padBottom = true, bool disabled = false, const char* disabledTooltipText = "", ImGuiCheckboxGraphics disabledGraphic = ImGuiCheckboxGraphics::Cross); - void PaddedText(const char* text, bool padTop = true, bool padBottom = true); - std::string GetWindowButtonText(const char* text, bool menuOpen); } #endif diff --git a/libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/sohconsole_sink.h b/libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/sohconsole_sink.h index 8a629aa1a..4bb8cf2c6 100644 --- a/libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/sohconsole_sink.h +++ b/libultraship/libultraship/Lib/spdlog/include/spdlog/sinks/sohconsole_sink.h @@ -41,8 +41,8 @@ protected: } formatted.push_back('\0'); const char* msg_output = formatted.data(); - if (CVar_GetS32("gSinkEnabled", 0) && SohImGui::console->IsOpened()) { - SohImGui::console->Append("Logs", msg.level, "%s", msg_output); + if (CVar_GetS32("gSinkEnabled", 0) && SohImGui::GetConsole()->IsOpened()) { + SohImGui::GetConsole()->Append("Logs", msg.level, "%s", msg_output); } } @@ -57,4 +57,4 @@ private: using soh_sink_mt = sohconsole_sink; using soh_sink_st = sohconsole_sink; } // namespace sinks -} // namespace spdlog \ No newline at end of file +} // namespace spdlog diff --git a/libultraship/libultraship/Window.cpp b/libultraship/libultraship/Window.cpp index b9e84fd60..36a10b505 100644 --- a/libultraship/libultraship/Window.cpp +++ b/libultraship/libultraship/Window.cpp @@ -86,7 +86,7 @@ extern "C" { pad->gyro_x = 0; pad->gyro_y = 0; - if (SohImGui::controller->IsOpened()) return; + if (SohImGui::GetInputEditor()->IsOpened()) return; Ship::Window::GetInstance()->GetControlDeck()->WriteToPad(pad); Ship::ExecuteHooks(pad); diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index 50bf5fa69..e903ee541 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -162,6 +162,7 @@ set(Header_Files__soh__Enhancements__controls ) source_group("Header Files\\soh\\Enhancements\\controls" FILES ${Header_Files__soh__Enhancements__controls}) + set(Header_Files__soh__Enhancements__cosmetics "soh/Enhancements/cosmetics/CosmeticsEditor.h" ) @@ -172,7 +173,6 @@ set(Header_Files__soh__Enhancements__debugger "soh/Enhancements/debugger/colViewer.h" "soh/Enhancements/debugger/debugger.h" "soh/Enhancements/debugger/debugSaveEditor.h" - "soh/Enhancements/debugger/ImGuiHelpers.h" ) source_group("Header Files\\soh\\Enhancements\\debugger" FILES ${Header_Files__soh__Enhancements__debugger}) @@ -251,6 +251,10 @@ set(Source_Files__soh "soh/z_message_OTR.cpp" "soh/z_play_otr.cpp" "soh/z_scene_otr.cpp" + "soh/GameMenuBar.hpp" + "soh/GameMenuBar.cpp" + "soh/UIWidgets.hpp" + "soh/UIWidgets.cpp" ) source_group("Source Files\\soh" FILES ${Source_Files__soh}) @@ -277,7 +281,6 @@ set(Source_Files__soh__Enhancements__debugger "soh/Enhancements/debugger/colViewer.cpp" "soh/Enhancements/debugger/debugger.cpp" "soh/Enhancements/debugger/debugSaveEditor.cpp" - "soh/Enhancements/debugger/ImGuiHelpers.cpp" ) source_group("Source Files\\soh\\Enhancements\\debugger" FILES ${Source_Files__soh__Enhancements__debugger}) @@ -1669,14 +1672,13 @@ set(SDL2-INCLUDE ${SDL2_INCLUDE_DIRS}) target_include_directories(${PROJECT_NAME} PRIVATE assets ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${CMAKE_CURRENT_SOURCE_DIR}/src/ + ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship + ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/ ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/libjpeg/include/ - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/ ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/spdlog/include/ + ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/Fast3D/U64/PR ${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPDUtils - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/Fast3D/U64 - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/Fast3D/U64/PR ${SDL2-INCLUDE} - ${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/ ${CMAKE_CURRENT_SOURCE_DIR}/assets/ . ) diff --git a/soh/include/global.h b/soh/include/global.h index 65203c1aa..aa904984f 100644 --- a/soh/include/global.h +++ b/soh/include/global.h @@ -6,7 +6,7 @@ #include "macros.h" #include "soh/OTRGlobals.h" #include "soh/Enhancements/gameconsole.h" -#include "Cvar.h" +#include diff --git a/soh/include/macros.h b/soh/include/macros.h index 1822cb1d6..e726d9f00 100644 --- a/soh/include/macros.h +++ b/soh/include/macros.h @@ -1,7 +1,7 @@ #ifndef MACROS_H #define MACROS_H -#include "endianness.h" +#include #define ARRAY_COUNT(arr) (s32)(sizeof(arr) / sizeof(arr[0])) #define ARRAY_COUNTU(arr) (u32)(sizeof(arr) / sizeof(arr[0])) diff --git a/soh/include/z64.h b/soh/include/z64.h index 1f0bbc25c..7264b663b 100644 --- a/soh/include/z64.h +++ b/soh/include/z64.h @@ -26,7 +26,7 @@ #include "z64interface.h" #include "sequence.h" #include "sfx.h" -#include "color.h" +#include #include "ichain.h" #include "regs.h" diff --git a/soh/include/z64audio.h b/soh/include/z64audio.h index e821d7f17..8f7b8f2b4 100644 --- a/soh/include/z64audio.h +++ b/soh/include/z64audio.h @@ -1,7 +1,7 @@ #ifndef Z64_AUDIO_H #define Z64_AUDIO_H -#include "endianness.h" +#include #define MK_CMD(b0,b1,b2,b3) ((((b0) & 0xFF) << 0x18) | (((b1) & 0xFF) << 0x10) | (((b2) & 0xFF) << 0x8) | (((b3) & 0xFF) << 0)) @@ -815,7 +815,7 @@ typedef struct { /* 0x0E */ u8 ttl; // duration after which the DMA can be discarded } SampleDma; // size = 0x10 -#include +#include typedef struct { /* 0x0000 */ char unk_0000; @@ -1122,4 +1122,4 @@ float Audio_GetGameVolume(int player_id); #ifdef __cplusplus } #endif -#endif \ No newline at end of file +#endif diff --git a/soh/include/z64effect.h b/soh/include/z64effect.h index 861eb9070..7b364f0ea 100644 --- a/soh/include/z64effect.h +++ b/soh/include/z64effect.h @@ -1,7 +1,7 @@ #ifndef Z64EFFECT_H #define Z64EFFECT_H -#include "color.h" +#include struct GraphicsContext; struct GlobalContext; diff --git a/soh/include/z64light.h b/soh/include/z64light.h index 639490022..d642a7364 100644 --- a/soh/include/z64light.h +++ b/soh/include/z64light.h @@ -4,7 +4,7 @@ #include "ultra64.h" #include "ultra64/gbi.h" #include "z64math.h" -#include "color.h" +#include typedef struct { /* 0x0 */ s16 x; diff --git a/soh/include/z64transition.h b/soh/include/z64transition.h index 2adb6f604..9c93e44b7 100644 --- a/soh/include/z64transition.h +++ b/soh/include/z64transition.h @@ -2,7 +2,7 @@ #define Z64TRANSITION_H #include "ultra64.h" -#include "color.h" +#include typedef struct { f32 unk_0; diff --git a/soh/soh/Enhancements/controls/GameControlEditor.cpp b/soh/soh/Enhancements/controls/GameControlEditor.cpp index ee8e33dea..f494711e6 100644 --- a/soh/soh/Enhancements/controls/GameControlEditor.cpp +++ b/soh/soh/Enhancements/controls/GameControlEditor.cpp @@ -6,12 +6,14 @@ #include #include -#include "Lib/ImGui/imgui.h" -#include "Lib/ImGui/imgui_internal.h" -#include "Cvar.h" -#include "UltraController.h" -#include "Utils/StringHelper.h" -#include "../libultraship/ImGuiImpl.h" +#include +#include +#include +#include +#include +#include + +#include "../../UIWidgets.hpp" namespace GameControlEditor { const ImGuiTableFlags PANEL_TABLE_FLAGS = @@ -50,7 +52,11 @@ namespace GameControlEditor { // place the ? button to the most of the right side of the cell it is using. ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 15); ImGui::SmallButton("?"); - SohImGui::Tooltip(helptext.c_str()); + + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("%s", helptext.c_str()); + } + if (sameline) { //I do not use ImGui::SameLine(); because it make some element vanish. ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 22); @@ -119,7 +125,7 @@ namespace GameControlEditor { preview = "Unknown"; } - SohImGui::InsertPadding(); + UIWidgets::Spacer(0); ImVec2 cursorPos = ImGui::GetCursorPos(); ImVec2 textSize = ImGui::CalcTextSize(mapping.label); ImGui::SetCursorPosY(cursorPos.y + textSize.y / 4); @@ -140,7 +146,7 @@ namespace GameControlEditor { } ImGui::EndCombo(); } - SohImGui::InsertPadding(); + UIWidgets::Spacer(0); } void DrawOcarinaControlPanel() { @@ -157,7 +163,7 @@ namespace GameControlEditor { ImVec2 cursor = ImGui::GetCursorPos(); ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); - SohImGui::EnhancementCheckbox("Customize Ocarina Controls", "gCustomOcarinaControls"); + UIWidgets::EnhancementCheckbox("Customize Ocarina Controls", "gCustomOcarinaControls"); if (CVar_GetS32("gCustomOcarinaControls", 0) == 1) { if (ImGui::BeginTable("tableCustomMainOcarinaControls", 2, ImGuiTableFlags_SizingStretchProp)) { @@ -194,10 +200,10 @@ namespace GameControlEditor { ImGui::EndTable(); } } else { - SohImGui::InsertPadding(); + UIWidgets::Spacer(0); ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); ImGui::TextWrapped("To modify the main ocarina controls, select the \"Customize Ocarina Controls\" checkbox."); - SohImGui::InsertPadding(); + UIWidgets::Spacer(0); } SohImGui::BeginGroupPanel("Alternate controls", ImGui::GetContentRegionAvail()); @@ -206,9 +212,9 @@ namespace GameControlEditor { ImGui::TableSetupColumn("Right stick", PANEL_TABLE_COLUMN_FLAGS); TableHelper::InitHeader(false); ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); - SohImGui::EnhancementCheckbox("Play with D-pad", "gDpadOcarina"); + UIWidgets::EnhancementCheckbox("Play with D-pad", "gDpadOcarina"); TableHelper::NextCol(); - SohImGui::EnhancementCheckbox("Play with camera stick", "gRStickOcarina"); + UIWidgets::EnhancementCheckbox("Play with camera stick", "gRStickOcarina"); ImGui::EndTable(); } SohImGui::EndGroupPanel(); @@ -223,17 +229,17 @@ namespace GameControlEditor { ImVec2 cursor = ImGui::GetCursorPos(); ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); - SohImGui::PaddedEnhancementCheckbox("Invert Camera X Axis", "gInvertXAxis"); - SohImGui::Tooltip("Inverts the Camera X Axis in:\n-Free camera\n-C-Up view\n-Weapon Aiming"); + UIWidgets::PaddedEnhancementCheckbox("Invert Camera X Axis", "gInvertXAxis"); + UIWidgets::Tooltip("Inverts the Camera X Axis in:\n-Free camera\n-C-Up view\n-Weapon Aiming"); ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); - SohImGui::PaddedEnhancementCheckbox("Invert Camera Y Axis", "gInvertYAxis"); - SohImGui::Tooltip("Inverts the Camera Y Axis in:\n-Free camera\n-C-Up view\n-Weapon Aiming"); + UIWidgets::PaddedEnhancementCheckbox("Invert Camera Y Axis", "gInvertYAxis"); + UIWidgets::Tooltip("Inverts the Camera Y Axis in:\n-Free camera\n-C-Up view\n-Weapon Aiming"); ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); - SohImGui::PaddedEnhancementCheckbox("Right Stick Aiming", "gRightStickAiming"); - SohImGui::Tooltip("Allows for aiming with the rights stick when:\n-Aiming in the C-Up view\n-Aiming with weapons"); + UIWidgets::PaddedEnhancementCheckbox("Right Stick Aiming", "gRightStickAiming"); + UIWidgets::Tooltip("Allows for aiming with the rights stick when:\n-Aiming in the C-Up view\n-Aiming with weapons"); ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); - SohImGui::PaddedEnhancementCheckbox("Auto-Center First Person View", "gAutoCenterView"); - SohImGui::Tooltip("Prevents the C-Up view from auto-centering, allowing for Gyro Aiming"); + UIWidgets::PaddedEnhancementCheckbox("Auto-Center First Person View", "gAutoCenterView"); + UIWidgets::Tooltip("Prevents the C-Up view from auto-centering, allowing for Gyro Aiming"); } void DrawUI(bool& open) { diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index b04f30e35..5782119f1 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -1,11 +1,13 @@ #include "CosmeticsEditor.h" -#include "../libultraship/ImGuiImpl.h" +#include #include -#include +#include #include #include -#include +#include + +#include "../../UIWidgets.hpp" const char* RainbowColorCvarList[] = { //This is the list of possible CVars that has rainbow effect. @@ -51,9 +53,9 @@ void GetRandomColorRGB(CosmeticsColorSection* ColorSection, int SectionSize){ std::string cvarName = Element->CvarName; std::string Cvar_RBM = cvarName + "RBM"; colors = RANDOMIZE_32(255); - NewColors.r = SohImGui::ClampFloatToInt(colors.x * 255, 0, 255); - NewColors.g = SohImGui::ClampFloatToInt(colors.y * 255, 0, 255); - NewColors.b = SohImGui::ClampFloatToInt(colors.z * 255, 0, 255); + NewColors.r = fmin(fmax(colors.x * 255, 0), 255); + NewColors.g = fmin(fmax(colors.y * 255, 0), 255); + NewColors.b = fmin(fmax(colors.z * 255, 0), 255); Element->ModifiedColor = colors; CVar_SetRGBA(cvarName.c_str(), NewColors); CVar_SetS32(Cvar_RBM.c_str(), 0); @@ -149,9 +151,9 @@ void LoadRainbowColor(bool& open) { case 6: NewColor.x = 255; NewColor.y = 0; NewColor.z = a; break; } Color_RGBA8 NewColorRGB = { - SohImGui::ClampFloatToInt(NewColor.x, 0, 255), - SohImGui::ClampFloatToInt(NewColor.y, 0, 255), - SohImGui::ClampFloatToInt(NewColor.z, 0, 255), + fmin(fmax(NewColor.x, 0), 255), + fmin(fmax(NewColor.y, 0), 255), + fmin(fmax(NewColor.z, 0), 255), 255 }; if (CVar_GetS32(Cvar_RBM.c_str(), 0) != 0) { @@ -187,7 +189,7 @@ void Draw_HelpIcon(const std::string& helptext, bool sameline = true, int Pos = ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x-60); ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 15); ImGui::SmallButton("?"); - SohImGui::Tooltip(helptext.c_str()); + UIWidgets::Tooltip(helptext.c_str()); if (sameline) { //I do not use ImGui::SameLine(); because it make some element vanish. ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 22); @@ -197,96 +199,96 @@ void Draw_HelpIcon(const std::string& helptext, bool sameline = true, int Pos = void DrawUseMarginsSlider(const std::string ElementName, const std::string CvarName){ std::string CvarLabel = CvarName + "UseMargins"; std::string Label = ElementName + " use margins"; - SohImGui::EnhancementCheckbox(Label.c_str(), CvarLabel.c_str()); - SohImGui::Tooltip("Using this allow you move the element with General margins sliders"); + UIWidgets::EnhancementCheckbox(Label.c_str(), CvarLabel.c_str()); + UIWidgets::Tooltip("Using this allow you move the element with General margins sliders"); } void DrawPositionsRadioBoxes(const std::string CvarName, bool NoAnchorEnabled = true){ std::string CvarLabel = CvarName + "PosType"; - SohImGui::EnhancementRadioButton("Original position", CvarLabel.c_str(), 0); - SohImGui::Tooltip("This will use original intended elements position"); - SohImGui::EnhancementRadioButton("Anchor to the left", CvarLabel.c_str(), 1); - SohImGui::Tooltip("This will make your elements follow the left side of your game window"); - SohImGui::EnhancementRadioButton("Anchor to the right", CvarLabel.c_str(), 2); - SohImGui::Tooltip("This will make your elements follow the right side of your game window"); + UIWidgets::EnhancementRadioButton("Original position", CvarLabel.c_str(), 0); + UIWidgets::Tooltip("This will use original intended elements position"); + UIWidgets::EnhancementRadioButton("Anchor to the left", CvarLabel.c_str(), 1); + UIWidgets::Tooltip("This will make your elements follow the left side of your game window"); + UIWidgets::EnhancementRadioButton("Anchor to the right", CvarLabel.c_str(), 2); + UIWidgets::Tooltip("This will make your elements follow the right side of your game window"); if (NoAnchorEnabled) { - SohImGui::EnhancementRadioButton("No anchors", CvarLabel.c_str(), 3); - SohImGui::Tooltip("This will make your elements to not follow any side\nBetter used for center elements"); + UIWidgets::EnhancementRadioButton("No anchors", CvarLabel.c_str(), 3); + UIWidgets::Tooltip("This will make your elements to not follow any side\nBetter used for center elements"); } - SohImGui::EnhancementRadioButton("Hidden", CvarLabel.c_str(), 4); - SohImGui::Tooltip("This will make your elements hidden"); + UIWidgets::EnhancementRadioButton("Hidden", CvarLabel.c_str(), 4); + UIWidgets::Tooltip("This will make your elements hidden"); } void DrawTransitions(const std::string CvarName){ - SohImGui::EnhancementRadioButton("Really slow fade (white)", CvarName.c_str(), 8); + UIWidgets::EnhancementRadioButton("Really slow fade (white)", CvarName.c_str(), 8); Table_NextCol(); - SohImGui::EnhancementRadioButton("Really slow fade (black)", CvarName.c_str(), 7); + UIWidgets::EnhancementRadioButton("Really slow fade (black)", CvarName.c_str(), 7); Table_NextLine(); - SohImGui::EnhancementRadioButton("Slow fade (white)", CvarName.c_str(), 10); + UIWidgets::EnhancementRadioButton("Slow fade (white)", CvarName.c_str(), 10); Table_NextCol(); - SohImGui::EnhancementRadioButton("Slow fade (black)", CvarName.c_str(), 9); + UIWidgets::EnhancementRadioButton("Slow fade (black)", CvarName.c_str(), 9); Table_NextLine(); - SohImGui::EnhancementRadioButton("Normal fade (white)", CvarName.c_str(), 3); + UIWidgets::EnhancementRadioButton("Normal fade (white)", CvarName.c_str(), 3); Table_NextCol(); - SohImGui::EnhancementRadioButton("Normal fade (black)", CvarName.c_str(), 2); + UIWidgets::EnhancementRadioButton("Normal fade (black)", CvarName.c_str(), 2); Table_NextLine(); - SohImGui::EnhancementRadioButton("Fast fade (white)", CvarName.c_str(), 5); + UIWidgets::EnhancementRadioButton("Fast fade (white)", CvarName.c_str(), 5); Table_NextCol(); - SohImGui::EnhancementRadioButton("Fast fade (black)", CvarName.c_str(), 4); + UIWidgets::EnhancementRadioButton("Fast fade (black)", CvarName.c_str(), 4); Table_NextLine(); - SohImGui::EnhancementRadioButton("Fast circle (white)", CvarName.c_str(), 40); + UIWidgets::EnhancementRadioButton("Fast circle (white)", CvarName.c_str(), 40); Table_NextCol(); - SohImGui::EnhancementRadioButton("Normal circle (black)", CvarName.c_str(), 32); + UIWidgets::EnhancementRadioButton("Normal circle (black)", CvarName.c_str(), 32); Table_NextLine(); - SohImGui::EnhancementRadioButton("Slow circle (white)", CvarName.c_str(), 41); + UIWidgets::EnhancementRadioButton("Slow circle (white)", CvarName.c_str(), 41); Table_NextCol(); - SohImGui::EnhancementRadioButton("Slow circle (black)", CvarName.c_str(), 33); + UIWidgets::EnhancementRadioButton("Slow circle (black)", CvarName.c_str(), 33); Table_NextLine(); - SohImGui::EnhancementRadioButton("Fast noise circle (white)", CvarName.c_str(), 42); + UIWidgets::EnhancementRadioButton("Fast noise circle (white)", CvarName.c_str(), 42); Table_NextCol(); - SohImGui::EnhancementRadioButton("Fast noise circle (black)", CvarName.c_str(), 34); + UIWidgets::EnhancementRadioButton("Fast noise circle (black)", CvarName.c_str(), 34); Table_NextLine(); - SohImGui::EnhancementRadioButton("Slow noise circle (white)", CvarName.c_str(), 43); + UIWidgets::EnhancementRadioButton("Slow noise circle (white)", CvarName.c_str(), 43); Table_NextCol(); - SohImGui::EnhancementRadioButton("Slow noise circle (black)", CvarName.c_str(), 35); + UIWidgets::EnhancementRadioButton("Slow noise circle (black)", CvarName.c_str(), 35); Table_NextLine(); - SohImGui::EnhancementRadioButton("Normal waves circle (white)", CvarName.c_str(), 44); + UIWidgets::EnhancementRadioButton("Normal waves circle (white)", CvarName.c_str(), 44); Table_NextCol(); - SohImGui::EnhancementRadioButton("Normal waves circle (black)", CvarName.c_str(), 36); + UIWidgets::EnhancementRadioButton("Normal waves circle (black)", CvarName.c_str(), 36); Table_NextLine(); - SohImGui::EnhancementRadioButton("Slow waves circle (white)", CvarName.c_str(), 45); + UIWidgets::EnhancementRadioButton("Slow waves circle (white)", CvarName.c_str(), 45); Table_NextCol(); - SohImGui::EnhancementRadioButton("Slow waves circle (black)", CvarName.c_str(), 37); + UIWidgets::EnhancementRadioButton("Slow waves circle (black)", CvarName.c_str(), 37); Table_NextLine(); - SohImGui::EnhancementRadioButton("Normal close circle (white)", CvarName.c_str(), 46); + UIWidgets::EnhancementRadioButton("Normal close circle (white)", CvarName.c_str(), 46); Table_NextCol(); - SohImGui::EnhancementRadioButton("Normal close circle (black)", CvarName.c_str(), 38); + UIWidgets::EnhancementRadioButton("Normal close circle (black)", CvarName.c_str(), 38); Table_NextLine(); - SohImGui::EnhancementRadioButton("Slow close circle (white)", CvarName.c_str(), 47); + UIWidgets::EnhancementRadioButton("Slow close circle (white)", CvarName.c_str(), 47); Table_NextCol(); - SohImGui::EnhancementRadioButton("Slow close circle (black)", CvarName.c_str(), 39); + UIWidgets::EnhancementRadioButton("Slow close circle (black)", CvarName.c_str(), 39); Table_NextLine(); - SohImGui::EnhancementRadioButton("Super fast circle (white)", CvarName.c_str(), 56); + UIWidgets::EnhancementRadioButton("Super fast circle (white)", CvarName.c_str(), 56); Table_NextCol(); - SohImGui::EnhancementRadioButton("Super fast circle (black)", CvarName.c_str(), 58); + UIWidgets::EnhancementRadioButton("Super fast circle (black)", CvarName.c_str(), 58); Table_NextLine(); - SohImGui::EnhancementRadioButton("Super fast noise circle (white)", CvarName.c_str(), 57); + UIWidgets::EnhancementRadioButton("Super fast noise circle (white)", CvarName.c_str(), 57); Table_NextCol(); - SohImGui::EnhancementRadioButton("Super fast noise circle (black)", CvarName.c_str(), 59); + UIWidgets::EnhancementRadioButton("Super fast noise circle (black)", CvarName.c_str(), 59); } void DrawPositionSlider(const std::string CvarName, int MinY, int MaxY, int MinX, int MaxX){ std::string PosXCvar = CvarName+"PosX"; std::string PosYCvar = CvarName+"PosY"; std::string InvisibleLabelX = "##"+PosXCvar; std::string InvisibleLabelY = "##"+PosYCvar; - SohImGui::EnhancementSliderInt("Up <-> Down : %d", InvisibleLabelY.c_str(), PosYCvar.c_str(), MinY, MaxY, "", 0, true); - SohImGui::Tooltip("This slider is used to move Up and Down your elements."); - SohImGui::EnhancementSliderInt("Left <-> Right : %d", InvisibleLabelX.c_str(), PosXCvar.c_str(), MinX, MaxX, "", 0, true); - SohImGui::Tooltip("This slider is used to move Left and Right your elements."); + UIWidgets::EnhancementSliderInt("Up <-> Down : %d", InvisibleLabelY.c_str(), PosYCvar.c_str(), MinY, MaxY, "", 0, true); + UIWidgets::Tooltip("This slider is used to move Up and Down your elements."); + UIWidgets::EnhancementSliderInt("Left <-> Right : %d", InvisibleLabelX.c_str(), PosXCvar.c_str(), MinX, MaxX, "", 0, true); + UIWidgets::Tooltip("This slider is used to move Left and Right your elements."); } void DrawScaleSlider(const std::string CvarName,float DefaultValue){ std::string InvisibleLabel = "##"+CvarName; std::string CvarLabel = CvarName+"Scale"; //Disabled for now. feature not done and several fixes needed to be merged. - //SohImGui::EnhancementSliderFloat("Scale : %dx", InvisibleLabel.c_str(), CvarLabel.c_str(), 0.1f, 3.0f,"",DefaultValue,true,true); + //UIWidgets::EnhancementSliderFloat("Scale : %dx", InvisibleLabel.c_str(), CvarLabel.c_str(), 0.1f, 3.0f,"",DefaultValue,true,true); } void DrawColorSection(CosmeticsColorSection* ColorSection, int SectionSize) { for (s16 i = 0; i < SectionSize; i++) { @@ -308,7 +310,7 @@ void DrawColorSection(CosmeticsColorSection* ColorSection, int SectionSize) { Table_NextLine(); } Draw_HelpIcon(Tooltip.c_str()); - SohImGui::EnhancementColor(Name.c_str(), Cvar.c_str(), ModifiedColor, DefaultColor, canRainbow, hasAlpha, sameLine); + UIWidgets::EnhancementColor(Name.c_str(), Cvar.c_str(), ModifiedColor, DefaultColor, canRainbow, hasAlpha, sameLine); } } void DrawRandomizeResetButton(const std::string Identifier, CosmeticsColorSection* ColorSection, int SectionSize, bool isAllCosmetics = false){ @@ -335,21 +337,21 @@ void DrawRandomizeResetButton(const std::string Identifier, CosmeticsColorSectio CVar_SetS32("gCCparated", 1); GetRandomColorRGB(ColorSection, SectionSize); } - SohImGui::Tooltip(Tooltip_RNG.c_str()); + UIWidgets::Tooltip(Tooltip_RNG.c_str()); Table_NextCol(); if(ImGui::Button(Reset_BtnText.c_str(), ImVec2( ImGui::GetContentRegionAvail().x, 20.0f))){ GetDefaultColorRGB(ColorSection, SectionSize); } - SohImGui::Tooltip("Enable/Disable custom Link's tunics colors\nIf disabled you will have original colors for Link's tunics."); - SohImGui::Tooltip(Tooltip_RNG.c_str()); + UIWidgets::Tooltip("Enable/Disable custom Link's tunics colors\nIf disabled you will have original colors for Link's tunics."); + UIWidgets::Tooltip(Tooltip_RNG.c_str()); ImGui::EndTable(); } } void Draw_Npcs(){ DrawRandomizeResetButton("all NPCs", NPCs_section, SECTION_SIZE(NPCs_section)); - SohImGui::EnhancementCheckbox("Custom colors for Navi", "gUseNaviCol"); - SohImGui::Tooltip("Enable/Disable custom Navi colors\nIf disabled, default colors will be used\nColors go into effect when Navi goes back into your pockets"); + UIWidgets::EnhancementCheckbox("Custom colors for Navi", "gUseNaviCol"); + UIWidgets::Tooltip("Enable/Disable custom Navi colors\nIf disabled, default colors will be used\nColors go into effect when Navi goes back into your pockets"); if (CVar_GetS32("gUseNaviCol",0)) { DrawRandomizeResetButton("Navi's", Navi_Section, SECTION_SIZE(Navi_Section)); }; @@ -360,8 +362,8 @@ void Draw_Npcs(){ DrawColorSection(Navi_Section, SECTION_SIZE(Navi_Section)); ImGui::EndTable(); } - SohImGui::EnhancementCheckbox("Custom colors for Keese", "gUseKeeseCol"); - SohImGui::Tooltip("Enable/Disable custom Keese element colors\nIf disabled, default element colors will be used\nColors go into effect when Keese respawn (or when the room is reloaded)"); + UIWidgets::EnhancementCheckbox("Custom colors for Keese", "gUseKeeseCol"); + UIWidgets::Tooltip("Enable/Disable custom Keese element colors\nIf disabled, default element colors will be used\nColors go into effect when Keese respawn (or when the room is reloaded)"); if (CVar_GetS32("gUseKeeseCol",0) && ImGui::BeginTable("tableKeese", 2, FlagsTable)) { ImGui::TableSetupColumn("Fire colors##Keese", FlagsCell, TablesCellsWidth/2); ImGui::TableSetupColumn("Ice colors##Keese", FlagsCell, TablesCellsWidth/2); @@ -369,8 +371,8 @@ void Draw_Npcs(){ DrawColorSection(Keese_Section, SECTION_SIZE(Keese_Section)); ImGui::EndTable(); } - SohImGui::EnhancementCheckbox("Custom colors for Dogs", "gUseDogsCol"); - SohImGui::Tooltip("Enable/Disable custom colors for the two Dog variants\nIf disabled, default colors will be used"); + UIWidgets::EnhancementCheckbox("Custom colors for Dogs", "gUseDogsCol"); + UIWidgets::Tooltip("Enable/Disable custom colors for the two Dog variants\nIf disabled, default colors will be used"); if (CVar_GetS32("gUseDogsCol",0) && ImGui::BeginTable("tableDogs", 2, FlagsTable)) { ImGui::TableSetupColumn("White Dog color", FlagsCell, TablesCellsWidth/2); ImGui::TableSetupColumn("Brown Dog color", FlagsCell, TablesCellsWidth/2); @@ -381,8 +383,8 @@ void Draw_Npcs(){ } void Draw_ItemsSkills(){ DrawRandomizeResetButton("all skills and items", AllItemsSkills_section, SECTION_SIZE(AllItemsSkills_section)); - SohImGui::EnhancementCheckbox("Custom tunics color", "gUseTunicsCol"); - SohImGui::Tooltip("Enable/Disable custom Link's tunics colors\nIf disabled you will have original colors for Link's tunics."); + UIWidgets::EnhancementCheckbox("Custom tunics color", "gUseTunicsCol"); + UIWidgets::Tooltip("Enable/Disable custom Link's tunics colors\nIf disabled you will have original colors for Link's tunics."); if (CVar_GetS32("gUseTunicsCol",0)) { DrawRandomizeResetButton("Link's tunics", Tunics_Section, SECTION_SIZE(Tunics_Section)); }; @@ -394,7 +396,7 @@ void Draw_ItemsSkills(){ DrawColorSection(Tunics_Section, SECTION_SIZE(Tunics_Section)); ImGui::EndTable(); } - SohImGui::EnhancementCheckbox("Custom arrows colors", "gUseArrowsCol"); + UIWidgets::EnhancementCheckbox("Custom arrows colors", "gUseArrowsCol"); if (CVar_GetS32("gUseArrowsCol",0)) { DrawRandomizeResetButton("elemental arrows", Arrows_section, SECTION_SIZE(Arrows_section)); } @@ -405,7 +407,7 @@ void Draw_ItemsSkills(){ DrawColorSection(Arrows_section, SECTION_SIZE(Arrows_section)); ImGui::EndTable(); } - SohImGui::EnhancementCheckbox("Custom spells colors", "gUseSpellsCol"); + UIWidgets::EnhancementCheckbox("Custom spells colors", "gUseSpellsCol"); if (CVar_GetS32("gUseSpellsCol",0)) { DrawRandomizeResetButton("spells", Spells_section, SECTION_SIZE(Spells_section)); } @@ -416,7 +418,7 @@ void Draw_ItemsSkills(){ DrawColorSection(Spells_section, SECTION_SIZE(Spells_section)); ImGui::EndTable(); } - SohImGui::EnhancementCheckbox("Custom spin attack colors", "gUseChargedCol"); + UIWidgets::EnhancementCheckbox("Custom spin attack colors", "gUseChargedCol"); if (CVar_GetS32("gUseChargedCol",0)) { DrawRandomizeResetButton("spins attack", SpinAtk_section, SECTION_SIZE(SpinAtk_section)); } @@ -427,13 +429,13 @@ void Draw_ItemsSkills(){ DrawColorSection(SpinAtk_section, SECTION_SIZE(SpinAtk_section)); ImGui::EndTable(); } - SohImGui::EnhancementCheckbox("Custom trails color", "gUseTrailsCol"); + UIWidgets::EnhancementCheckbox("Custom trails color", "gUseTrailsCol"); if (CVar_GetS32("gUseTrailsCol",0) && ImGui::BeginTable("tabletrails", 1, FlagsTable)) { ImGui::TableSetupColumn("Custom Trails", FlagsCell, TablesCellsWidth); Table_InitHeader(); DrawColorSection(Trails_section, SECTION_SIZE(Trails_section)); - SohImGui::EnhancementSliderInt("Trails duration: %dx", "##TrailsMul", "gTrailDurantion", 1, 5, ""); - SohImGui::Tooltip("The longer the trails the weirder it become"); + UIWidgets::EnhancementSliderInt("Trails duration: %dx", "##TrailsMul", "gTrailDurantion", 1, 5, ""); + UIWidgets::Tooltip("The longer the trails the weirder it become"); ImGui::NewLine(); ImGui::EndTable(); } @@ -455,18 +457,18 @@ void Draw_Placements(){ if (ImGui::BeginTable("tableMargins", 1, FlagsTable)) { ImGui::TableSetupColumn("General margins settings", FlagsCell, TablesCellsWidth); Table_InitHeader(); - SohImGui::EnhancementSliderInt("Top : %dx", "##UIMARGINT", "gHUDMargin_T", (ImGui::GetWindowViewport()->Size.y/2)*-1, 25, "", 0, true); - SohImGui::EnhancementSliderInt("Left: %dx", "##UIMARGINL", "gHUDMargin_L", -25, ImGui::GetWindowViewport()->Size.x, "", 0, true); - SohImGui::EnhancementSliderInt("Right: %dx", "##UIMARGINR", "gHUDMargin_R", (ImGui::GetWindowViewport()->Size.x)*-1, 25, "", 0, true); - SohImGui::EnhancementSliderInt("Bottom: %dx", "##UIMARGINB", "gHUDMargin_B", (ImGui::GetWindowViewport()->Size.y/2)*-1, 25, "", 0, true); + UIWidgets::EnhancementSliderInt("Top : %dx", "##UIMARGINT", "gHUDMargin_T", (ImGui::GetWindowViewport()->Size.y/2)*-1, 25, "", 0, true); + UIWidgets::EnhancementSliderInt("Left: %dx", "##UIMARGINL", "gHUDMargin_L", -25, ImGui::GetWindowViewport()->Size.x, "", 0, true); + UIWidgets::EnhancementSliderInt("Right: %dx", "##UIMARGINR", "gHUDMargin_R", (ImGui::GetWindowViewport()->Size.x)*-1, 25, "", 0, true); + UIWidgets::EnhancementSliderInt("Bottom: %dx", "##UIMARGINB", "gHUDMargin_B", (ImGui::GetWindowViewport()->Size.y/2)*-1, 25, "", 0, true); SetMarginAll("All margins on",true); - SohImGui::Tooltip("Set most of the element to use margin\nSome elements with default position will not be affected\nElements without Archor or Hidden will not be turned on"); + UIWidgets::Tooltip("Set most of the element to use margin\nSome elements with default position will not be affected\nElements without Archor or Hidden will not be turned on"); ImGui::SameLine(); SetMarginAll("All margins off",false); - SohImGui::Tooltip("Set all of the element to not use margin"); + UIWidgets::Tooltip("Set all of the element to not use margin"); ImGui::SameLine(); ResetPositionAll(); - SohImGui::Tooltip("Revert every element to use their original position and no margins"); + UIWidgets::Tooltip("Revert every element to use their original position and no margins"); ImGui::NewLine(); ImGui::EndTable(); } @@ -775,7 +777,7 @@ void Draw_HUDButtons(){ DrawColorSection(C_Btn_Unified_section, SECTION_SIZE(C_Btn_Unified_section)); ImGui::EndTable(); } - SohImGui::EnhancementCheckbox("C-Buttons use separate colors", "gCCparated"); + UIWidgets::EnhancementCheckbox("C-Buttons use separate colors", "gCCparated"); if (CVar_GetS32("gCCparated",0) && ImGui::CollapsingHeader("C Button individual colors")) { if (ImGui::BeginTable("tableBTN_CSep", 1, FlagsTable)) { ImGui::TableSetupColumn("C-Buttons individual colors", FlagsCell, TablesCellsWidth); @@ -813,19 +815,19 @@ void Draw_General(){ ImGui::TableSetupColumn("Custom Schemes", FlagsCell, TablesCellsWidth); Table_InitHeader(); Draw_HelpIcon("Change interface color to N64 style"); - SohImGui::EnhancementRadioButton("N64 Colors", "gHudColors", 0); + UIWidgets::EnhancementRadioButton("N64 Colors", "gHudColors", 0); Table_NextCol(); Draw_HelpIcon("Change interface color to GameCube style"); - SohImGui::EnhancementRadioButton("GCN Colors", "gHudColors", 1); + UIWidgets::EnhancementRadioButton("GCN Colors", "gHudColors", 1); Table_NextCol(); Draw_HelpIcon("Lets you change every interface color to your liking"); - SohImGui::EnhancementRadioButton("Custom Colors", "gHudColors", 2); + UIWidgets::EnhancementRadioButton("Custom Colors", "gHudColors", 2); ImGui::EndTable(); } if (CVar_GetS32("gHudColors",0) ==2 ){ DrawRandomizeResetButton("interface (excluding buttons)", Misc_Interface_section, SECTION_SIZE(Misc_Interface_section)); if (ImGui::CollapsingHeader("Hearts colors")) { - SohImGui::Tooltip("Hearts colors in general\nDD stand for Double Defense"); + UIWidgets::Tooltip("Hearts colors in general\nDD stand for Double Defense"); if (ImGui::BeginTable("tableHearts", 3, FlagsTable | ImGuiTableFlags_Hideable)) { ImGui::TableSetupColumn("Hearts (normal)", ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable, TablesCellsWidth/3); ImGui::TableSetupColumn("Hearts (DD)", ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable, TablesCellsWidth/3); @@ -874,25 +876,25 @@ void Draw_General(){ ImGui::TableSetupColumn("transitionother1", FlagsCell, TablesCellsWidth/2); ImGui::TableSetupColumn("transitionother2", FlagsCell, TablesCellsWidth/2); Table_InitHeader(false); - SohImGui::EnhancementRadioButton("Originals", "gSceneTransitions", 255); - SohImGui::Tooltip("This will make the game use original scenes transitions"); + UIWidgets::EnhancementRadioButton("Originals", "gSceneTransitions", 255); + UIWidgets::Tooltip("This will make the game use original scenes transitions"); Table_NextCol(); - SohImGui::EnhancementRadioButton("None", "gSceneTransitions", 11); - SohImGui::Tooltip("This will make the game use no any scenes transitions"); + UIWidgets::EnhancementRadioButton("None", "gSceneTransitions", 11); + UIWidgets::Tooltip("This will make the game use no any scenes transitions"); Table_NextLine(); - SohImGui::EnhancementRadioButton("Desert mode (persistant)", "gSceneTransitions", 14); - SohImGui::Tooltip("This will make the game use the sand storm scenes transitions that will persist in map"); + UIWidgets::EnhancementRadioButton("Desert mode (persistant)", "gSceneTransitions", 14); + UIWidgets::Tooltip("This will make the game use the sand storm scenes transitions that will persist in map"); Table_NextCol(); - SohImGui::EnhancementRadioButton("Desert mode (non persistant)", "gSceneTransitions", 15); - SohImGui::Tooltip("This will make the game use the sand storm scenes transitions"); + UIWidgets::EnhancementRadioButton("Desert mode (non persistant)", "gSceneTransitions", 15); + UIWidgets::Tooltip("This will make the game use the sand storm scenes transitions"); Table_NextLine(); - SohImGui::EnhancementRadioButton("Normal fade (green)", "gSceneTransitions", 18); - SohImGui::Tooltip("This will make the game use a greenish fade in/out scenes transitions"); + UIWidgets::EnhancementRadioButton("Normal fade (green)", "gSceneTransitions", 18); + UIWidgets::Tooltip("This will make the game use a greenish fade in/out scenes transitions"); Table_NextCol(); - SohImGui::EnhancementRadioButton("Normal fade (blue)", "gSceneTransitions", 19); - SohImGui::Tooltip("This will make the game use a blue fade in/out scenes transitions"); + UIWidgets::EnhancementRadioButton("Normal fade (blue)", "gSceneTransitions", 19); + UIWidgets::Tooltip("This will make the game use a blue fade in/out scenes transitions"); Table_NextLine(); - SohImGui::EnhancementRadioButton("Triforce", "gSceneTransitions", 1); + UIWidgets::EnhancementRadioButton("Triforce", "gSceneTransitions", 1); ImGui::EndTable(); } if (ImGui::BeginTable("tabletransitionCol", 2, FlagsTable | ImGuiTableFlags_Hideable)) { @@ -948,6 +950,7 @@ void DrawCosmeticsEditor(bool& open) { } ImGui::End(); } + void InitCosmeticsEditor() { //This allow to hide a window without disturbing the player nor adding things in menu //LoadRainbowColor() will this way run in background once it's window is activated @@ -955,4 +958,4 @@ void InitCosmeticsEditor() { SohImGui::AddWindow("Enhancements", "Rainbowfunction", LoadRainbowColor, true, true); //Draw the bar in the menu. SohImGui::AddWindow("Enhancements", "Cosmetics Editor", DrawCosmeticsEditor); -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h index 4b6ea249b..cd104633d 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h @@ -1,5 +1,5 @@ #pragma once -#include "../libultraship/ImGuiImpl.h" +#include #define SECTION_SIZE(arr) (s32)(sizeof(arr) / sizeof(arr[0])) #define RANDOMIZE_32(Max) GetRandomValue(Max); #define CATEGORY_NPC 0 @@ -405,4 +405,4 @@ static CosmeticsColorSection AllItemsSkills_section[]{ void InitCosmeticsEditor();//Init the menu itself void LoadRainbowColor(); -void NewSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0); \ No newline at end of file +void NewSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0); diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index 409f2e4b5..36c9f9ea0 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -1,7 +1,7 @@ #include "debugconsole.h" -#include "../libultraship/ImGuiImpl.h" +#include #include "savestates.h" -#include "Console.h" +#include #include #include @@ -12,8 +12,8 @@ #define PATH_HACK #include -#include "Window.h" -#include "Lib/ImGui/imgui_internal.h" +#include +#include #undef PATH_HACK #undef Path @@ -25,18 +25,18 @@ extern "C" { extern GlobalContext* gGlobalCtx; } -#include "Cvar.h" +#include -#define CMD_REGISTER SohImGui::BindCmd +#define CMD_REGISTER SohImGui::GetConsole()->AddCommand static bool ActorSpawnHandler(std::shared_ptr Console, const std::vector& args) { if ((args.size() != 9) && (args.size() != 3) && (args.size() != 6)) { - SohImGui::console->SendErrorMessage("Not enough arguments passed to actorspawn"); + SohImGui::GetConsole()->SendErrorMessage("Not enough arguments passed to actorspawn"); return CMD_FAILED; } if (gGlobalCtx == nullptr) { - SohImGui::console->SendErrorMessage("GlobalCtx == nullptr"); + SohImGui::GetConsole()->SendErrorMessage("GlobalCtx == nullptr"); return CMD_FAILED; } @@ -72,7 +72,7 @@ static bool ActorSpawnHandler(std::shared_ptr Console, const std: if (Actor_Spawn(&gGlobalCtx->actorCtx, gGlobalCtx, actorId, spawnPoint.pos.x, spawnPoint.pos.y, spawnPoint.pos.z, spawnPoint.rot.x, spawnPoint.rot.y, spawnPoint.rot.z, params) == NULL) { - SohImGui::console->SendErrorMessage("Failed to spawn actor. Actor_Spawn returned NULL"); + SohImGui::GetConsole()->SendErrorMessage("Failed to spawn actor. Actor_Spawn returned NULL"); return CMD_FAILED; } return CMD_SUCCESS; @@ -81,13 +81,13 @@ static bool ActorSpawnHandler(std::shared_ptr Console, const std: static bool KillPlayerHandler(std::shared_ptr Console, const std::vector&) { gSaveContext.health = 0; - SohImGui::console->SendInfoMessage("[SOH] You've met with a terrible fate, haven't you?"); + SohImGui::GetConsole()->SendInfoMessage("[SOH] You've met with a terrible fate, haven't you?"); return CMD_SUCCESS; } static bool SetPlayerHealthHandler(std::shared_ptr Console, const std::vector& args) { if (args.size() != 2) { - SohImGui::console->SendErrorMessage("[SOH] Unexpected arguments passed"); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed"); return CMD_FAILED; } @@ -96,18 +96,18 @@ static bool SetPlayerHealthHandler(std::shared_ptr Console, const try { health = std::stoi(args[1]); } catch (std::invalid_argument const& ex) { - SohImGui::console->SendErrorMessage("[SOH] Health value must be an integer."); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Health value must be an integer."); return CMD_FAILED; } if (health < 0) { - SohImGui::console->SendErrorMessage("[SOH] Health value must be a positive integer"); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Health value must be a positive integer"); return CMD_SUCCESS; } gSaveContext.health = health * 0x10; - SohImGui::console->SendInfoMessage("[SOH] Player health updated to %d", health); + SohImGui::GetConsole()->SendInfoMessage("[SOH] Player health updated to %d", health); return CMD_SUCCESS; } @@ -129,31 +129,31 @@ static bool RuppeHandler(std::shared_ptr Console, const std::vect rupeeAmount = std::stoi(args[1]); } catch (std::invalid_argument const& ex) { - SohImGui::console->SendErrorMessage("[SOH] Rupee count must be an integer."); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Rupee count must be an integer."); return CMD_FAILED; } if (rupeeAmount < 0) { - SohImGui::console->SendErrorMessage("[SOH] Rupee count must be positive"); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Rupee count must be positive"); return CMD_FAILED; } gSaveContext.rupees = rupeeAmount; - SohImGui::console->SendInfoMessage("Set rupee count to %u", rupeeAmount); + SohImGui::GetConsole()->SendInfoMessage("Set rupee count to %u", rupeeAmount); return CMD_SUCCESS; } static bool SetPosHandler(std::shared_ptr Console, const std::vector args) { if (gGlobalCtx == nullptr) { - SohImGui::console->SendErrorMessage("GlobalCtx == nullptr"); + SohImGui::GetConsole()->SendErrorMessage("GlobalCtx == nullptr"); return CMD_FAILED; } Player* player = GET_PLAYER(gGlobalCtx); if (args.size() == 1) { - SohImGui::console->SendInfoMessage("Player position is [ %.2f, %.2f, %.2f ]", player->actor.world.pos.x, + SohImGui::GetConsole()->SendInfoMessage("Player position is [ %.2f, %.2f, %.2f ]", player->actor.world.pos.x, player->actor.world.pos.y, player->actor.world.pos.z); return CMD_SUCCESS; @@ -165,7 +165,7 @@ static bool SetPosHandler(std::shared_ptr Console, const std::vec player->actor.world.pos.y = std::stof(args[2]); player->actor.world.pos.z = std::stof(args[3]); - SohImGui::console->SendInfoMessage("Set player position to [ %.2f, %.2f, %.2f ]", player->actor.world.pos.x, + SohImGui::GetConsole()->SendInfoMessage("Set player position to [ %.2f, %.2f, %.2f ]", player->actor.world.pos.x, player->actor.world.pos.y, player->actor.world.pos.z); return CMD_SUCCESS; @@ -173,7 +173,7 @@ static bool SetPosHandler(std::shared_ptr Console, const std::vec static bool ResetHandler(std::shared_ptr Console, std::vector args) { if (gGlobalCtx == nullptr) { - SohImGui::console->SendErrorMessage("GlobalCtx == nullptr"); + SohImGui::GetConsole()->SendErrorMessage("GlobalCtx == nullptr"); return CMD_FAILED; } @@ -194,7 +194,7 @@ const static std::map ammoItems{ static bool AmmoHandler(std::shared_ptr Console, const std::vector& args) { if (args.size() != 3) { - SohImGui::console->SendErrorMessage("[SOH] Unexpected arguments passed"); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed"); return CMD_FAILED; } @@ -203,19 +203,19 @@ static bool AmmoHandler(std::shared_ptr Console, const std::vecto try { count = std::stoi(args[2]); } catch (std::invalid_argument const& ex) { - SohImGui::console->SendErrorMessage("Ammo count must be an integer"); + SohImGui::GetConsole()->SendErrorMessage("Ammo count must be an integer"); return CMD_FAILED; } if (count < 0) { - SohImGui::console->SendErrorMessage("Ammo count must be positive"); + SohImGui::GetConsole()->SendErrorMessage("Ammo count must be positive"); return CMD_FAILED; } const auto& it = ammoItems.find(args[1]); if (it == ammoItems.end()) { - SohImGui::console->SendErrorMessage("Invalid item passed"); + SohImGui::GetConsole()->SendErrorMessage("Invalid item passed"); return CMD_FAILED; } @@ -237,7 +237,7 @@ const static std::map bottleItems{ static bool BottleHandler(std::shared_ptr Console, const std::vector& args) { if (args.size() != 3) { - SohImGui::console->SendErrorMessage("[SOH] Unexpected arguments passed"); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed"); return CMD_FAILED; } @@ -245,19 +245,19 @@ static bool BottleHandler(std::shared_ptr Console, const std::vec try { slot = std::stoi(args[2]); } catch (std::invalid_argument const& ex) { - SohImGui::console->SendErrorMessage("[SOH] Bottle slot must be an integer."); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Bottle slot must be an integer."); return CMD_FAILED; } if ((slot < 1) || (slot > 4)) { - SohImGui::console->SendErrorMessage("Invalid slot passed"); + SohImGui::GetConsole()->SendErrorMessage("Invalid slot passed"); return CMD_FAILED; } const auto& it = bottleItems.find(args[1]); if (it == bottleItems.end()) { - SohImGui::console->SendErrorMessage("Invalid item passed"); + SohImGui::GetConsole()->SendErrorMessage("Invalid item passed"); return CMD_FAILED; } @@ -269,7 +269,7 @@ static bool BottleHandler(std::shared_ptr Console, const std::vec static bool BHandler(std::shared_ptr Console, const std::vector& args) { if (args.size() != 2) { - SohImGui::console->SendErrorMessage("[SOH] Unexpected arguments passed"); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed"); return CMD_FAILED; } @@ -279,7 +279,7 @@ static bool BHandler(std::shared_ptr Console, const std::vector Console, const std::vector& args) { if (args.size() != 3) { - SohImGui::console->SendErrorMessage("[SOH] Unexpected arguments passed"); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed"); return CMD_FAILED; } @@ -290,7 +290,7 @@ static bool ItemHandler(std::shared_ptr Console, const std::vecto static bool EntranceHandler(std::shared_ptr Console, const std::vector& args) { if (args.size() != 2) { - SohImGui::console->SendErrorMessage("[SOH] Unexpected arguments passed"); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed"); return CMD_FAILED; } @@ -299,7 +299,7 @@ static bool EntranceHandler(std::shared_ptr Console, const std::v try { entrance = std::stoi(args[1], nullptr, 16); } catch (std::invalid_argument const& ex) { - SohImGui::console->SendErrorMessage("[SOH] Entrance value must be a Hex number."); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Entrance value must be a Hex number."); return CMD_FAILED; } @@ -319,7 +319,7 @@ static bool VoidHandler(std::shared_ptr Console, const std::vecto gGlobalCtx->fadeTransition = 2; gSaveContext.nextTransition = 2; } else { - SohImGui::console->SendErrorMessage("gGlobalCtx == nullptr"); + SohImGui::GetConsole()->SendErrorMessage("gGlobalCtx == nullptr"); return CMD_FAILED; } return CMD_SUCCESS; @@ -332,7 +332,7 @@ static bool ReloadHandler(std::shared_ptr Console, const std::vec gGlobalCtx->fadeTransition = 11; gSaveContext.nextTransition = 11; } else { - SohImGui::console->SendErrorMessage("gGlobalCtx == nullptr"); + SohImGui::GetConsole()->SendErrorMessage("gGlobalCtx == nullptr"); return CMD_FAILED; } return CMD_SUCCESS; @@ -345,11 +345,11 @@ static bool FWHandler(std::shared_ptr Console, const std::vector< gGlobalCtx->nextEntranceIndex = gSaveContext.respawn[RESPAWN_MODE_TOP].entranceIndex; gGlobalCtx->fadeTransition = 5; } else { - SohImGui::console->SendErrorMessage("Farore's wind not set!"); + SohImGui::GetConsole()->SendErrorMessage("Farore's wind not set!"); } } else { - SohImGui::console->SendErrorMessage("gGlobalCtx == nullptr"); + SohImGui::GetConsole()->SendErrorMessage("gGlobalCtx == nullptr"); return CMD_FAILED; } @@ -361,7 +361,7 @@ static bool FileSelectHandler(std::shared_ptr Console, const std: SET_NEXT_GAMESTATE(&gGlobalCtx->state, FileChoose_Init, FileChooseContext); gGlobalCtx->state.running = 0; } else { - SohImGui::console->SendErrorMessage("gGlobalCtx == nullptr"); + SohImGui::GetConsole()->SendErrorMessage("gGlobalCtx == nullptr"); return CMD_FAILED; } return CMD_SUCCESS; @@ -378,10 +378,10 @@ static bool SaveStateHandler(std::shared_ptr Console, const std:: switch (rtn) { case SaveStateReturn::SUCCESS: - SohImGui::console->SendInfoMessage("[SOH] Saved state to slot %u", slot); + SohImGui::GetConsole()->SendInfoMessage("[SOH] Saved state to slot %u", slot); return CMD_SUCCESS; case SaveStateReturn::FAIL_WRONG_GAMESTATE: - SohImGui::console->SendErrorMessage("[SOH] Can not save a state outside of \"GamePlay\""); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Can not save a state outside of \"GamePlay\""); return CMD_FAILED; } } @@ -392,16 +392,16 @@ static bool LoadStateHandler(std::shared_ptr Console, const std:: switch (rtn) { case SaveStateReturn::SUCCESS: - SohImGui::console->SendInfoMessage("[SOH] Loaded state from slot (%u)", slot); + SohImGui::GetConsole()->SendInfoMessage("[SOH] Loaded state from slot (%u)", slot); return CMD_SUCCESS; case SaveStateReturn::FAIL_INVALID_SLOT: - SohImGui::console->SendErrorMessage("[SOH] Invalid State Slot Number (%u)", slot); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Invalid State Slot Number (%u)", slot); return CMD_FAILED; case SaveStateReturn::FAIL_STATE_EMPTY: - SohImGui::console->SendErrorMessage("[SOH] State Slot (%u) is empty", slot); + SohImGui::GetConsole()->SendErrorMessage("[SOH] State Slot (%u) is empty", slot); return CMD_FAILED; case SaveStateReturn::FAIL_WRONG_GAMESTATE: - SohImGui::console->SendErrorMessage("[SOH] Can not load a state outside of \"GamePlay\""); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Can not load a state outside of \"GamePlay\""); return CMD_FAILED; } @@ -409,7 +409,7 @@ static bool LoadStateHandler(std::shared_ptr Console, const std:: static bool StateSlotSelectHandler(std::shared_ptr Console, const std::vector& args) { if (args.size() != 2) { - SohImGui::console->SendErrorMessage("[SOH] Unexpected arguments passed"); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed"); return CMD_FAILED; } int slot; @@ -417,17 +417,17 @@ static bool StateSlotSelectHandler(std::shared_ptr Console, const try { slot = std::stoi(args[1], nullptr, 10); } catch (std::invalid_argument const& ex) { - SohImGui::console->SendErrorMessage("[SOH] SaveState slot value must be a number."); + SohImGui::GetConsole()->SendErrorMessage("[SOH] SaveState slot value must be a number."); return CMD_FAILED; } if (slot < 0) { - SohImGui::console->SendErrorMessage("[SOH] Invalid slot passed. Slot must be between 0 and 2"); + SohImGui::GetConsole()->SendErrorMessage("[SOH] Invalid slot passed. Slot must be between 0 and 2"); return CMD_FAILED; } OTRGlobals::Instance->gSaveStateMgr->SetCurrentSlot(slot); - SohImGui::console->SendInfoMessage("[SOH] Slot %u selected", + SohImGui::GetConsole()->SendInfoMessage("[SOH] Slot %u selected", OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot()); return CMD_SUCCESS; } @@ -488,7 +488,7 @@ static bool SetCVarHandler(std::shared_ptr Console, const std::ve CVar_Save(); - //SohImGui::console->SendInfoMessage("[SOH] Updated player position to [ %.2f, %.2f, %.2f ]", pos.x, pos.y, pos.z); + //SohImGui::GetConsole()->SendInfoMessage("[SOH] Updated player position to [ %.2f, %.2f, %.2f ]", pos.x, pos.y, pos.z); return CMD_SUCCESS; } @@ -502,17 +502,17 @@ static bool GetCVarHandler(std::shared_ptr Console, const std::ve if (cvar != nullptr) { if (cvar->type == CVarType::S32) - SohImGui::console->SendInfoMessage("[SOH] Variable %s is %i", args[1].c_str(), cvar->value.valueS32); + SohImGui::GetConsole()->SendInfoMessage("[SOH] Variable %s is %i", args[1].c_str(), cvar->value.valueS32); else if (cvar->type == CVarType::Float) - SohImGui::console->SendInfoMessage("[SOH] Variable %s is %f", args[1].c_str(), cvar->value.valueFloat); + SohImGui::GetConsole()->SendInfoMessage("[SOH] Variable %s is %f", args[1].c_str(), cvar->value.valueFloat); else if (cvar->type == CVarType::String) - SohImGui::console->SendInfoMessage("[SOH] Variable %s is %s", args[1].c_str(), cvar->value.valueStr); + SohImGui::GetConsole()->SendInfoMessage("[SOH] Variable %s is %s", args[1].c_str(), cvar->value.valueStr); else if (cvar->type == CVarType::RGBA) - SohImGui::console->SendInfoMessage("[SOH] Variable %s is %08X", args[1].c_str(), cvar->value.valueRGBA); + SohImGui::GetConsole()->SendInfoMessage("[SOH] Variable %s is %08X", args[1].c_str(), cvar->value.valueRGBA); } else { - SohImGui::console->SendInfoMessage("[SOH] Could not find variable %s", args[1].c_str()); + SohImGui::GetConsole()->SendInfoMessage("[SOH] Could not find variable %s", args[1].c_str()); } diff --git a/soh/soh/Enhancements/debugger/ImGuiHelpers.cpp b/soh/soh/Enhancements/debugger/ImGuiHelpers.cpp deleted file mode 100644 index 7fec0de14..000000000 --- a/soh/soh/Enhancements/debugger/ImGuiHelpers.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "ImGuiHelpers.h" -#include "../../../../libultraship/libultraship/ImGuiImpl.h" - -// Adds a text tooltip for the previous ImGui item -void SetLastItemHoverText(const std::string& text) { - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text(SohImGui::BreakTooltip(text, 60).c_str()); - ImGui::EndTooltip(); - } -} - -// Adds a "?" next to the previous ImGui item with a custom tooltip -void InsertHelpHoverText(const std::string& text) { - ImGui::SameLine(); - ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "?"); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text(SohImGui::BreakTooltip(text, 60).c_str()); - ImGui::EndTooltip(); - } -} diff --git a/soh/soh/Enhancements/debugger/ImGuiHelpers.h b/soh/soh/Enhancements/debugger/ImGuiHelpers.h deleted file mode 100644 index 7f01e4580..000000000 --- a/soh/soh/Enhancements/debugger/ImGuiHelpers.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include "../libultraship/Lib/ImGui/imgui.h" - -#include - -void SetLastItemHoverText(const std::string& text); - -void InsertHelpHoverText(const std::string& text); diff --git a/soh/soh/Enhancements/debugger/actorViewer.cpp b/soh/soh/Enhancements/debugger/actorViewer.cpp index 33bc532a0..8c6a4d543 100644 --- a/soh/soh/Enhancements/debugger/actorViewer.cpp +++ b/soh/soh/Enhancements/debugger/actorViewer.cpp @@ -1,13 +1,13 @@ #include "actorViewer.h" #include "../../util.h" -#include "../libultraship/ImGuiImpl.h" -#include "ImGuiHelpers.h" +#include "../../UIWidgets.hpp" +#include #include #include #include #include -#include +#include extern "C" { #include @@ -632,7 +632,7 @@ void DrawActorViewer(bool& open) { if (display.category == ACTORCAT_BOSS || display.category == ACTORCAT_ENEMY) { ImGui::InputScalar("Enemy Health", ImGuiDataType_U8, &display.colChkInfo.health); - InsertHelpHoverText("Some actors might not use this!"); + UIWidgets::InsertHelpHoverText("Some actors might not use this!"); } if (ImGui::Button("Refresh")) { @@ -667,7 +667,7 @@ void DrawActorViewer(bool& open) { rm = TARGET; } } - InsertHelpHoverText("Grabs actor with target arrow above it. You might need C-Up for enemies"); + UIWidgets::InsertHelpHoverText("Grabs actor with target arrow above it. You might need C-Up for enemies"); if (ImGui::Button("Fetch from Held")) { Player* player = GET_PLAYER(gGlobalCtx); fetch = player->heldActor; @@ -678,7 +678,7 @@ void DrawActorViewer(bool& open) { rm = HELD; } } - InsertHelpHoverText("Grabs actor that Link is holding"); + UIWidgets::InsertHelpHoverText("Grabs actor that Link is holding"); if (ImGui::Button("Fetch from Interaction")) { Player* player = GET_PLAYER(gGlobalCtx); fetch = player->interactRangeActor; @@ -689,7 +689,7 @@ void DrawActorViewer(bool& open) { rm = INTERACT; } } - InsertHelpHoverText("Grabs actor from \"interaction range\""); + UIWidgets::InsertHelpHoverText("Grabs actor from \"interaction range\""); ImGui::TreePop(); } @@ -776,4 +776,4 @@ void DrawActorViewer(bool& open) { void InitActorViewer() { SohImGui::AddWindow("Developer Tools", "Actor Viewer", DrawActorViewer); -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/debugger/colViewer.cpp b/soh/soh/Enhancements/debugger/colViewer.cpp index e98ff0399..0146e626f 100644 --- a/soh/soh/Enhancements/debugger/colViewer.cpp +++ b/soh/soh/Enhancements/debugger/colViewer.cpp @@ -1,12 +1,12 @@ #include "colViewer.h" -#include "../libultraship/ImGuiImpl.h" -#include "ImGuiHelpers.h" +#include #include "../../frame_interpolation.h" +#include "../../UIWidgets.hpp" #include #include #include -#include +#include extern "C" { #include @@ -62,42 +62,42 @@ void DrawColViewerWindow(bool& open) { ImGui::End(); return; } - SohImGui::EnhancementCheckbox("Enabled", "gColViewerEnabled"); + UIWidgets::EnhancementCheckbox("Enabled", "gColViewerEnabled"); - SohImGui::EnhancementCombo("Scene", "gColViewerScene", ColRenderSettingNames); - SohImGui::EnhancementCombo("Bg Actors", "gColViewerBgActors", ColRenderSettingNames); - SohImGui::EnhancementCombo("Col Check", "gColViewerColCheck", ColRenderSettingNames); - SohImGui::EnhancementCombo("Waterbox", "gColViewerWaterbox", ColRenderSettingNames); + UIWidgets::EnhancementCombo("Scene", "gColViewerScene", ColRenderSettingNames); + UIWidgets::EnhancementCombo("Bg Actors", "gColViewerBgActors", ColRenderSettingNames); + UIWidgets::EnhancementCombo("Col Check", "gColViewerColCheck", ColRenderSettingNames); + UIWidgets::EnhancementCombo("Waterbox", "gColViewerWaterbox", ColRenderSettingNames); - SohImGui::EnhancementCheckbox("Apply as decal", "gColViewerDecal"); - InsertHelpHoverText("Applies the collision as a decal display. This can be useful if there is z-fighting occuring " + UIWidgets::EnhancementCheckbox("Apply as decal", "gColViewerDecal"); + UIWidgets::InsertHelpHoverText("Applies the collision as a decal display. This can be useful if there is z-fighting occuring " "with the scene geometry, but can cause other artifacts."); - SohImGui::EnhancementCheckbox("Shaded", "gColViewerShaded"); - InsertHelpHoverText("Applies the scene's shading to the collision display."); + UIWidgets::EnhancementCheckbox("Shaded", "gColViewerShaded"); + UIWidgets::InsertHelpHoverText("Applies the scene's shading to the collision display."); // This has to be duplicated in both code paths due to the nature of ImGui::IsItemHovered() const std::string colorHelpText = "View and change the colors used for collision display."; if (ImGui::TreeNode("Colors")) { - InsertHelpHoverText(colorHelpText); + UIWidgets::InsertHelpHoverText(colorHelpText); - SohImGui::EnhancementColor("Normal", "gColViewerColorNormal", scene_col, ImVec4(255, 255, 255, 255), false); - SohImGui::EnhancementColor("Hookshot", "gColViewerColorHookshot", hookshot_col, ImVec4(128, 128, 255, 255), + UIWidgets::EnhancementColor("Normal", "gColViewerColorNormal", scene_col, ImVec4(255, 255, 255, 255), false); + UIWidgets::EnhancementColor("Hookshot", "gColViewerColorHookshot", hookshot_col, ImVec4(128, 128, 255, 255), false); - SohImGui::EnhancementColor("Entrance", "gColViewerColorEntrance", entrance_col, ImVec4(0, 255, 0, 255), false); - SohImGui::EnhancementColor("Special Surface (Grass/Sand/Etc)", "gColViewerColorSpecialSurface", + UIWidgets::EnhancementColor("Entrance", "gColViewerColorEntrance", entrance_col, ImVec4(0, 255, 0, 255), false); + UIWidgets::EnhancementColor("Special Surface (Grass/Sand/Etc)", "gColViewerColorSpecialSurface", specialSurface_col, ImVec4(192, 255, 192, 255), false); - SohImGui::EnhancementColor("Interactable (Vines/Crawlspace/Etc)", "gColViewerColorInteractable", + UIWidgets::EnhancementColor("Interactable (Vines/Crawlspace/Etc)", "gColViewerColorInteractable", interactable_col, ImVec4(192, 0, 192, 255), false); - SohImGui::EnhancementColor("Slope", "gColViewerColorSlope", slope_col, ImVec4(255, 255, 128, 255), false); - SohImGui::EnhancementColor("Void", "gColViewerColorVoid", void_col, ImVec4(255, 0, 0, 255), false); - SohImGui::EnhancementColor("OC", "gColViewerColorOC", oc_col, ImVec4(255, 255, 255, 255), false); - SohImGui::EnhancementColor("AC", "gColViewerColorAC", ac_col, ImVec4(0, 0, 255, 255), false); - SohImGui::EnhancementColor("AT", "gColViewerColorAT", at_col, ImVec4(255, 0, 0, 255), false); - SohImGui::EnhancementColor("Waterbox", "gColViewerColorWaterbox", waterbox_col, ImVec4(0, 0, 255, 255), false); + UIWidgets::EnhancementColor("Slope", "gColViewerColorSlope", slope_col, ImVec4(255, 255, 128, 255), false); + UIWidgets::EnhancementColor("Void", "gColViewerColorVoid", void_col, ImVec4(255, 0, 0, 255), false); + UIWidgets::EnhancementColor("OC", "gColViewerColorOC", oc_col, ImVec4(255, 255, 255, 255), false); + UIWidgets::EnhancementColor("AC", "gColViewerColorAC", ac_col, ImVec4(0, 0, 255, 255), false); + UIWidgets::EnhancementColor("AT", "gColViewerColorAT", at_col, ImVec4(255, 0, 0, 255), false); + UIWidgets::EnhancementColor("Waterbox", "gColViewerColorWaterbox", waterbox_col, ImVec4(0, 0, 255, 255), false); ImGui::TreePop(); } else { - InsertHelpHoverText(colorHelpText); + UIWidgets::InsertHelpHoverText(colorHelpText); } ImGui::End(); diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index 5e21cec08..dfe947be8 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1,13 +1,13 @@ #include "debugSaveEditor.h" #include "../../util.h" -#include "../libultraship/ImGuiImpl.h" -#include "ImGuiHelpers.h" +#include +#include "../../UIWidgets.hpp" #include #include #include #include -#include +#include extern "C" { #include @@ -309,7 +309,7 @@ void DrawInfoTab() { ImGui::PushItemWidth(ImGui::GetFontSize() * 6); ImGui::Text("Name: %s", name.c_str()); - InsertHelpHoverText("Player Name"); + UIWidgets::InsertHelpHoverText("Player Name"); std::string nameID; for (int i = 0; i < 8; i++) { nameID = z2ASCII(i); @@ -326,7 +326,7 @@ void DrawInfoTab() { if (ImGui::IsItemDeactivated()) { gSaveContext.healthCapacity = healthIntermediary; } - InsertHelpHoverText("Maximum health. 16 units per full heart"); + UIWidgets::InsertHelpHoverText("Maximum health. 16 units per full heart"); if (gSaveContext.health > gSaveContext.healthCapacity) { gSaveContext.health = gSaveContext.healthCapacity; // Clamp health to new max } @@ -335,7 +335,7 @@ void DrawInfoTab() { const uint16_t healthMax = gSaveContext.healthCapacity; ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15); ImGui::SliderScalar("Health", ImGuiDataType_S16, &gSaveContext.health, &healthMin, &healthMax); - InsertHelpHoverText("Current health. 16 units per full heart"); + UIWidgets::InsertHelpHoverText("Current health. 16 units per full heart"); bool doubleDefense = gSaveContext.doubleDefense != 0; if (ImGui::Checkbox("Double Defense", &doubleDefense)) { @@ -343,7 +343,7 @@ void DrawInfoTab() { gSaveContext.inventory.defenseHearts = gSaveContext.doubleDefense ? 20 : 0; // Set to get the border drawn in the UI } - InsertHelpHoverText("Is double defense unlocked?"); + UIWidgets::InsertHelpHoverText("Is double defense unlocked?"); std::string magicName; if (gSaveContext.magicLevel == 2) { @@ -373,7 +373,7 @@ void DrawInfoTab() { ImGui::EndCombo(); } - InsertHelpHoverText("Current magic level"); + UIWidgets::InsertHelpHoverText("Current magic level"); gSaveContext.unk_13F4 = gSaveContext.magicLevel * 0x30; // Set to get the bar drawn in the UI if (gSaveContext.magic > gSaveContext.unk_13F4) { gSaveContext.magic = gSaveContext.unk_13F4; // Clamp magic to new max @@ -383,16 +383,16 @@ void DrawInfoTab() { const uint8_t magicMax = gSaveContext.unk_13F4; ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15); ImGui::SliderScalar("Magic", ImGuiDataType_S8, &gSaveContext.magic, &magicMin, &magicMax); - InsertHelpHoverText("Current magic. 48 units per magic level"); + UIWidgets::InsertHelpHoverText("Current magic. 48 units per magic level"); ImGui::InputScalar("Rupees", ImGuiDataType_S16, &gSaveContext.rupees); - InsertHelpHoverText("Current rupees"); + UIWidgets::InsertHelpHoverText("Current rupees"); const uint16_t dayTimeMin = 0; const uint16_t dayTimeMax = 0xFFFF; ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15); ImGui::SliderScalar("Time", ImGuiDataType_U16, &gSaveContext.dayTime, &dayTimeMin, &dayTimeMax); - InsertHelpHoverText("Time of day"); + UIWidgets::InsertHelpHoverText("Time of day"); if (ImGui::Button("Dawn")) { gSaveContext.dayTime = 0x4000; } @@ -410,43 +410,43 @@ void DrawInfoTab() { } ImGui::InputScalar("Total Days", ImGuiDataType_S32, &gSaveContext.totalDays); - InsertHelpHoverText("Total number of days elapsed since the start of the game"); + UIWidgets::InsertHelpHoverText("Total number of days elapsed since the start of the game"); ImGui::InputScalar("Deaths", ImGuiDataType_U16, &gSaveContext.deaths); - InsertHelpHoverText("Total number of deaths"); + UIWidgets::InsertHelpHoverText("Total number of deaths"); bool bgsFlag = gSaveContext.bgsFlag != 0; if (ImGui::Checkbox("Has BGS", &bgsFlag)) { gSaveContext.bgsFlag = bgsFlag; } - InsertHelpHoverText("Is Biggoron sword unlocked? Replaces Giant's knife"); + UIWidgets::InsertHelpHoverText("Is Biggoron sword unlocked? Replaces Giant's knife"); ImGui::InputScalar("Sword Health", ImGuiDataType_U16, &gSaveContext.swordHealth); - InsertHelpHoverText("Giant's knife health. Default is 8. Must be >0 for Biggoron sword to work"); + UIWidgets::InsertHelpHoverText("Giant's knife health. Default is 8. Must be >0 for Biggoron sword to work"); ImGui::InputScalar("Bgs Day Count", ImGuiDataType_S32, &gSaveContext.bgsDayCount); - InsertHelpHoverText("Total number of days elapsed since giving Biggoron the claim check"); + UIWidgets::InsertHelpHoverText("Total number of days elapsed since giving Biggoron the claim check"); ImGui::InputScalar("Entrance Index", ImGuiDataType_S32, &gSaveContext.entranceIndex); - InsertHelpHoverText("From which entrance did Link arrive?"); + UIWidgets::InsertHelpHoverText("From which entrance did Link arrive?"); ImGui::InputScalar("Cutscene Index", ImGuiDataType_S32, &gSaveContext.cutsceneIndex); - InsertHelpHoverText("Which cutscene is this?"); + UIWidgets::InsertHelpHoverText("Which cutscene is this?"); ImGui::InputScalar("Navi Timer", ImGuiDataType_U16, &gSaveContext.naviTimer); - InsertHelpHoverText("Navi wants to talk at 600 units, decides not to at 3000."); + UIWidgets::InsertHelpHoverText("Navi wants to talk at 600 units, decides not to at 3000."); ImGui::InputScalar("Timer 1 State", ImGuiDataType_S16, &gSaveContext.timer1State); - InsertHelpHoverText("Heat timer, race timer, etc. Has white font"); + UIWidgets::InsertHelpHoverText("Heat timer, race timer, etc. Has white font"); ImGui::InputScalar("Timer 1 Value", ImGuiDataType_S16, &gSaveContext.timer1Value, &one, NULL); - InsertHelpHoverText("Time, in seconds"); + UIWidgets::InsertHelpHoverText("Time, in seconds"); ImGui::InputScalar("Timer 2 State", ImGuiDataType_S16, &gSaveContext.timer2State); - InsertHelpHoverText("Trade timer, Ganon collapse timer, etc. Has yellow font"); + UIWidgets::InsertHelpHoverText("Trade timer, Ganon collapse timer, etc. Has yellow font"); ImGui::InputScalar("Timer 2 Value", ImGuiDataType_S16, &gSaveContext.timer2Value, &one, NULL); - InsertHelpHoverText("Time, in seconds"); + UIWidgets::InsertHelpHoverText("Time, in seconds"); const char* audioName; switch (gSaveContext.audioSetting) { @@ -481,13 +481,13 @@ void DrawInfoTab() { ImGui::EndCombo(); } - InsertHelpHoverText("Sound setting"); + UIWidgets::InsertHelpHoverText("Sound setting"); bool n64DDFlag = gSaveContext.n64ddFlag != 0; if (ImGui::Checkbox("64 DD file?", &n64DDFlag)) { gSaveContext.n64ddFlag = n64DDFlag; } - InsertHelpHoverText("WARNING! If you save, your file may be locked! Use caution!"); + UIWidgets::InsertHelpHoverText("WARNING! If you save, your file may be locked! Use caution!"); if (ImGui::BeginCombo("Z Target Mode", gSaveContext.zTargetSetting ? "Hold" : "Switch")) { if (ImGui::Selectable("Switch")) { @@ -498,7 +498,7 @@ void DrawInfoTab() { } ImGui::EndCombo(); } - InsertHelpHoverText("Z-Targeting behavior"); + UIWidgets::InsertHelpHoverText("Z-Targeting behavior"); ImGui::PushItemWidth(ImGui::GetFontSize() * 10); @@ -529,7 +529,7 @@ void DrawInventoryTab() { static bool restrictToValid = true; ImGui::Checkbox("Restrict to valid items", &restrictToValid); - InsertHelpHoverText("Restricts items and ammo to only what is possible to legally acquire in-game"); + UIWidgets::InsertHelpHoverText("Restricts items and ammo to only what is possible to legally acquire in-game"); for (int32_t y = 0; y < 4; y++) { for (int32_t x = 0; x < 6; x++) { @@ -568,7 +568,7 @@ void DrawInventoryTab() { gSaveContext.inventory.items[selectedIndex] = ITEM_NONE; ImGui::CloseCurrentPopup(); } - SetLastItemHoverText("None"); + UIWidgets::SetLastItemHoverText("None"); std::vector possibleItems; if (restrictToValid) { @@ -598,7 +598,7 @@ void DrawInventoryTab() { gSaveContext.inventory.items[selectedIndex] = slotEntry.id; ImGui::CloseCurrentPopup(); } - SetLastItemHoverText(SohUtils::GetItemName(slotEntry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(slotEntry.id)); } ImGui::EndPopup(); @@ -682,7 +682,7 @@ void DrawFlagsTab() { DrawGroupWithBorder([&]() { ImGui::Text("Switch"); - InsertHelpHoverText("Permanently-saved switch flags"); + UIWidgets::InsertHelpHoverText("Permanently-saved switch flags"); DrawFlagArray32("Switch", act->flags.swch); }); @@ -690,13 +690,13 @@ void DrawFlagsTab() { DrawGroupWithBorder([&]() { ImGui::Text("Temp Switch"); - InsertHelpHoverText("Temporary switch flags. Unset on scene transitions"); + UIWidgets::InsertHelpHoverText("Temporary switch flags. Unset on scene transitions"); DrawFlagArray32("Temp Switch", act->flags.tempSwch); }); DrawGroupWithBorder([&]() { ImGui::Text("Clear"); - InsertHelpHoverText("Permanently-saved room-clear flags"); + UIWidgets::InsertHelpHoverText("Permanently-saved room-clear flags"); DrawFlagArray32("Clear", act->flags.clear); }); @@ -704,13 +704,13 @@ void DrawFlagsTab() { DrawGroupWithBorder([&]() { ImGui::Text("Temp Clear"); - InsertHelpHoverText("Temporary room-clear flags. Unset on scene transitions"); + UIWidgets::InsertHelpHoverText("Temporary room-clear flags. Unset on scene transitions"); DrawFlagArray32("Temp Clear", act->flags.tempClear); }); DrawGroupWithBorder([&]() { ImGui::Text("Collect"); - InsertHelpHoverText("Permanently-saved collect flags"); + UIWidgets::InsertHelpHoverText("Permanently-saved collect flags"); DrawFlagArray32("Collect", act->flags.collect); }); @@ -718,13 +718,13 @@ void DrawFlagsTab() { DrawGroupWithBorder([&]() { ImGui::Text("Temp Collect"); - InsertHelpHoverText("Temporary collect flags. Unset on scene transitions"); + UIWidgets::InsertHelpHoverText("Temporary collect flags. Unset on scene transitions"); DrawFlagArray32("Temp Collect", act->flags.tempCollect); }); DrawGroupWithBorder([&]() { ImGui::Text("Chest"); - InsertHelpHoverText("Permanently-saved chest flags"); + UIWidgets::InsertHelpHoverText("Permanently-saved chest flags"); DrawFlagArray32("Chest", act->flags.chest); }); @@ -738,7 +738,7 @@ void DrawFlagsTab() { act->flags.collect = gSaveContext.sceneFlags[gGlobalCtx->sceneNum].collect; act->flags.chest = gSaveContext.sceneFlags[gGlobalCtx->sceneNum].chest; } - SetLastItemHoverText("Load flags from saved scene flags. Normally happens on scene load"); + UIWidgets::SetLastItemHoverText("Load flags from saved scene flags. Normally happens on scene load"); if (ImGui::Button("Save Flags")) { gSaveContext.sceneFlags[gGlobalCtx->sceneNum].swch = act->flags.swch; @@ -746,7 +746,7 @@ void DrawFlagsTab() { gSaveContext.sceneFlags[gGlobalCtx->sceneNum].collect = act->flags.collect; gSaveContext.sceneFlags[gGlobalCtx->sceneNum].chest = act->flags.chest; } - SetLastItemHoverText("Save current scene flags. Normally happens on scene exit"); + UIWidgets::SetLastItemHoverText("Save current scene flags. Normally happens on scene exit"); ImGui::EndGroup(); } else { @@ -776,12 +776,12 @@ void DrawFlagsTab() { if (ImGui::Button("Current")) { selectedSceneFlagMap = gGlobalCtx->sceneNum; } - SetLastItemHoverText("Open flags for current scene"); + UIWidgets::SetLastItemHoverText("Open flags for current scene"); } DrawGroupWithBorder([&]() { ImGui::Text("Switch"); - InsertHelpHoverText("Switch flags"); + UIWidgets::InsertHelpHoverText("Switch flags"); DrawFlagArray32("Switch", gSaveContext.sceneFlags[selectedSceneFlagMap].swch); }); @@ -789,13 +789,13 @@ void DrawFlagsTab() { DrawGroupWithBorder([&]() { ImGui::Text("Clear"); - InsertHelpHoverText("Room-clear flags"); + UIWidgets::InsertHelpHoverText("Room-clear flags"); DrawFlagArray32("Clear", gSaveContext.sceneFlags[selectedSceneFlagMap].clear); }); DrawGroupWithBorder([&]() { ImGui::Text("Collect"); - InsertHelpHoverText("Collect flags"); + UIWidgets::InsertHelpHoverText("Collect flags"); DrawFlagArray32("Collect", gSaveContext.sceneFlags[selectedSceneFlagMap].collect); }); @@ -803,13 +803,13 @@ void DrawFlagsTab() { DrawGroupWithBorder([&]() { ImGui::Text("Chest"); - InsertHelpHoverText("Chest flags"); + UIWidgets::InsertHelpHoverText("Chest flags"); DrawFlagArray32("Chest", gSaveContext.sceneFlags[selectedSceneFlagMap].chest); }); DrawGroupWithBorder([&]() { ImGui::Text("Rooms"); - InsertHelpHoverText("Flags for visted rooms"); + UIWidgets::InsertHelpHoverText("Flags for visted rooms"); DrawFlagArray32("Rooms", gSaveContext.sceneFlags[selectedSceneFlagMap].rooms); }); @@ -817,7 +817,7 @@ void DrawFlagsTab() { DrawGroupWithBorder([&]() { ImGui::Text("Floors"); - InsertHelpHoverText("Flags for visted floors"); + UIWidgets::InsertHelpHoverText("Flags for visted floors"); DrawFlagArray32("Floors", gSaveContext.sceneFlags[selectedSceneFlagMap].floors); }); @@ -870,7 +870,7 @@ void DrawFlagsTab() { static bool keepGsCountUpdated = true; ImGui::Checkbox("Keep GS Count Updated", &keepGsCountUpdated); - InsertHelpHoverText("Automatically adjust the number of gold skulltula tokens acquired based on set flags"); + UIWidgets::InsertHelpHoverText("Automatically adjust the number of gold skulltula tokens acquired based on set flags"); int32_t gsCount = 0; if (keepGsCountUpdated) { for (int32_t gsFlagIndex = 0; gsFlagIndex < 6; gsFlagIndex++) { @@ -883,85 +883,85 @@ void DrawFlagsTab() { if (ImGui::TreeNode("Event Check Inf Flags")) { DrawGroupWithBorder([&]() { ImGui::Text("0"); - InsertHelpHoverText("Mostly Kokiri Forest related"); + UIWidgets::InsertHelpHoverText("Mostly Kokiri Forest related"); DrawFlagArray16("eci0", gSaveContext.eventChkInf[0]); }); DrawGroupWithBorder([&]() { ImGui::Text("1"); - InsertHelpHoverText("Mostly Lon Lon Ranch related"); + UIWidgets::InsertHelpHoverText("Mostly Lon Lon Ranch related"); DrawFlagArray16("eci1", gSaveContext.eventChkInf[1]); }); DrawGroupWithBorder([&]() { ImGui::Text("2"); - InsertHelpHoverText("Dodongo Related?"); + UIWidgets::InsertHelpHoverText("Dodongo Related?"); DrawFlagArray16("eci2", gSaveContext.eventChkInf[2]); }); DrawGroupWithBorder([&]() { ImGui::Text("3"); - InsertHelpHoverText("Mostly Zora related"); + UIWidgets::InsertHelpHoverText("Mostly Zora related"); DrawFlagArray16("eci3", gSaveContext.eventChkInf[3]); }); DrawGroupWithBorder([&]() { ImGui::Text("4"); - InsertHelpHoverText("Random"); + UIWidgets::InsertHelpHoverText("Random"); DrawFlagArray16("eci4", gSaveContext.eventChkInf[4]); }); DrawGroupWithBorder([&]() { ImGui::Text("5"); - InsertHelpHoverText("Mostly song learning related"); + UIWidgets::InsertHelpHoverText("Mostly song learning related"); DrawFlagArray16("eci5", gSaveContext.eventChkInf[5]); }); DrawGroupWithBorder([&]() { ImGui::Text("6"); - InsertHelpHoverText("Random"); + UIWidgets::InsertHelpHoverText("Random"); DrawFlagArray16("eci6", gSaveContext.eventChkInf[6]); }); DrawGroupWithBorder([&]() { ImGui::Text("7"); - InsertHelpHoverText("Boss Battle related"); + UIWidgets::InsertHelpHoverText("Boss Battle related"); DrawFlagArray16("eci7", gSaveContext.eventChkInf[7]); }); DrawGroupWithBorder([&]() { ImGui::Text("8"); - InsertHelpHoverText("Mask related?"); + UIWidgets::InsertHelpHoverText("Mask related?"); DrawFlagArray16("eci8", gSaveContext.eventChkInf[8]); }); DrawGroupWithBorder([&]() { ImGui::Text("9"); - InsertHelpHoverText("Mostly carpenter related"); + UIWidgets::InsertHelpHoverText("Mostly carpenter related"); DrawFlagArray16("eci9", gSaveContext.eventChkInf[9]); }); DrawGroupWithBorder([&]() { ImGui::Text("A"); - InsertHelpHoverText("First-time overworld entrance cs related"); + UIWidgets::InsertHelpHoverText("First-time overworld entrance cs related"); DrawFlagArray16("eci10", gSaveContext.eventChkInf[10]); }); DrawGroupWithBorder([&]() { ImGui::Text("B"); - InsertHelpHoverText("First-time dungeon entrance cs/trial cs related"); + UIWidgets::InsertHelpHoverText("First-time dungeon entrance cs/trial cs related"); DrawFlagArray16("eci11", gSaveContext.eventChkInf[11]); }); DrawGroupWithBorder([&]() { ImGui::Text("C"); - InsertHelpHoverText("Random"); + UIWidgets::InsertHelpHoverText("Random"); DrawFlagArray16("eci12", gSaveContext.eventChkInf[12]); }); DrawGroupWithBorder([&]() { ImGui::Text("D"); - InsertHelpHoverText("Frog songs/GS rewards"); + UIWidgets::InsertHelpHoverText("Frog songs/GS rewards"); DrawFlagArray16("eci13", gSaveContext.eventChkInf[13]); }); @@ -1014,7 +1014,7 @@ void DrawUpgrade(const std::string& categoryName, int32_t categoryId, const std: ImGui::EndCombo(); } ImGui::PopID(); - SetLastItemHoverText(categoryName.c_str()); + UIWidgets::SetLastItemHoverText(categoryName.c_str()); } // Draws a combo that lets you choose and upgrade value from a popup grid of icons @@ -1039,7 +1039,7 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const } ImGui::PopStyleVar(); ImGui::PopStyleColor(); - SetLastItemHoverText(categoryName.c_str()); + UIWidgets::SetLastItemHoverText(categoryName.c_str()); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); if (ImGui::BeginPopup(upgradePopupPicker)) { @@ -1053,7 +1053,7 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const Inventory_ChangeUpgrade(categoryId, pickerIndex); ImGui::CloseCurrentPopup(); } - SetLastItemHoverText("None"); + UIWidgets::SetLastItemHoverText("None"); } else { const ItemMapEntry& slotEntry = itemMapping[items[pickerIndex]]; if (ImGui::ImageButton(SohImGui::GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0), @@ -1061,7 +1061,7 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const Inventory_ChangeUpgrade(categoryId, pickerIndex); ImGui::CloseCurrentPopup(); } - SetLastItemHoverText(SohUtils::GetItemName(slotEntry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(slotEntry.id)); } } @@ -1103,7 +1103,7 @@ void DrawEquipmentTab() { } ImGui::PopStyleColor(); ImGui::PopID(); - SetLastItemHoverText(SohUtils::GetItemName(entry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(entry.id)); } const std::vector bulletBagValues = { @@ -1193,7 +1193,7 @@ void DrawQuestItemButton(uint32_t item) { } } ImGui::PopStyleColor(); - SetLastItemHoverText(SohUtils::GetQuestItemName(entry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetQuestItemName(entry.id)); } // Draws a toggleable icon for a dungeon item that is faded when disabled @@ -1211,7 +1211,7 @@ void DrawDungeonItemButton(uint32_t item, uint32_t scene) { } } ImGui::PopStyleColor(); - SetLastItemHoverText(SohUtils::GetItemName(entry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(entry.id)); } void DrawQuestStatusTab() { @@ -1258,11 +1258,11 @@ void DrawQuestStatusTab() { } } ImGui::PopStyleColor(); - SetLastItemHoverText(SohUtils::GetQuestItemName(entry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetQuestItemName(entry.id)); } ImGui::InputScalar("GS Count", ImGuiDataType_S16, &gSaveContext.inventory.gsTokens); - InsertHelpHoverText("Number of gold skulltula tokens aquired"); + UIWidgets::InsertHelpHoverText("Number of gold skulltula tokens aquired"); uint32_t bitMask = 1 << QUEST_SKULL_TOKEN; bool gsUnlocked = (bitMask & gSaveContext.inventory.questItems) != 0; @@ -1273,7 +1273,7 @@ void DrawQuestStatusTab() { gSaveContext.inventory.questItems &= ~bitMask; } } - InsertHelpHoverText("If unlocked, enables showing the gold skulltula count in the quest status menu"); + UIWidgets::InsertHelpHoverText("If unlocked, enables showing the gold skulltula count in the quest status menu"); int32_t pohCount = (gSaveContext.inventory.questItems & 0xF0000000) >> 28; if (ImGui::BeginCombo("PoH count", std::to_string(pohCount).c_str())) { @@ -1285,7 +1285,7 @@ void DrawQuestStatusTab() { } ImGui::EndCombo(); } - InsertHelpHoverText("The number of pieces of heart acquired towards the next heart container"); + UIWidgets::InsertHelpHoverText("The number of pieces of heart acquired towards the next heart container"); DrawGroupWithBorder([&]() { ImGui::Text("Dungeon Items"); @@ -1410,7 +1410,7 @@ void DrawPlayerTab() { DrawGroupWithBorder([&]() { ImGui::Text("Link's Rotation"); - InsertHelpHoverText("For Link's rotation in relation to the world"); + UIWidgets::InsertHelpHoverText("For Link's rotation in relation to the world"); ImGui::InputScalar("X Rot", ImGuiDataType_S16, &player->actor.world.rot.x); ImGui::SameLine(); ImGui::InputScalar("Y Rot", ImGuiDataType_S16, &player->actor.world.rot.y); @@ -1420,7 +1420,7 @@ void DrawPlayerTab() { DrawGroupWithBorder([&]() { ImGui::Text("Link's Model Rotation"); - InsertHelpHoverText("For Link's actual model"); + UIWidgets::InsertHelpHoverText("For Link's actual model"); ImGui::InputScalar("X ModRot", ImGuiDataType_S16, &player->actor.shape.rot.x); ImGui::SameLine(); ImGui::InputScalar("Y ModRot", ImGuiDataType_S16, &player->actor.shape.rot.y); @@ -1429,19 +1429,19 @@ void DrawPlayerTab() { }); ImGui::InputScalar("Linear Velocity", ImGuiDataType_Float, &player->linearVelocity); - InsertHelpHoverText("Link's speed along the XZ plane"); + UIWidgets::InsertHelpHoverText("Link's speed along the XZ plane"); ImGui::InputScalar("Y Velocity", ImGuiDataType_Float, &player->actor.velocity.y); - InsertHelpHoverText("Link's speed along the Y plane. Caps at -20"); + UIWidgets::InsertHelpHoverText("Link's speed along the Y plane. Caps at -20"); ImGui::InputScalar("Wall Height", ImGuiDataType_Float, &player->wallHeight); - InsertHelpHoverText("Height used to determine whether Link can climb or grab a ledge at the top"); + UIWidgets::InsertHelpHoverText("Height used to determine whether Link can climb or grab a ledge at the top"); ImGui::InputScalar("Invincibility Timer", ImGuiDataType_S8, &player->invincibilityTimer); - InsertHelpHoverText("Can't take damage while this is nonzero"); + UIWidgets::InsertHelpHoverText("Can't take damage while this is nonzero"); ImGui::InputScalar("Gravity", ImGuiDataType_Float, &player->actor.gravity); - InsertHelpHoverText("Rate at which Link falls. Default -4.0f"); + UIWidgets::InsertHelpHoverText("Rate at which Link falls. Default -4.0f"); if (ImGui::BeginCombo("Link Age on Load", gGlobalCtx->linkAgeOnLoad == 0 ? "Adult" : "Child")) { if (ImGui::Selectable("Adult")) { @@ -1453,7 +1453,7 @@ void DrawPlayerTab() { ImGui::EndCombo(); } - InsertHelpHoverText("This will change Link's age when you load a map"); + UIWidgets::InsertHelpHoverText("This will change Link's age when you load a map"); ImGui::Separator(); diff --git a/soh/soh/Enhancements/gameconsole.h b/soh/soh/Enhancements/gameconsole.h index 33301afe6..27838ff63 100644 --- a/soh/soh/Enhancements/gameconsole.h +++ b/soh/soh/Enhancements/gameconsole.h @@ -3,7 +3,7 @@ #include #include -#include "Cvar.h" +#include #define MAX_CVARS 2048 @@ -39,4 +39,4 @@ s32 GameConsole_Split(char* str, char** argv); } #endif -#endif \ No newline at end of file +#endif diff --git a/soh/soh/Enhancements/randomizer/3drando/entrance.cpp b/soh/soh/Enhancements/randomizer/3drando/entrance.cpp index 144759e29..549624760 100644 --- a/soh/soh/Enhancements/randomizer/3drando/entrance.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/entrance.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include std::list entranceOverrides = {}; bool noRandomEntrances = false; diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 14bf594c2..34037f3a1 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include using namespace CustomMessages; using namespace Logic; diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index 4c18524fc..b5f0743fb 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -12,7 +12,7 @@ #include "trial.hpp" #include "entrance.hpp" #include "z64item.h" -#include +#include using namespace CustomMessages; using namespace Logic; diff --git a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp index 27101864b..83cf12b30 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp @@ -6,7 +6,7 @@ #include "shops.hpp" #include "debug.hpp" #include "keys.hpp" -#include +#include //Location definitions static std::array locationTable; @@ -1577,4 +1577,4 @@ void CreateItemOverrides() { } SPDLOG_DEBUG("Overrides Created: "); SPDLOG_DEBUG(std::to_string(overrides.size())); -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index b7ed68ea6..ad85bd401 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -9,7 +9,7 @@ #include "settings.hpp" #include "spoiler_log.hpp" #include "z64item.h" -#include +#include using namespace Settings; diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.cpp b/soh/soh/Enhancements/randomizer/3drando/menu.cpp index f7699b754..468758fe3 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.cpp @@ -13,8 +13,8 @@ #include "spoiler_log.hpp" #include "location_access.hpp" #include "debug.hpp" -#include -#include "soh/Enhancements/randomizer/randomizerTypes.h" +#include +#include "../../randomizer/randomizerTypes.h" namespace { bool seedChanged; @@ -547,4 +547,4 @@ std::string GenerateRandomizer(std::unordered_map std::string GetInput(const char* hintText) { return std::string(); -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp index 7d0fc8b14..ac68e579b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp @@ -5,9 +5,9 @@ #include "location_access.hpp" #include "rando_main.hpp" // #include -#include -#include -#include +#include +#include +#include #define TICKS_PER_SEC 268123480.0 @@ -25,4 +25,4 @@ void RandoMain::GenerateRando(std::unordered_map cvarS CVar_Save(); CVar_Load(); CVar_SetS32("gNewSeedGenerated", 1); -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index c9af08082..9ea43f2b2 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -11,7 +11,7 @@ #include "utils.hpp" #include "shops.hpp" #include "hints.hpp" -#include "Lib/nlohmann/json.hpp" +#include #include #include @@ -26,7 +26,7 @@ #include #include -#include "Window.h" +#include using json = nlohmann::json; @@ -771,4 +771,4 @@ bool PlacementLog_Write() { contentNode->SetCData(true); return true; -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 495850361..0d0f4300b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1,21 +1,21 @@ #include "randomizer.h" -#include "Lib/nlohmann/json.hpp" +#include #include #include #include #include #include -#include +#include #include #include -#include "../libultraship/ImGuiImpl.h" +#include #include #include "3drando/rando_main.hpp" -#include -#include "Lib/ImGui/imgui_internal.h" -#include -#include -#include +#include "../../UIWidgets.hpp" +#include +#include "../custom-message/CustomMessageManager.h" +#include "../custom-message/CustomMessageTypes.h" +#include "../item-tables/ItemTableManager.h" #include using json = nlohmann::json; @@ -3364,7 +3364,7 @@ void DrawRandoEditor(bool& open) { ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * disableEditingRandoSettings ? 0.5f : 1.0f); - SohImGui::EnhancementCheckbox("Enable Randomizer", "gRandomizer"); + UIWidgets::EnhancementCheckbox("Enable Randomizer", "gRandomizer"); if (CVar_GetS32("gRandomizer", 0) == 1) { if (ImGui::Button("Generate Seed")) { @@ -3404,17 +3404,17 @@ void DrawRandoEditor(bool& open) { ImGui::Text("Forest"); switch (CVar_GetS32("gRandomizeForest", 1)) { case 1: - InsertHelpHoverText("Mido no longer blocks the path to the Deku Tree\n" + UIWidgets::InsertHelpHoverText("Mido no longer blocks the path to the Deku Tree\n" "The Kokiri boy no longer blocks the path out of the forest."); break; case 2: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "The Kokiri boy no longer blocks the path out of the forest\nMido " "still blocks the path to the Deku Tree, requiring the Kokiri Sword " "and a Deku Shield to access the Deku Tree."); break; case 0: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Beating Deku Tree is logically required to leave the forest area " "(Kokiri Forest / Lost Woods / Sacred Forest Meadow / Deku Tree) " "while the Kokiri Sword and a Deku Shield are required to access the " @@ -3422,125 +3422,125 @@ void DrawRandoEditor(bool& open) { "forest area.\nThis setting is incompatible with starting as adult."); break; } - SohImGui::EnhancementCombobox("gRandomizeForest", randoForest, 3, 1); + UIWidgets::EnhancementCombobox("gRandomizeForest", randoForest, 3, 1); ImGui::Separator(); // Kakariko Gate ImGui::Text("Kakariko Gate"); switch (CVar_GetS32("gRandomizeKakarikoGate", 0)) { case 0: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "The gate and the Happy Mask Shop both remain closed until showing " "Zelda's Letter to the guard in Kakariko."); break; case 1: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "The gate is always open instead of needing Zelda's Letter.\nThe Happy Mask Shop " "opens upon obtaining Zelda's Letter without needing to show it to the guard."); break; } - SohImGui::EnhancementCombobox("gRandomizeKakarikoGate", randoKakarikoGate, 2, 1); + UIWidgets::EnhancementCombobox("gRandomizeKakarikoGate", randoKakarikoGate, 2, 1); ImGui::Separator(); // Door of Time ImGui::Text("Door of Time"); switch (CVar_GetS32("gRandomizeDoorOfTime", 0)) { case 0: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "The Door of Time starts opened instead of needing to play the Song of Time."); break; case 1: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Only an Ocarina and the Song of Time need to be found to open the Door of Time."); break; case 2: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "The Ocarina of Time, the Song of Time and all Spiritual Stones need to " "be found to open the Door of Time."); break; } - SohImGui::EnhancementCombobox("gRandomizeDoorOfTime", randoDoorOfTime, 3, 0); + UIWidgets::EnhancementCombobox("gRandomizeDoorOfTime", randoDoorOfTime, 3, 0); ImGui::Separator(); // Zora's Fountain ImGui::Text("Zora's Fountain"); switch (CVar_GetS32("gRandomizeZorasFountain", 0)) { case 0: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "King Zora obstructs the way to Zora's Fountain.\nRuto's Letter must be " "shown as child in order to move him from both eras."); break; case 1: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "King Zora is always moved in the adult era.\nThis means Ruto's Letter is " "only required to access Zora's fountain as child."); break; case 2: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "King Zora starts as moved in both the child and adult eras.\nThis also " "removes Ruto's Letter from the pool since it can't be used."); break; } - SohImGui::EnhancementCombobox("gRandomizeZorasFountain", randoZorasFountain, 3, 0); + UIWidgets::EnhancementCombobox("gRandomizeZorasFountain", randoZorasFountain, 3, 0); ImGui::Separator(); // Gerudo Fortress ImGui::Text("Gerudo Fortress"); switch (CVar_GetS32("gRandomizeGerudoFortress", 0)) { case 0: - InsertHelpHoverText("All 4 carpenters can be rescued."); + UIWidgets::InsertHelpHoverText("All 4 carpenters can be rescued."); break; case 1: - InsertHelpHoverText("Only the bottom left carpenter must be rescued."); + UIWidgets::InsertHelpHoverText("Only the bottom left carpenter must be rescued."); break; case 2: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "The carpenters are rescued from the start of the game and if \"Shuffle " "Gerudo Card\" is disabled, the player starts with the Gerudo Card in " "the inventory allowing access to Gerudo Training Grounds."); break; } - SohImGui::EnhancementCombobox("gRandomizeGerudoFortress", randoGerudoFortress, 3, 1); + UIWidgets::EnhancementCombobox("gRandomizeGerudoFortress", randoGerudoFortress, 3, 1); ImGui::Separator(); // Rainbow Bridge ImGui::Text("Rainbow Bridge"); - SohImGui::EnhancementCombobox("gRandomizeRainbowBridge", randoRainbowBridge, 7, 3); + UIWidgets::EnhancementCombobox("gRandomizeRainbowBridge", randoRainbowBridge, 7, 3); switch (CVar_GetS32("gRandomizeRainbowBridge", 3)) { case 1: - InsertHelpHoverText("The Rainbow Bridge requires Shadow and Spirit Medallions as well " + UIWidgets::InsertHelpHoverText("The Rainbow Bridge requires Shadow and Spirit Medallions as well " "as Light Arrows."); break; case 2: - InsertHelpHoverText("The Rainbow Bridge requires collecting a configurable number of " + UIWidgets::InsertHelpHoverText("The Rainbow Bridge requires collecting a configurable number of " "Spiritual Stones."); - SohImGui::EnhancementSliderInt("Stone Count: %d", "##RandoStoneCount", + UIWidgets::EnhancementSliderInt("Stone Count: %d", "##RandoStoneCount", "gRandomizeStoneCount", 0, 3, ""); - SetLastItemHoverText( + UIWidgets::SetLastItemHoverText( "Sets the number of Spiritual Stones required to spawn the Rainbow Bridge."); break; case 3: - SohImGui::EnhancementSliderInt("Medallion Count: %d", "##RandoMedallionCount", + UIWidgets::EnhancementSliderInt("Medallion Count: %d", "##RandoMedallionCount", "gRandomizeMedallionCount", 0, 6, "", 6); - SetLastItemHoverText( + UIWidgets::SetLastItemHoverText( "The Rainbow Bridge requires collecting a configurable number of Medallions."); break; case 4: - SohImGui::EnhancementSliderInt("Reward Count: %d", "##RandoRewardCount", + UIWidgets::EnhancementSliderInt("Reward Count: %d", "##RandoRewardCount", "gRandomizeRewardCount", 0, 9, ""); - SetLastItemHoverText("The Rainbow Bridge requires collecting a configurable number of " + UIWidgets::SetLastItemHoverText("The Rainbow Bridge requires collecting a configurable number of " "Dungeon Rewards."); break; case 5: - SohImGui::EnhancementSliderInt("Dungeon Count: %d", "##RandoDungeonCount", + UIWidgets::EnhancementSliderInt("Dungeon Count: %d", "##RandoDungeonCount", "gRandomizeDungeonCount", 0, 8, ""); - SetLastItemHoverText( + UIWidgets::SetLastItemHoverText( "The Rainbow Bridge requires completing a configurable number of Dungeons.\nDungeons " "are considered complete when Link steps into the blue warp at the end of them."); break; case 6: - SohImGui::EnhancementSliderInt("Token Count: %d", "##RandoTokenCount", + UIWidgets::EnhancementSliderInt("Token Count: %d", "##RandoTokenCount", "gRandomizeTokenCount", 0, 100, ""); - SetLastItemHoverText("The Rainbow Bridge requires collecting a configurable number of " + UIWidgets::SetLastItemHoverText("The Rainbow Bridge requires collecting a configurable number of " "Gold Skulltula Tokens."); break; } @@ -3557,8 +3557,8 @@ void DrawRandoEditor(bool& open) { // "gRandomizeGanonTrialCount", 0, 6, ""); //InsertHelpHoverText("Set the number of trials required to enter Ganon's Tower."); // RANDTODO: Switch back to slider when pre-completing some of Ganon's Trials is properly implemnted. - SohImGui::EnhancementCheckbox("Skip Ganon's Trials", "gRandomizeGanonTrialCount"); - InsertHelpHoverText( + UIWidgets::EnhancementCheckbox("Skip Ganon's Trials", "gRandomizeGanonTrialCount"); + UIWidgets::InsertHelpHoverText( "Sets whether or not Ganon's Castle Trials are required to enter Ganon's Tower."); // } @@ -3698,23 +3698,23 @@ void DrawRandoEditor(bool& open) { ImGui::Text("Shuffle Dungeon Rewards"); switch (CVar_GetS32("gRandomizeShuffleDungeonReward", 0)) { case 0: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Medallions and Spiritual Stones will be given as rewards for beating dungeons.\n" "This setting will force Link's Pocket to be a Medallion or a Spiritual Stone."); break; case 1: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Medallions and Spiritual Stones can only appear inside of dungeons."); break; case 2: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Medallions and Spiritual Stones can only appear outside dungeons."); break; case 3: - InsertHelpHoverText("Medallions and Spiritual Stones can appear anywhere."); + UIWidgets::InsertHelpHoverText("Medallions and Spiritual Stones can appear anywhere."); break; } - SohImGui::EnhancementCombobox("gRandomizeShuffleDungeonReward", randoShuffleDungeonRewards, 4, + UIWidgets::EnhancementCombobox("gRandomizeShuffleDungeonReward", randoShuffleDungeonRewards, 4, 0); // todo: support non dungeon rewards for link's pocket @@ -3748,10 +3748,10 @@ void DrawRandoEditor(bool& open) { ImGui::Text("Shuffle Songs"); switch (CVar_GetS32("gRandomizeShuffleSongs", 0)) { case 0: - InsertHelpHoverText("Songs will only appear at locations that normally teach songs."); + UIWidgets::InsertHelpHoverText("Songs will only appear at locations that normally teach songs."); break; case 1: - InsertHelpHoverText("Songs appear at the end of dungeons.\nFor major dungeons, they " + UIWidgets::InsertHelpHoverText("Songs appear at the end of dungeons.\nFor major dungeons, they " "will be at the boss heart container location.\nThe remaining 4 " "songs are placed at:\n- Zelda's Lullaby location\n" "- Ice Cavern's Serenade of Water Location\n" @@ -3759,10 +3759,10 @@ void DrawRandoEditor(bool& open) { "- Gerudo Training Ground's Ice Arrow Location."); break; case 2: - InsertHelpHoverText("Songs can appear in any location"); + UIWidgets::InsertHelpHoverText("Songs can appear in any location"); break; } - SohImGui::EnhancementCombobox("gRandomizeShuffleSongs", randoShuffleSongs, 3, 0); + UIWidgets::EnhancementCombobox("gRandomizeShuffleSongs", randoShuffleSongs, 3, 0); ImGui::Separator(); // todo implement shops @@ -3863,19 +3863,19 @@ void DrawRandoEditor(bool& open) { if(CVar_GetS32("gRandomizeStartingKokiriSword", 0) == 0) { // Shuffle Kokiri Sword ImGui::Text("Shuffle Kokiri Sword"); - InsertHelpHoverText("Enabling this shuffles the Kokiri Sword into the item pool.\nThis will " + UIWidgets::InsertHelpHoverText("Enabling this shuffles the Kokiri Sword into the item pool.\nThis will " "require extensive use of sticks until the sword is found."); - SohImGui::EnhancementCombobox("gRandomizeShuffleKokiriSword", randoShuffleKokiriSword, 2, 0); + UIWidgets::EnhancementCombobox("gRandomizeShuffleKokiriSword", randoShuffleKokiriSword, 2, 0); ImGui::Separator(); } if(CVar_GetS32("gRandomizeStartingOcarina", 0) == 0) { // Shuffle Ocarinas ImGui::Text("Shuffle Ocarinas"); - InsertHelpHoverText("Enabling this shuffles the Fairy Ocarina and the Ocarina of time into " + UIWidgets::InsertHelpHoverText("Enabling this shuffles the Fairy Ocarina and the Ocarina of time into " "the item pool.\n" "This will require finding an Ocarina before being able to play songs."); - SohImGui::EnhancementCombobox("gRandomizeShuffleOcarinas", randoShuffleOcarinas, 2, 0); + UIWidgets::EnhancementCombobox("gRandomizeShuffleOcarinas", randoShuffleOcarinas, 2, 0); ImGui::Separator(); } @@ -3883,22 +3883,22 @@ void DrawRandoEditor(bool& open) { if(CVar_GetS32("gRandomizeSkipChildZelda", 0) == 0) { // Shuffle Weird Egg ImGui::Text("Shuffle Weird Egg"); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Enabling this shuffles the Weird Egg from Malon into the item pool.\nThis " "will require finding the Weird Egg to talk to Zelda in Hyrule Castle which " "in turn unlocks rewards from Impa, Saria, Malon and Talon as well as the " "Happy Mask Sidequest.\nThe Weird egg is also required for Zelda's Letter to " "unlock the Kakariko Gate as child which can lock some progression."); - SohImGui::EnhancementCombobox("gRandomizeShuffleWeirdEgg", randoShuffleWeirdEgg, 2, 0); + UIWidgets::EnhancementCombobox("gRandomizeShuffleWeirdEgg", randoShuffleWeirdEgg, 2, 0); ImGui::Separator(); } // Shuffle Gerudo Membership Card ImGui::Text("Shuffle Gerudo Membership Card"); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Enabling this shuffles the Gerudo Membership Card into the item pool.\nThe Gerudo " "Token is required to enter the Gerudo Training Ground."); - SohImGui::EnhancementCombobox("gRandomizeShuffleGerudoToken", randoShuffleGerudoToken, 2, 0); + UIWidgets::EnhancementCombobox("gRandomizeShuffleGerudoToken", randoShuffleGerudoToken, 2, 0); ImGui::Separator(); // todo implement magic bean 10 pack @@ -3939,14 +3939,14 @@ void DrawRandoEditor(bool& open) { ImGui::PopItemWidth(); ImGui::TableNextColumn(); - SohImGui::EnhancementCheckbox("Start with Fairy Ocarina", "gRandomizeStartingOcarina"); - SohImGui::EnhancementCheckbox("Start with Kokiri Sword", "gRandomizeStartingKokiriSword"); - SohImGui::EnhancementCheckbox("Start with Deku Shield", "gRandomizeStartingDekuShield"); - SohImGui::EnhancementCheckbox("Start with Maps/Compasses", "gRandomizeStartingMapsCompasses"); - SohImGui::EnhancementCheckbox("Skip Child Zelda", "gRandomizeSkipChildZelda"); - SohImGui::EnhancementCheckbox("Start with Consumables", "gRandomizeStartingConsumables"); - SohImGui::EnhancementCheckbox("Full Wallets", "gRandomizeFullWallets"); - InsertHelpHoverText("Start with a full wallet. All wallet upgrades come filled with rupees."); + UIWidgets::EnhancementCheckbox("Start with Fairy Ocarina", "gRandomizeStartingOcarina"); + UIWidgets::EnhancementCheckbox("Start with Kokiri Sword", "gRandomizeStartingKokiriSword"); + UIWidgets::EnhancementCheckbox("Start with Deku Shield", "gRandomizeStartingDekuShield"); + UIWidgets::EnhancementCheckbox("Start with Maps/Compasses", "gRandomizeStartingMapsCompasses"); + UIWidgets::EnhancementCheckbox("Skip Child Zelda", "gRandomizeSkipChildZelda"); + UIWidgets::EnhancementCheckbox("Start with Consumables", "gRandomizeStartingConsumables"); + UIWidgets::EnhancementCheckbox("Full Wallets", "gRandomizeFullWallets"); + UIWidgets::InsertHelpHoverText("Start with a full wallet. All wallet upgrades come filled with rupees."); // todo dungeon items stuff (more details in commented out block) // ImGui::TableNextColumn(); @@ -4088,19 +4088,19 @@ void DrawRandoEditor(bool& open) { // Ganon's Boss Key ImGui::PushItemWidth(-FLT_MIN); ImGui::Text("Ganon's Boss Key"); - SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 3, + UIWidgets::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 3, 0); switch (CVar_GetS32("gRandomizeShuffleGanonBossKey", 0)) { case 0: - SetLastItemHoverText( + UIWidgets::SetLastItemHoverText( "Ganon's Boss Key is given to you from the start and you don't " "have to worry about finding it."); break; case 1: - SetLastItemHoverText("Ganon's Boss Key will appear in the vanilla location."); + UIWidgets::SetLastItemHoverText("Ganon's Boss Key will appear in the vanilla location."); break; case 2: - SetLastItemHoverText("Ganon's Boss Key will appear somewhere inside Ganon's Castle."); + UIWidgets::SetLastItemHoverText("Ganon's Boss Key will appear somewhere inside Ganon's Castle."); break; // case 0: // SetLastItemHoverText( @@ -4219,30 +4219,30 @@ void DrawRandoEditor(bool& open) { // ImGui::Separator(); // Cuccos to return - SohImGui::EnhancementSliderInt("Cuccos to return: %d", "##RandoCuccosToReturn", + UIWidgets::EnhancementSliderInt("Cuccos to return: %d", "##RandoCuccosToReturn", "gRandomizeCuccosToReturn", 0, 7, "", 7); - InsertHelpHoverText("The cucco Lady will give a reward for returning this many of her cuccos to the pen."); + UIWidgets::InsertHelpHoverText("The cucco Lady will give a reward for returning this many of her cuccos to the pen."); ImGui::Separator(); // // Big Poe Target Count - SohImGui::EnhancementSliderInt("Big Poe Target Count: %d", "##RandoBigPoeTargetCount", + UIWidgets::EnhancementSliderInt("Big Poe Target Count: %d", "##RandoBigPoeTargetCount", "gRandomizeBigPoeTargetCount", 1, 10, "", 10); - InsertHelpHoverText("The Poe buyer will give a reward for turning in the chosen number of Big Poes."); + UIWidgets::InsertHelpHoverText("The Poe buyer will give a reward for turning in the chosen number of Big Poes."); ImGui::Separator(); // // Skip child stealth - SohImGui::EnhancementCheckbox("Skip Child Stealth", "gRandomizeSkipChildStealth"); - InsertHelpHoverText("The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards."); + UIWidgets::EnhancementCheckbox("Skip Child Stealth", "gRandomizeSkipChildStealth"); + UIWidgets::InsertHelpHoverText("The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards."); ImGui::Separator(); // Skip Epona race - SohImGui::EnhancementCheckbox("Skip Epona Race", "gRandomizeSkipEponaRace"); - InsertHelpHoverText("Epona can be summoned with Epona's Song without needing to race Ingo."); + UIWidgets::EnhancementCheckbox("Skip Epona Race", "gRandomizeSkipEponaRace"); + UIWidgets::InsertHelpHoverText("Epona can be summoned with Epona's Song without needing to race Ingo."); ImGui::Separator(); // Skip tower escape - SohImGui::EnhancementCheckbox("Skip Tower Escape", "gRandomizeSkipTowerEscape"); - InsertHelpHoverText("The tower escape sequence between Ganondorf and Ganon will be skipped."); + UIWidgets::EnhancementCheckbox("Skip Tower Escape", "gRandomizeSkipTowerEscape"); + UIWidgets::InsertHelpHoverText("The tower escape sequence between Ganondorf and Ganon will be skipped."); ImGui::Separator(); // todo implement complete mask quest @@ -4275,53 +4275,53 @@ void DrawRandoEditor(bool& open) { ImGui::PushItemWidth(-FLT_MIN); // Gossip Stone Hints ImGui::Text("Gossip Stone Hints"); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Gossip Stones can be made to give hints about where items can be found.\nDifferent settings can " "be chosen to decide which item is needed to speak to Gossip Stones. \nChoosing to stick with the " "Mask of Truth will make the hints very difficult to obtain.\nHints for \"on the way of the " "hero\" are locations that contain items that are required to beat the game."); - SohImGui::EnhancementCombobox("gRandomizeGossipStoneHints", randoGossipStoneHints, 4, 1); + UIWidgets::EnhancementCombobox("gRandomizeGossipStoneHints", randoGossipStoneHints, 4, 1); if (CVar_GetS32("gRandomizeGossipStoneHints", 1) != 0) { // Hint Clarity ImGui::Indent(); ImGui::Text("Hint Clarity"); switch (CVar_GetS32("gRandomizeHintClarity", 2)) { case 0: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Sets the difficulty of hints.\nObscure: Hints are unique for each thing, but the " "writing may be confusing.\nEx: Kokiri Sword > a butter knife"); break; case 1: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Sets the difficulty of hints.\nAmbiguous: Hints are clearly written, " "but may refer to more than one thing.\nEx: Kokiri Sword > a sword"); break; case 2: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Sets the difficulty of hints.\nClear: Hints are clearly written and " "are unique for each thing.\nEx: Kokiri Sword > the Kokiri Sword"); break; } - SohImGui::EnhancementCombobox("gRandomizeHintClarity", randoHintClarity, 3, 2); + UIWidgets::EnhancementCombobox("gRandomizeHintClarity", randoHintClarity, 3, 2); // Hint Distribution ImGui::Text("Hint Distribution"); switch (CVar_GetS32("gRandomizeHintDistribution", 1)) { case 0: - InsertHelpHoverText("Only junk hints."); + UIWidgets::InsertHelpHoverText("Only junk hints."); break; case 1: - InsertHelpHoverText("Recommended hint spread."); + UIWidgets::InsertHelpHoverText("Recommended hint spread."); break; case 2: - InsertHelpHoverText("More useful hints."); + UIWidgets::InsertHelpHoverText("More useful hints."); break; case 3: - InsertHelpHoverText("Many powerful hints."); + UIWidgets::InsertHelpHoverText("Many powerful hints."); break; } - SohImGui::EnhancementCombobox("gRandomizeHintDistribution", randoHintDistribution, 4, 1); + UIWidgets::EnhancementCombobox("gRandomizeHintDistribution", randoHintDistribution, 4, 1); ImGui::Unindent(); } ImGui::Separator(); @@ -4375,43 +4375,43 @@ void DrawRandoEditor(bool& open) { ImGui::Text("Item Pool"); switch (CVar_GetS32("gRandomizeItemPool", 1)) { case 0: - InsertHelpHoverText("Extra major items are added to the pool."); + UIWidgets::InsertHelpHoverText("Extra major items are added to the pool."); break; case 1: - InsertHelpHoverText("Original item pool."); + UIWidgets::InsertHelpHoverText("Original item pool."); break; case 2: - InsertHelpHoverText("Some excess items are removed, including health upgrades."); + UIWidgets::InsertHelpHoverText("Some excess items are removed, including health upgrades."); break; case 3: - InsertHelpHoverText("Most excess items are removed."); + UIWidgets::InsertHelpHoverText("Most excess items are removed."); break; } - SohImGui::EnhancementCombobox("gRandomizeItemPool", randoItemPool, 4, 1); + UIWidgets::EnhancementCombobox("gRandomizeItemPool", randoItemPool, 4, 1); ImGui::Separator(); // // Ice Traps ImGui::Text("Ice Traps"); switch (CVar_GetS32("gRandomizeIceTraps", 1)) { case 0: - InsertHelpHoverText("All Ice Traps are removed."); + UIWidgets::InsertHelpHoverText("All Ice Traps are removed."); break; case 1: - InsertHelpHoverText("Only Ice Traps from the base item pool are placed."); + UIWidgets::InsertHelpHoverText("Only Ice Traps from the base item pool are placed."); break; case 2: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Chance to add extra Ice Traps when junk items are added to the item pool."); break; case 3: - InsertHelpHoverText("All added junk items will be Ice Traps."); + UIWidgets::InsertHelpHoverText("All added junk items will be Ice Traps."); break; case 4: - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "All junk items will be replaced by Ice Traps, even those in the base pool."); break; } - SohImGui::EnhancementCombobox("gRandomizeIceTraps", randoIceTraps, 5, 1); + UIWidgets::EnhancementCombobox("gRandomizeIceTraps", randoIceTraps, 5, 1); ImGui::Separator(); // todo implement double defense getitem @@ -4450,17 +4450,17 @@ void DrawRandoEditor(bool& open) { ImGui::TableNextColumn(); // COLUMN 2 - OPEN EXCLUDE LOCATIONS ImGui::NewLine(); - SohImGui::EnhancementCheckbox("Deku Theater Mask of Truth", "gRandomizeExcludeDekuTheaterMaskOfTruth"); + UIWidgets::EnhancementCheckbox("Deku Theater Mask of Truth", "gRandomizeExcludeDekuTheaterMaskOfTruth"); ImGui::NewLine(); - SohImGui::EnhancementCheckbox("10 Skulltula Reward", "gRandomizeExcludeKak10SkullReward"); + UIWidgets::EnhancementCheckbox("10 Skulltula Reward", "gRandomizeExcludeKak10SkullReward"); ImGui::NewLine(); - SohImGui::EnhancementCheckbox("20 Skulltula Reward", "gRandomizeExcludeKak20SkullReward"); + UIWidgets::EnhancementCheckbox("20 Skulltula Reward", "gRandomizeExcludeKak20SkullReward"); ImGui::NewLine(); - SohImGui::EnhancementCheckbox("30 Skulltula Reward", "gRandomizeExcludeKak30SkullReward"); + UIWidgets::EnhancementCheckbox("30 Skulltula Reward", "gRandomizeExcludeKak30SkullReward"); ImGui::NewLine(); - SohImGui::EnhancementCheckbox("40 Skulltula Reward", "gRandomizeExcludeKak40SkullReward"); + UIWidgets::EnhancementCheckbox("40 Skulltula Reward", "gRandomizeExcludeKak40SkullReward"); ImGui::NewLine(); - SohImGui::EnhancementCheckbox("50 Skulltula Reward", "gRandomizeExcludeKak50SkullReward"); + UIWidgets::EnhancementCheckbox("50 Skulltula Reward", "gRandomizeExcludeKak50SkullReward"); // ImGui::TableNextColumn(); // // COLUMN 3 - LOGICAL TRICKS // ImGui::NewLine(); @@ -4742,4 +4742,4 @@ void Rando_Init(void) { InitRando(); } -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 2dcef684c..e9b321434 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -1,13 +1,13 @@ #include "randomizer_item_tracker.h" #include "../../util.h" -#include "../libultraship/ImGuiImpl.h" -#include +#include +#include "../../UIWidgets.hpp" #include #include #include #include -#include +#include extern "C" { #include @@ -20,6 +20,7 @@ extern GlobalContext* gGlobalCtx; #include "textures/icon_item_24_static/icon_item_24_static.h" } + typedef struct { uint32_t id; std::string name; @@ -252,7 +253,7 @@ void DrawEquip(uint32_t itemId) { ImGui::Image(SohImGui::GetTextureByName(hasEquip ? entry.name : entry.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); - SetLastItemHoverText(SohUtils::GetItemName(entry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(entry.id)); } std::unordered_map questTrackerMap = { @@ -300,7 +301,7 @@ void DrawQuest(uint32_t itemId) { ImGui::EndGroup(); - SetLastItemHoverText(SohUtils::GetQuestItemName(entry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetQuestItemName(entry.id)); }; std::unordered_map itemTrackerMap = { @@ -677,7 +678,7 @@ void DrawItem(uint32_t itemId) { } ImGui::EndGroup(); - SetLastItemHoverText(SohUtils::GetItemName(entry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(entry.id)); } void DrawBottle(uint32_t itemId, uint32_t bottleSlot) { @@ -688,7 +689,7 @@ void DrawBottle(uint32_t itemId, uint32_t bottleSlot) { ImGui::Image(SohImGui::GetTextureByName(hasItem ? entry.name : entry.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); - SetLastItemHoverText(SohUtils::GetItemName(entry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(entry.id)); }; typedef struct { @@ -733,12 +734,12 @@ void DrawUpgrade(int32_t categoryId) { const ItemTrackerUpgradeEntry& entry = upgradeTrackerMap[categoryId][0]; ImGui::Image(SohImGui::GetTextureByName(entry.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); - SetLastItemHoverText(SohUtils::GetItemName(entry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(entry.id)); } else { const ItemTrackerUpgradeEntry& entry = upgradeTrackerMap[categoryId][CUR_UPG_VALUE(categoryId) - 1]; ImGui::Image(SohImGui::GetTextureByName(entry.name), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); - SetLastItemHoverText(SohUtils::GetItemName(entry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(entry.id)); } } @@ -804,7 +805,7 @@ void DrawSong(int32_t songId) { bool hasSong = (bitMask & gSaveContext.inventory.questItems) != 0; ImGui::Image(SohImGui::GetTextureByName(hasSong ? entry.name : entry.nameFaded), ImVec2(iconSize/1.5, iconSize), ImVec2(0, 0), ImVec2(1, 1)); - SetLastItemHoverText(SohUtils::GetQuestItemName(entry.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetQuestItemName(entry.id)); } void DrawItemTracker(bool& open) { @@ -983,12 +984,12 @@ void DrawItemTracker(bool& open) { } else { minimalSpacingX = 32; } - SohImGui::EnhancementCheckbox("Display \"Ammo/MaxAmo\"", "gItemTrackerAmmoDisplay"); - SohImGui::EnhancementCheckbox("Randomizer colors for Songs", "gItemTrackeSongColor"); - SohImGui::Tooltip("Will display non-warp songs with randomizer colors instead of pure white"); - SohImGui::EnhancementSliderInt("Icon size : %dpx", "##ITEMTRACKERICONSIZE", "gRandoTrackIconSize", 32, 128, ""); + UIWidgets::EnhancementCheckbox("Display \"Ammo/MaxAmo\"", "gItemTrackerAmmoDisplay"); + UIWidgets::EnhancementCheckbox("Randomizer colors for Songs", "gItemTrackeSongColor"); + UIWidgets::Tooltip("Will display non-warp songs with randomizer colors instead of pure white"); + UIWidgets::EnhancementSliderInt("Icon size : %dpx", "##ITEMTRACKERICONSIZE", "gRandoTrackIconSize", 32, 128, ""); - SohImGui::EnhancementSliderInt("X spacing : %dpx", "##ITEMTRACKERSPACINGX", "gRandoTrackIconSpacingX", minimalSpacingX, 256, + UIWidgets::EnhancementSliderInt("X spacing : %dpx", "##ITEMTRACKERSPACINGX", "gRandoTrackIconSpacingX", minimalSpacingX, 256, ""); // SohImGui::EnhancementSliderInt("Y Spacing : %dpx", "##ITEMTRACKERSPACINGY", "gRandoTrackIconSpacingY", 0, // 16, ""); @@ -1016,4 +1017,4 @@ void DrawItemTracker(bool& open) { void InitItemTracker() { SohImGui::AddWindow("Randomizer", "Item Tracker", DrawItemTracker); -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/savestates.cpp b/soh/soh/Enhancements/savestates.cpp index 37856aa81..4296ce869 100644 --- a/soh/soh/Enhancements/savestates.cpp +++ b/soh/soh/Enhancements/savestates.cpp @@ -1,6 +1,6 @@ #include "savestates.h" -#include "GameVersions.h" +#include #include // std::sprintf @@ -9,7 +9,7 @@ #include #include -#include +#include #include "z64.h" #include "z64save.h" @@ -823,7 +823,7 @@ extern "C" void ProcessSaveStateRequests(void) { } void SaveStateMgr::SetCurrentSlot(unsigned int slot) { - SohImGui::overlay->TextDrawNotification(1.0f, true, "slot %u set", slot); + SohImGui::GetGameOverlay()->TextDrawNotification(1.0f, true, "slot %u set", slot); this->currentSlot = slot; } @@ -841,12 +841,12 @@ void SaveStateMgr::ProcessSaveStateRequests(void) { this->states[request.slot] = std::make_shared(OTRGlobals::Instance->gSaveStateMgr, request.slot); } this->states[request.slot]->Save(); - SohImGui::overlay->TextDrawNotification(1.0f, true, "saved state %u", request.slot); + SohImGui::GetGameOverlay()->TextDrawNotification(1.0f, true, "saved state %u", request.slot); break; case RequestType::LOAD: if (this->states.contains(request.slot)) { this->states[request.slot]->Load(); - SohImGui::overlay->TextDrawNotification(1.0f, true, "loaded state %u", request.slot); + SohImGui::GetGameOverlay()->TextDrawNotification(1.0f, true, "loaded state %u", request.slot); } else { SPDLOG_ERROR("Invalid SaveState slot: {}", request.type); } @@ -862,7 +862,7 @@ void SaveStateMgr::ProcessSaveStateRequests(void) { SaveStateReturn SaveStateMgr::AddRequest(const SaveStateRequest request) { if (gGlobalCtx == nullptr) { SPDLOG_ERROR("[SOH] Can not save or load a state outside of \"GamePlay\""); - SohImGui::overlay->TextDrawNotification(1.0f, true, "states not available here", request.slot); + SohImGui::GetGameOverlay()->TextDrawNotification(1.0f, true, "states not available here", request.slot); return SaveStateReturn::FAIL_WRONG_GAMESTATE; } @@ -876,7 +876,7 @@ SaveStateReturn SaveStateMgr::AddRequest(const SaveStateRequest request) { return SaveStateReturn::SUCCESS; } else { SPDLOG_ERROR("Invalid SaveState slot: {}", request.type); - SohImGui::overlay->TextDrawNotification(1.0f, true, "state slot %u empty", request.slot); + SohImGui::GetGameOverlay()->TextDrawNotification(1.0f, true, "state slot %u empty", request.slot); return SaveStateReturn::FAIL_INVALID_SLOT; } [[unlikely]] default: diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp new file mode 100644 index 000000000..cf843cc8b --- /dev/null +++ b/soh/soh/GameMenuBar.cpp @@ -0,0 +1,1367 @@ +// +// GameMenuBar.cpp +// soh +// +// Created by David Chavez on 24.08.22. +// + +#include "GameMenuBar.hpp" + +#include +#include +#define IMGUI_DEFINE_MATH_OPERATORS +#include +#include +#include +#include +#include +#include +#include + +#ifdef __SWITCH__ +#include +#endif + +#include "UIWidgets.hpp" +#include "include/z64audio.h" + +#define EXPERIMENTAL() \ + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 50, 50, 255)); \ + UIWidgets::Spacer(3.0f); \ + ImGui::Text("Experimental"); \ + ImGui::PopStyleColor(); \ + UIWidgets::PaddedSeparator(false, true); + +bool isBetaQuestEnabled = false; + +extern "C" { + void enableBetaQuest() { isBetaQuestEnabled = true; } + void disableBetaQuest() { isBetaQuestEnabled = false; } +} + +enum SeqPlayers { + /* 0 */ SEQ_BGM_MAIN, + /* 1 */ SEQ_FANFARE, + /* 2 */ SEQ_SFX, + /* 3 */ SEQ_BGM_SUB, + /* 4 */ SEQ_MAX +}; + +namespace GameMenuBar { + + // MARK: - Properties + + const char* powers[9] = { + "Vanilla (1x)", + "Double (2x)", + "Quadruple (4x)", + "Octuple (8x)", + "Hexadecuple (16x)", + "Duotrigintuple (32x)", + "Quattuorsexagintuple (64x)", + "Octoviginticentuple (128x)", + "Hexaquinquagintiducentuple (256x)" + }; + + // MARK: - Helpers + + std::string GetWindowButtonText(const char* text, bool menuOpen) { + char buttonText[100] = ""; + if(menuOpen) { strcat(buttonText,"> "); } + strcat(buttonText, text); + if (!menuOpen) { strcat(buttonText, " "); } + return buttonText; + } + + void BindAudioSlider(const char* name, const char* key, float defaultValue, SeqPlayers playerId) { + float value = CVar_GetFloat(key, defaultValue); + + ImGui::Text(name, static_cast(100 * value)); + if (ImGui::SliderFloat((std::string("##") + key).c_str(), &value, 0.0f, 1.0f, "")) { + const float volume = floorf(value * 100) / 100; + CVar_SetFloat(key, volume); + SohImGui::RequestCvarSaveOnNextTick(); + Audio_SetGameVolume(playerId, volume); + } + } + + void UpdateAudio() { + Audio_SetGameVolume(SEQ_BGM_MAIN, CVar_GetFloat("gMainMusicVolume", 1)); + Audio_SetGameVolume(SEQ_BGM_SUB, CVar_GetFloat("gSubMusicVolume", 1)); + Audio_SetGameVolume(SEQ_FANFARE, CVar_GetFloat("gSFXMusicVolume", 1)); + Audio_SetGameVolume(SEQ_SFX, CVar_GetFloat("gFanfareVolume", 1)); + } + + void applyEnhancementPresetDefault(void) { + // D-pad Support on Pause and File Select + CVar_SetS32("gDpadPauseName", 0); + // D-pad Support in Ocarina and Text Choice + CVar_SetS32("gDpadOcarinaText", 0); + // D-pad Support for Browsing Shop Items + CVar_SetS32("gDpadShop", 0); + // D-pad as Equip Items + CVar_SetS32("gDpadEquips", 0); + // Allow the cursor to be on any slot + CVar_SetS32("gPauseAnyCursor", 0); + // Prevent Dropped Ocarina Inputs + CVar_SetS32("gDpadNoDropOcarinaInput", 0); + // Answer Navi Prompt with L Button + CVar_SetS32("gNaviOnL", 0); + + // Text Speed (1 to 5) + CVar_SetS32("gTextSpeed", 1); + // King Zora Speed (1 to 5) + CVar_SetS32("gMweepSpeed", 1); + // Biggoron Forge Time (0 to 3) + CVar_SetS32("gForgeTime", 3); + // Vine/Ladder Climb speed (+0 to +12) + CVar_SetS32("gClimbSpeed", 0); + // Faster Block Push (+0 to +5) + CVar_SetS32("gFasterBlockPush", 0); + // Faster Heavy Block Lift + CVar_SetS32("gFasterHeavyBlockLift", 0); + // No Forced Navi + CVar_SetS32("gNoForcedNavi", 0); + // No Skulltula Freeze + CVar_SetS32("gSkulltulaFreeze", 0); + // MM Bunny Hood + CVar_SetS32("gMMBunnyHood", 0); + // Fast Chests + CVar_SetS32("gFastChests", 0); + // Fast Drops + CVar_SetS32("gFastDrops", 0); + // Better Owl + CVar_SetS32("gBetterOwl", 0); + // Fast Ocarina Playback + CVar_SetS32("gFastOcarinaPlayback", 0); + // Instant Putaway + CVar_SetS32("gInstantPutaway", 0); + // Instant Boomerang Recall + CVar_SetS32("gFastBoomerang", 0); + // Mask Select in Inventory + CVar_SetS32("gMaskSelect", 0); + // Remember Save Location + CVar_SetS32("gRememberSaveLocation", 0); + + // Damage Multiplier (0 to 8) + CVar_SetS32("gDamageMul", 0); + // Fall Damage Multiplier (0 to 7) + CVar_SetS32("gFallDamageMul", 0); + // Void Damage Multiplier (0 to 6) + CVar_SetS32("gVoidDamageMul", 0); + // No Random Drops + CVar_SetS32("gNoRandomDrops", 0); + // No Heart Drops + CVar_SetS32("gNoHeartDrops", 0); + // Enable Bombchu Drops + CVar_SetS32("gBombchuDrops", 0); + // Always Win Goron Pot + CVar_SetS32("gGoronPot", 0); + + // Change Red Potion Effect + CVar_SetS32("gRedPotionEffect", 0); + // Red Potion Health (1 to 100) + CVar_SetS32("gRedPotionHealth", 1); + // Red Potion Percent Restore + CVar_SetS32("gRedPercentRestore", 0); + // Change Green Potion Effect + CVar_SetS32("gGreenPotionEffect", 0); + // Green Potion Mana (1 to 100) + CVar_SetS32("gGreenPotionMana", 1); + // Green Potion Percent Restore + CVar_SetS32("gGreenPercentRestore", 0); + // Change Blue Potion Effects + CVar_SetS32("gBluePotionEffects", 0); + // Blue Potion Health (1 to 100) + CVar_SetS32("gBluePotionHealth", 1); + // Blue Potion Health Percent Restore + CVar_SetS32("gBlueHealthPercentRestore", 0); + // Blue Potion Mana (1 to 100) + CVar_SetS32("gBluePotionMana", 1); + // Blue Potion Mana Percent Restore + CVar_SetS32("gBlueManaPercentRestore", 0); + // Change Milk Effect + CVar_SetS32("gMilkEffect", 0); + // Milk Health (1 to 100) + CVar_SetS32("gMilkHealth", 1); + // Milk Percent Restore + CVar_SetS32("gMilkPercentRestore", 0); + // Separate Half Milk Effect + CVar_SetS32("gSeparateHalfMilkEffect", 0); + // Half Milk Health (1 to 100) + CVar_SetS32("gHalfMilkHealth", 0); + // Half Milk Percent Restore + CVar_SetS32("gHalfMilkPercentRestore", 0); + // Change Fairy Effect + CVar_SetS32("gFairyEffect", 0); + // Fairy (1 to 100) + CVar_SetS32("gFairyHealth", 1); + // Fairy Percent Restore + CVar_SetS32("gFairyPercentRestore", 0); + // Change Fairy Revive Effect + CVar_SetS32("gFairyReviveEffect", 0); + // Fairy Revival (1 to 100) + CVar_SetS32("gFairyReviveHealth", 1); + // Fairy Revive Percent Restore + CVar_SetS32("gFairyRevivePercentRestore", 0); + + // Instant Fishing + CVar_SetS32("gInstantFishing", 0); + // Guarantee Bite + CVar_SetS32("gGuaranteeFishingBite", 0); + // Child Minimum Weight (6 to 10) + CVar_SetS32("gChildMinimumWeightFish", 10); + // Adult Minimum Weight (8 to 13) + CVar_SetS32("gAdultMinimumWeightFish", 13); + + // Mute Low HP Alarm + CVar_SetS32("gLowHpAlarm", 0); + // Minimal UI + CVar_SetS32("gMinimalUI", 0); + // Disable Navi Call Audio + CVar_SetS32("gDisableNaviCallAudio", 0); + + // Visual Stone of Agony + CVar_SetS32("gVisualAgony", 0); + // Assignable Tunics and Boots + CVar_SetS32("gAssignableTunicsAndBoots", 0); + // Equipment Toggle + CVar_SetS32("gEquipmentCanBeRemoved", 0); + // Link's Cow in Both Time Periods + CVar_SetS32("gCowOfTime", 0); + // Enable visible guard vision + CVar_SetS32("gGuardVision", 0); + // Enable passage of time on file select + CVar_SetS32("gTimeFlowFileSelect", 0); + // Count Golden Skulltulas + CVar_SetS32("gInjectSkulltulaCount", 0); + // Pull grave during the day + CVar_SetS32("gDayGravePull", 0); + + // Rotate link (0 to 2) + CVar_SetS32("gPauseLiveLinkRotation", 0); + // Pause link animation (0 to 16) + CVar_SetS32("gPauseLiveLink", 0); + // Frames to wait + CVar_SetS32("gMinFrameCount", 1); + + // N64 Mode + CVar_SetS32("gN64Mode", 0); + // Enable 3D Dropped items/projectiles + CVar_SetS32("gNewDrops", 0); + // Disable Black Bar Letterboxes + CVar_SetS32("gDisableBlackBars", 0); + // Dynamic Wallet Icon + CVar_SetS32("gDynamicWalletIcon", 0); + // Always show dungeon entrances + CVar_SetS32("gAlwaysShowDungeonMinimapIcon", 0); + + // Fix L&R Pause menu + CVar_SetS32("gUniformLR", 0); + // Fix L&Z Page switch in Pause menu + CVar_SetS32("gNGCKaleidoSwitcher", 0); + // Fix Dungeon entrances + CVar_SetS32("gFixDungeonMinimapIcon", 0); + // Fix Two Handed idle animations + CVar_SetS32("gTwoHandedIdle", 0); + // Fix the Gravedigging Tour Glitch + CVar_SetS32("gGravediggingTourFix", 0); + // Fix Deku Nut upgrade + CVar_SetS32("gDekuNutUpgradeFix", 0); + // Fix Navi text HUD position + CVar_SetS32("gNaviTextFix", 0); + // Fix Anubis fireballs + CVar_SetS32("gAnubisFix", 0); + // Fix Megaton Hammer crouch stab + CVar_SetS32("gCrouchStabHammerFix", 0); + // Fix all crouch stab + CVar_SetS32("gCrouchStabFix", 0); + + // Red Ganon blood + CVar_SetS32("gRedGanonBlood", 0); + // Fish while hovering + CVar_SetS32("gHoverFishing", 0); + // N64 Weird Frames + CVar_SetS32("gN64WeirdFrames", 0); + // Bombchus out of bounds + CVar_SetS32("gBombchusOOB", 0); + + CVar_SetS32("gGsCutscene", 0); + // Autosave + CVar_SetS32("gAutosave", 0); + } + + void applyEnhancementPresetVanillaPlus(void) { + // D-pad Support in Ocarina and Text Choice + CVar_SetS32("gDpadOcarinaText", 1); + // D-pad Support for Browsing Shop Items + CVar_SetS32("gDpadShop", 1); + // D-pad as Equip Items + CVar_SetS32("gDpadEquips", 1); + // Prevent Dropped Ocarina Inputs + CVar_SetS32("gDpadNoDropOcarinaInput", 1); + + // Text Speed (1 to 5) + CVar_SetS32("gTextSpeed", 5); + // King Zora Speed (1 to 5) + CVar_SetS32("gMweepSpeed", 2); + // Faster Block Push (+0 to +5) + CVar_SetS32("gFasterBlockPush", 5); + // Better Owl + CVar_SetS32("gBetterOwl", 1); + + // Assignable Tunics and Boots + CVar_SetS32("gAssignableTunicsAndBoots", 1); + // Enable passage of time on file select + CVar_SetS32("gTimeFlowFileSelect", 1); + // Count Golden Skulltulas + CVar_SetS32("gInjectSkulltulaCount", 1); + + // Pause link animation (0 to 16) + CVar_SetS32("gPauseLiveLink", 1); + + // Dynamic Wallet Icon + CVar_SetS32("gDynamicWalletIcon", 1); + // Always show dungeon entrances + CVar_SetS32("gAlwaysShowDungeonMinimapIcon", 1); + + // Fix L&R Pause menu + CVar_SetS32("gUniformLR", 1); + // Fix Dungeon entrances + CVar_SetS32("gFixDungeonMinimapIcon", 1); + // Fix Two Handed idle animations + CVar_SetS32("gTwoHandedIdle", 1); + // Fix the Gravedigging Tour Glitch + CVar_SetS32("gGravediggingTourFix", 1); + // Fix Deku Nut upgrade + CVar_SetS32("gDekuNutUpgradeFix", 1); + + // Red Ganon blood + CVar_SetS32("gRedGanonBlood", 1); + // Fish while hovering + CVar_SetS32("gHoverFishing", 1); + // N64 Weird Frames + CVar_SetS32("gN64WeirdFrames", 1); + // Bombchus out of bounds + CVar_SetS32("gBombchusOOB", 1); + } + + void applyEnhancementPresetEnhanced(void) { + // King Zora Speed (1 to 5) + CVar_SetS32("gMweepSpeed", 5); + // Biggoron Forge Time (0 to 3) + CVar_SetS32("gForgeTime", 0); + // Vine/Ladder Climb speed (+0 to +12) + CVar_SetS32("gClimbSpeed", 1); + // Faster Heavy Block Lift + CVar_SetS32("gFasterHeavyBlockLift", 1); + // No Forced Navi + CVar_SetS32("gNoForcedNavi", 1); + // No Skulltula Freeze + CVar_SetS32("gSkulltulaFreeze", 1); + // MM Bunny Hood + CVar_SetS32("gMMBunnyHood", 1); + // Fast Chests + CVar_SetS32("gFastChests", 1); + // Fast Drops + CVar_SetS32("gFastDrops", 1); + // Fast Ocarina Playback + CVar_SetS32("gFastOcarinaPlayback", 1); + // Instant Putaway + CVar_SetS32("gInstantPutaway", 1); + // Instant Boomerang Recall + CVar_SetS32("gFastBoomerang", 1); + // Mask Select in Inventory + CVar_SetS32("gMaskSelect", 1); + + // Disable Navi Call Audio + CVar_SetS32("gDisableNaviCallAudio", 1); + + // Equipment Toggle + CVar_SetS32("gEquipmentCanBeRemoved", 1); + // Count Golden Skulltulas + CVar_SetS32("gInjectSkulltulaCount", 1); + + // Enable 3D Dropped items/projectiles + CVar_SetS32("gNewDrops", 1); + + // Fix Anubis fireballs + CVar_SetS32("gAnubisFix", 1); + } + + void applyEnhancementPresetRandomizer(void) { + // Allow the cursor to be on any slot + CVar_SetS32("gPauseAnyCursor", 1); + + // Instant Fishing + CVar_SetS32("gInstantFishing", 1); + // Guarantee Bite + CVar_SetS32("gGuaranteeFishingBite", 1); + // Child Minimum Weight (6 to 10) + CVar_SetS32("gChildMinimumWeightFish", 6); + // Adult Minimum Weight (8 to 13) + CVar_SetS32("gAdultMinimumWeightFish", 8); + + // Visual Stone of Agony + CVar_SetS32("gVisualAgony", 1); + // Pull grave during the day + CVar_SetS32("gDayGravePull", 1); + // Pull out Ocarina to Summon Scarecrow + CVar_SetS32("gSkipScarecrow", 0); + + // Pause link animation (0 to 16) + CVar_SetS32("gPauseLiveLink", 16); + // Frames to wait + CVar_SetS32("gMinFrameCount", 200); + } + + void applyEnhancementPresets(void) { + switch (CVar_GetS32("gSelectEnhancementPresets", 0)) { + // Default + case 0: + applyEnhancementPresetDefault(); + break; + + // Vanilla Plus + case 1: + applyEnhancementPresetDefault(); + applyEnhancementPresetVanillaPlus(); + break; + + // Enhanced + case 2: + applyEnhancementPresetDefault(); + applyEnhancementPresetVanillaPlus(); + applyEnhancementPresetEnhanced(); + break; + + // Randomizer + case 3: + applyEnhancementPresetDefault(); + applyEnhancementPresetVanillaPlus(); + applyEnhancementPresetEnhanced(); + applyEnhancementPresetRandomizer(); + break; + } + } + + // MARK: - Delegates + + void SetupHooks() { + Ship::RegisterHook(UpdateAudio); + Ship::RegisterHook(UpdateAudio); + } + + void Draw() { + if (ImGui::BeginMenu("Settings")) + { + if (ImGui::BeginMenu("Audio")) { + UIWidgets::EnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true); + UIWidgets::Spacer(0); + BindAudioSlider("Main Music Volume: %d %%", "gMainMusicVolume", 1.0f, SEQ_BGM_MAIN); + UIWidgets::Spacer(0); + BindAudioSlider("Sub Music Volume: %d %%", "gSubMusicVolume", 1.0f, SEQ_BGM_SUB); + UIWidgets::Spacer(0); + BindAudioSlider("Sound Effects Volume: %d %%", "gSFXMusicVolume", 1.0f, SEQ_SFX); + UIWidgets::Spacer(0); + BindAudioSlider("Fanfare Volume: %d %%", "gFanfareVolume", 1.0f, SEQ_FANFARE); + + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Controller")) { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2 (12.0f, 6.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); + if (ImGui::Button(GetWindowButtonText("Controller Configuration", CVar_GetS32("gControllerConfigurationEnabled", 0)).c_str())) + { + bool currentValue = CVar_GetS32("gControllerConfigurationEnabled", 0); + CVar_SetS32("gControllerConfigurationEnabled", !currentValue); + SohImGui::RequestCvarSaveOnNextTick(); + SohImGui::ToggleInputEditorWindow(CVar_GetS32("gControllerConfigurationEnabled", 0)); + } + ImGui::PopStyleColor(1); + ImGui::PopStyleVar(3); + #ifndef __SWITCH__ + UIWidgets::PaddedEnhancementCheckbox("Use Controller Navigation", "gControlNav", true, false); + UIWidgets::Tooltip("Allows controller navigation of the menu bar\nD-pad to move between items, A to select, and X to grab focus on the menu bar"); + #endif + UIWidgets::PaddedEnhancementCheckbox("Show Inputs", "gInputEnabled", true, false); + UIWidgets::Tooltip("Shows currently pressed inputs on the bottom right of the screen"); + UIWidgets::Spacer(0); + ImGui::PushItemWidth(ImGui::GetWindowSize().x - 20.0f); + UIWidgets::EnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f, false); + UIWidgets::Tooltip("Sets the on screen size of the displayed inputs from the Show Inputs setting"); + ImGui::PopItemWidth(); + + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Graphics")) { + #ifndef __APPLE__ + UIWidgets::EnhancementSliderFloat("Internal Resolution: %d %%", "##IMul", "gInternalResolution", 0.5f, 2.0f, "", 1.0f, true, true); + UIWidgets::Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but effective form of anti-aliasing"); + SohImGui::SetResolutionMultiplier(CVar_GetFloat("gInternalResolution", 1)); + #endif + #ifndef __WIIU__ + UIWidgets::PaddedEnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, "", 1, false, true, false); + UIWidgets::Tooltip("Activates multi-sample anti-aliasing when above 1x up to 8x for 8 samples for every pixel"); + SohImGui::SetMSAALevel(CVar_GetS32("gMSAAValue", 1)); + #endif + + if (SohImGui::WindowBackend() == SohImGui::Backend::DX11) + { + const char* cvar = "gExtraLatencyThreshold"; + int val = CVar_GetS32(cvar, 80); + val = fmax(fmin(val, 360), 0); + int fps = val; + + UIWidgets::Spacer(0); + + if (fps == 0) + { + ImGui::Text("Jitter fix: Off"); + } + else + { + ImGui::Text("Jitter fix: >= %d FPS", fps); + } + + std::string MinusBTNELT = " - ##ExtraLatencyThreshold"; + std::string PlusBTNELT = " + ##ExtraLatencyThreshold"; + if (ImGui::Button(MinusBTNELT.c_str())) { + val--; + CVar_SetS32(cvar, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + ImGui::PushItemWidth(ImGui::GetWindowSize().x - 79.0f); + if (ImGui::SliderInt("##ExtraLatencyThreshold", &val, 0, 360, "", ImGuiSliderFlags_AlwaysClamp)) + { + CVar_SetS32(cvar, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + ImGui::PopItemWidth(); + UIWidgets::Tooltip("When Interpolation FPS setting is at least this threshold, add one frame of input lag (e.g. 16.6 ms for 60 FPS) in order to avoid jitter. This setting allows the CPU to work on one frame while GPU works on the previous frame.\nThis setting should be used when your computer is too slow to do CPU + GPU work in time."); + + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + if (ImGui::Button(PlusBTNELT.c_str())) { + val++; + CVar_SetS32(cvar, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + + UIWidgets::Spacer(0); + } + + ImGui::Text("Renderer API (Needs reload)"); + auto backends = SohImGui::GetAvailableRenderingBackends(); + auto currentBackend = SohImGui::GetCurrentRenderingBackend(); + + if (ImGui::BeginCombo("##RApi", currentBackend.second)) { + for (uint8_t i = 0; i < sizeof(backends) / sizeof(backends[0]); i++) { + if (ImGui::Selectable(backends[i].second, backends[i] == currentBackend)) { + SohImGui::SetCurrentRenderingBackend(i, backends[i]); + } + } + + ImGui::EndCombo(); + } + + EXPERIMENTAL(); + + ImGui::Text("Texture Filter (Needs reload)"); + UIWidgets::EnhancementCombobox("gTextureFilter", SohImGui::GetSupportedTextureFilters(), 3, 0); + + UIWidgets::Spacer(0); + + SohImGui::DrawSettings(); + + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Languages")) { + UIWidgets::EnhancementRadioButton("English", "gLanguages", 0); + UIWidgets::EnhancementRadioButton("German", "gLanguages", 1); + UIWidgets::EnhancementRadioButton("French", "gLanguages", 2); + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } + + ImGui::SetCursorPosY(0.0f); + + if (ImGui::BeginMenu("Enhancements")) + { + + const char* enhancementPresets[4] = { "Default", "Vanilla Plus", "Enhanced", "Randomizer"}; + UIWidgets::PaddedText("Enhancement Presets", false, true); + UIWidgets::EnhancementCombobox("gSelectEnhancementPresets", enhancementPresets, 4, 0); + UIWidgets::Tooltip( + "Default - Set all enhancements to their default values. The true vanilla SoH experience.\n" + "\n" + "Vanilla Plus - Adds Quality of Life features that enhance your experience, but don't alter gameplay. Recommended for a first playthrough of OoT.\n" + "\n" + "Enhanced - The \"Vanilla Plus\" preset, but with more quality of life enhancements that might alter gameplay slightly. Recommended for returning players.\n" + "\n" + "Randomizer - The \"Enhanced\" preset, plus any other enhancements that are recommended for playing Randomizer." + ); + + UIWidgets::Spacer(0); + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f)); + if (ImGui::Button("Apply Preset")) { + applyEnhancementPresets(); + SohImGui::RequestCvarSaveOnNextTick(); + } + ImGui::PopStyleVar(1); + + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Controls")) { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); + float availableWidth = ImGui::GetContentRegionAvail().x; + if (ImGui::Button( + GetWindowButtonText("Customize Game Controls", CVar_GetS32("gGameControlEditorEnabled", 0)).c_str(), + ImVec2(availableWidth, 0) + )) { + bool currentValue = CVar_GetS32("gGameControlEditorEnabled", 0); + CVar_SetS32("gGameControlEditorEnabled", !currentValue); + SohImGui::RequestCvarSaveOnNextTick(); + SohImGui::EnableWindow("Game Control Editor", CVar_GetS32("gGameControlEditorEnabled", 0)); + } + ImGui::PopStyleVar(3); + ImGui::PopStyleColor(1); + + // TODO mutual exclusions -- There should be some system to prevent conclifting enhancements from being selected + UIWidgets::PaddedEnhancementCheckbox("D-pad Support on Pause and File Select", "gDpadPauseName"); + UIWidgets::Tooltip("Enables Pause and File Select screen navigation with the D-pad\nIf used with D-pad as Equip Items, you must hold C-Up to equip instead of navigate"); + UIWidgets::PaddedEnhancementCheckbox("D-pad Support in Text Choice", "gDpadText", true, false); + UIWidgets::PaddedEnhancementCheckbox("D-pad Support for Browsing Shop Items", "gDpadShop", true, false); + UIWidgets::PaddedEnhancementCheckbox("D-pad as Equip Items", "gDpadEquips", true, false); + UIWidgets::Tooltip("Allows the D-pad to be used as extra C buttons"); + UIWidgets::PaddedEnhancementCheckbox("Allow the cursor to be on any slot", "gPauseAnyCursor", true, false); + UIWidgets::Tooltip("Allows the cursor on the pause menu to be over any slot\nSimilar to Rando and Spaceworld 97"); + UIWidgets::PaddedEnhancementCheckbox("Prevent Dropped Ocarina Inputs", "gDpadNoDropOcarinaInput", true, false); + UIWidgets::Tooltip("Prevent dropping inputs when playing the ocarina quickly"); + UIWidgets::PaddedEnhancementCheckbox("Answer Navi Prompt with L Button", "gNaviOnL", true, false); + UIWidgets::Tooltip("Speak to Navi with L but enter first-person camera with C-Up"); + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Gameplay")) + { + if (ImGui::BeginMenu("Time Savers")) + { + UIWidgets::PaddedEnhancementSliderInt("Text Speed: %dx", "##TEXTSPEED", "gTextSpeed", 1, 5, "", 1, false, false, true); + UIWidgets::PaddedEnhancementSliderInt("King Zora Speed: %dx", "##MWEEPSPEED", "gMweepSpeed", 1, 5, "", 1, false, false, true); + UIWidgets::EnhancementSliderInt("Biggoron Forge Time: %d days", "##FORGETIME", "gForgeTime", 0, 3, "", 3); + UIWidgets::Tooltip("Allows you to change the number of days it takes for Biggoron to forge the Biggoron Sword"); + UIWidgets::PaddedEnhancementSliderInt("Vine/Ladder Climb speed +%d", "##CLIMBSPEED", "gClimbSpeed", 0, 12, "", 0, false, false, true); + UIWidgets::PaddedEnhancementSliderInt("Block pushing speed +%d", "##BLOCKSPEED", "gFasterBlockPush", 0, 5, "", 0, false, false, true); + UIWidgets::PaddedEnhancementCheckbox("Faster Heavy Block Lift", "gFasterHeavyBlockLift", true, false); + UIWidgets::Tooltip("Speeds up lifting silver rocks and obelisks"); + UIWidgets::PaddedEnhancementCheckbox("No Forced Navi", "gNoForcedNavi", true, false); + UIWidgets::Tooltip("Prevent forced Navi conversations"); + UIWidgets::PaddedEnhancementCheckbox("No Skulltula Freeze", "gSkulltulaFreeze", true, false); + UIWidgets::Tooltip("Stops the game from freezing the player when picking up Gold Skulltulas"); + UIWidgets::PaddedEnhancementCheckbox("MM Bunny Hood", "gMMBunnyHood", true, false); + UIWidgets::Tooltip("Wearing the Bunny Hood grants a speed increase like in Majora's Mask"); + UIWidgets::PaddedEnhancementCheckbox("Fast Chests", "gFastChests", true, false); + UIWidgets::Tooltip("Kick open every chest"); + UIWidgets::PaddedEnhancementCheckbox("Skip Pickup Messages", "gFastDrops", true, false); + UIWidgets::Tooltip("Skip pickup messages for new consumable items and bottle swipes"); + UIWidgets::PaddedEnhancementCheckbox("Better Owl", "gBetterOwl", true, false); + UIWidgets::Tooltip("The default response to Kaepora Gaebora is always that you understood what he said"); + UIWidgets::PaddedEnhancementCheckbox("Fast Ocarina Playback", "gFastOcarinaPlayback", true, false); + UIWidgets::Tooltip("Skip the part where the Ocarina playback is called when you play a song"); + UIWidgets::PaddedEnhancementCheckbox("Skip Scarecrow Song", "gSkipScarecrow", true, false); + UIWidgets::Tooltip("Pierre appears when Ocarina is pulled out. Requires learning scarecrow song."); + UIWidgets::PaddedEnhancementCheckbox("Instant Putaway", "gInstantPutaway", true, false); + UIWidgets::Tooltip("Allow Link to put items away without having to wait around"); + UIWidgets::PaddedEnhancementCheckbox("Instant Boomerang Recall", "gFastBoomerang", true, false); + UIWidgets::Tooltip("Instantly return the boomerang to Link by pressing its item button while it's in the air"); + UIWidgets::PaddedEnhancementCheckbox("Mask Select in Inventory", "gMaskSelect", true, false); + UIWidgets::Tooltip("After completing the mask trading sub-quest, press A and any direction on the mask slot to change masks"); + UIWidgets::PaddedEnhancementCheckbox("Remember Save Location", "gRememberSaveLocation", true, false); + UIWidgets::Tooltip("When loading a save, places Link at the last entrance he went through.\n" + "This doesn't work if the save was made in a grotto."); + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Difficulty Options")) + { + ImGui::Text("Damage Multiplier"); + UIWidgets::EnhancementCombobox("gDamageMul", powers, 9, 0); + UIWidgets::Tooltip( + "Modifies all sources of damage not affected by other sliders\n\ + 2x: Can survive all common attacks from the start of the game\n\ + 4x: Dies in 1 hit to any substantial attack from the start of the game\n\ + 8x: Can only survive trivial damage from the start of the game\n\ + 16x: Can survive all common attacks with max health without double defense\n\ + 32x: Can survive all common attacks with max health and double defense\n\ + 64x: Can survive trivial damage with max health without double defense\n\ + 128x: Can survive trivial damage with max health and double defense\n\ + 256x: Cannot survive damage" + ); + UIWidgets::PaddedText("Fall Damage Multiplier", true, false); + UIWidgets::EnhancementCombobox("gFallDamageMul", powers, 8, 0); + UIWidgets::Tooltip( + "Modifies all fall damage\n\ + 2x: Can survive all fall damage from the start of the game\n\ + 4x: Can only survive short fall damage from the start of the game\n\ + 8x: Cannot survive any fall damage from the start of the game\n\ + 16x: Can survive all fall damage with max health without double defense\n\ + 32x: Can survive all fall damage with max health and double defense\n\ + 64x: Can survive short fall damage with double defense\n\ + 128x: Cannot survive fall damage" + ); + UIWidgets::PaddedText("Void Damage Multiplier", true, false); + UIWidgets::EnhancementCombobox("gVoidDamageMul", powers, 7, 0); + UIWidgets::Tooltip( + "Modifies damage taken after falling into a void\n\ + 2x: Can survive void damage from the start of the game\n\ + 4x: Cannot survive void damage from the start of the game\n\ + 8x: Can survive void damage twice with max health without double defense\n\ + 16x: Can survive void damage with max health without double defense\n\ + 32x: Can survive void damage with max health and double defense\n\ + 64x: Cannot survive void damage" + ); + UIWidgets::PaddedEnhancementCheckbox("No Random Drops", "gNoRandomDrops", true, false); + UIWidgets::Tooltip("Disables random drops, except from the Goron Pot, Dampe, and bosses"); + UIWidgets::PaddedEnhancementCheckbox("Enable Bombchu Drops", "gBombchuDrops", true, false); + UIWidgets::Tooltip("Bombchus will sometimes drop in place of bombs"); + UIWidgets::PaddedEnhancementCheckbox("No Heart Drops", "gNoHeartDrops", true, false); + UIWidgets::Tooltip("Disables heart drops, but not heart placements, like from a Deku Scrub running off\nThis simulates Hero Mode from other games in the series"); + UIWidgets::PaddedEnhancementCheckbox("Always Win Goron Pot", "gGoronPot", true, false); + UIWidgets::Tooltip("Always get the heart piece/purple rupee from the spinning Goron pot"); + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Potion Values")) + { + UIWidgets::EnhancementCheckbox("Change Red Potion Effect", "gRedPotionEffect"); + UIWidgets::Tooltip("Enable the following changes to the amount of health restored by Red Potions"); + UIWidgets::EnhancementSliderInt("Red Potion Health: %d", "##REDPOTIONHEALTH", "gRedPotionHealth", 1, 100, "", 0, true); + UIWidgets::Tooltip("Changes the amount of health restored by Red Potions"); + UIWidgets::EnhancementCheckbox("Red Potion Percent Restore", "gRedPercentRestore"); + UIWidgets::Tooltip("Toggles from Red Potions restoring a fixed amount of health to a percent of the player's current max health"); + + ImGui::Separator(); + + UIWidgets::EnhancementCheckbox("Change Green Potion Effect", "gGreenPotionEffect"); + UIWidgets::Tooltip("Enable the following changes to the amount of mana restored by Green Potions"); + UIWidgets::EnhancementSliderInt("Green Potion Mana: %d", "##GREENPOTIONMANA", "gGreenPotionMana", 1, 100, "", 0, true); + UIWidgets::Tooltip("Changes the amount of mana restored by Green Potions, base max mana is 48, max upgraded mana is 96"); + UIWidgets::EnhancementCheckbox("Green Potion Percent Restore", "gGreenPercentRestore"); + UIWidgets::Tooltip("Toggles from Green Potions restoring a fixed amount of mana to a percent of the player's current max mana"); + + ImGui::Separator(); + + UIWidgets::EnhancementCheckbox("Change Blue Potion Effects", "gBluePotionEffects"); + UIWidgets::Tooltip("Enable the following changes to the amount of health and mana restored by Blue Potions"); + UIWidgets::EnhancementSliderInt("Blue Potion Health: %d", "##BLUEPOTIONHEALTH", "gBluePotionHealth", 1, 100, "", 0, true); + UIWidgets::Tooltip("Changes the amount of health restored by Blue Potions"); + UIWidgets::EnhancementCheckbox("Blue Potion Health Percent Restore", "gBlueHealthPercentRestore"); + UIWidgets::Tooltip("Toggles from Blue Potions restoring a fixed amount of health to a percent of the player's current max health"); + + ImGui::Separator(); + + UIWidgets::EnhancementSliderInt("Blue Potion Mana: %d", "##BLUEPOTIONMANA", "gBluePotionMana", 1, 100, "", 0, true); + UIWidgets::Tooltip("Changes the amount of mana restored by Blue Potions, base max mana is 48, max upgraded mana is 96"); + UIWidgets::EnhancementCheckbox("Blue Potion Mana Percent Restore", "gBlueManaPercentRestore"); + UIWidgets::Tooltip("Toggles from Blue Potions restoring a fixed amount of mana to a percent of the player's current max mana"); + + ImGui::Separator(); + + UIWidgets::EnhancementCheckbox("Change Milk Effect", "gMilkEffect"); + UIWidgets::Tooltip("Enable the following changes to the amount of health restored by Milk"); + UIWidgets::EnhancementSliderInt("Milk Health: %d", "##MILKHEALTH", "gMilkHealth", 1, 100, "", 0, true); + UIWidgets::Tooltip("Changes the amount of health restored by Milk"); + UIWidgets::EnhancementCheckbox("Milk Percent Restore", "gMilkPercentRestore"); + UIWidgets::Tooltip("Toggles from Milk restoring a fixed amount of health to a percent of the player's current max health"); + + ImGui::Separator(); + + UIWidgets::EnhancementCheckbox("Separate Half Milk Effect", "gSeparateHalfMilkEffect"); + UIWidgets::Tooltip("Enable the following changes to the amount of health restored by Half Milk\nIf this is disabled, Half Milk will behave the same as Full Milk."); + UIWidgets::EnhancementSliderInt("Half Milk Health: %d", "##HALFMILKHEALTH", "gHalfMilkHealth", 1, 100, "", 0, true); + UIWidgets::Tooltip("Changes the amount of health restored by Half Milk"); + UIWidgets::EnhancementCheckbox("Half Milk Percent Restore", "gHalfMilkPercentRestore"); + UIWidgets::Tooltip("Toggles from Half Milk restoring a fixed amount of health to a percent of the player's current max health"); + + ImGui::Separator(); + + UIWidgets::EnhancementCheckbox("Change Fairy Effect", "gFairyEffect"); + UIWidgets::Tooltip("Enable the following changes to the amount of health restored by Fairies"); + UIWidgets::EnhancementSliderInt("Fairy: %d", "##FAIRYHEALTH", "gFairyHealth", 1, 100, "", 0, true); + UIWidgets::Tooltip("Changes the amount of health restored by Fairies"); + UIWidgets::EnhancementCheckbox("Fairy Percent Restore", "gFairyPercentRestore"); + UIWidgets::Tooltip("Toggles from Fairies restoring a fixed amount of health to a percent of the player's current max health"); + + ImGui::Separator(); + + UIWidgets::EnhancementCheckbox("Change Fairy Revive Effect", "gFairyReviveEffect"); + UIWidgets::Tooltip("Enable the following changes to the amount of health restored by Fairy Revivals"); + UIWidgets::EnhancementSliderInt("Fairy Revival: %d", "##FAIRYREVIVEHEALTH", "gFairyReviveHealth", 1, 100, "", 0, true); + UIWidgets::Tooltip("Changes the amount of health restored by Fairy Revivals"); + UIWidgets::EnhancementCheckbox("Fairy Revive Percent Restore", "gFairyRevivePercentRestore"); + UIWidgets::Tooltip("Toggles from Fairy Revivals restoring a fixed amount of health to a percent of the player's current max health"); + + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Fishing")) { + UIWidgets::EnhancementCheckbox("Instant Fishing", "gInstantFishing"); + UIWidgets::Tooltip("All fish will be caught instantly"); + UIWidgets::PaddedEnhancementCheckbox("Guarantee Bite", "gGuaranteeFishingBite", true, false); + UIWidgets::Tooltip("When a line is stable, guarantee bite. Otherwise use default logic"); + UIWidgets::PaddedEnhancementSliderInt("Child Minimum Weight: %d", "##cMinimumWeight", "gChildMinimumWeightFish", 6, 10, "", 10, false, true, false); + UIWidgets::Tooltip("The minimum weight for the unique fishing reward as a child"); + UIWidgets::PaddedEnhancementSliderInt("Adult Minimum Weight: %d", "##aMinimumWeight", "gAdultMinimumWeightFish", 8, 13, "", 13, false, true, false); + UIWidgets::Tooltip("The minimum weight for the unique fishing reward as an adult"); + ImGui::EndMenu(); + } + + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Reduced Clutter")) + { + UIWidgets::EnhancementCheckbox("Mute Low HP Alarm", "gLowHpAlarm"); + UIWidgets::Tooltip("Disable the low HP beeping sound"); + UIWidgets::PaddedEnhancementCheckbox("Minimal UI", "gMinimalUI", true, false); + UIWidgets::Tooltip("Hides most of the UI when not needed\nNote: Doesn't activate until after loading a new scene"); + UIWidgets::PaddedEnhancementCheckbox("Disable Navi Call Audio", "gDisableNaviCallAudio", true, false); + UIWidgets::Tooltip("Disables the voice audio when Navi calls you"); + + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + UIWidgets::EnhancementCheckbox("Visual Stone of Agony", "gVisualAgony"); + UIWidgets::Tooltip("Displays an icon and plays a sound when Stone of Agony should be activated, for those without rumble"); + UIWidgets::PaddedEnhancementCheckbox("Assignable Tunics and Boots", "gAssignableTunicsAndBoots", true, false); + UIWidgets::Tooltip("Allows equipping the tunic and boots to c-buttons"); + UIWidgets::PaddedEnhancementCheckbox("Equipment Toggle", "gEquipmentCanBeRemoved", true, false); + UIWidgets::Tooltip("Allows equipment to be removed by toggling it off on\nthe equipment subscreen."); + UIWidgets::PaddedEnhancementCheckbox("Link's Cow in Both Time Periods", "gCowOfTime", true, false); + UIWidgets::Tooltip("Allows the Lon Lon Ranch obstacle course reward to be shared across time periods"); + UIWidgets::PaddedEnhancementCheckbox("Enable visible guard vision", "gGuardVision", true, false); + UIWidgets::PaddedEnhancementCheckbox("Enable passage of time on file select", "gTimeFlowFileSelect", true, false); + UIWidgets::PaddedEnhancementCheckbox("Count Golden Skulltulas", "gInjectSkulltulaCount", true, false); + UIWidgets::Tooltip("Injects Golden Skulltula total count in pickup messages"); + UIWidgets::PaddedEnhancementCheckbox("Pull grave during the day", "gDayGravePull", true, false); + UIWidgets::Tooltip("Allows graves to be pulled when child during the day"); + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Graphics")) + { + if (ImGui::BeginMenu("Animated Link in Pause Menu")) { + ImGui::Text("Rotation"); + UIWidgets::EnhancementRadioButton("Disabled", "gPauseLiveLinkRotation", 0); + UIWidgets::EnhancementRadioButton("Rotate Link with D-pad", "gPauseLiveLinkRotation", 1); + UIWidgets::Tooltip("Allow you to rotate Link on the Equipment menu with the D-pad\nUse D-pad Up or D-pad Down to reset Link's rotation"); + UIWidgets::EnhancementRadioButton("Rotate Link with C-buttons", "gPauseLiveLinkRotation", 2); + UIWidgets::Tooltip("Allow you to rotate Link on the Equipment menu with the C-buttons\nUse C-Up or C-Down to reset Link's rotation"); + UIWidgets::EnhancementRadioButton("Rotate Link with Right Stick", "gPauseLiveLinkRotation", 3); + UIWidgets::Tooltip("Allow you to rotate Link on the Equipment menu with the Right Stick\nYou can zoom in by pointing up and reset Link's rotation by pointing down"); + if (CVar_GetS32("gPauseLiveLinkRotation", 0) != 0) { + UIWidgets::EnhancementSliderInt("Rotation Speed: %d", "##MinRotationSpeed", "gPauseLiveLinkRotationSpeed", 1, 20, ""); + } + UIWidgets::PaddedSeparator(); + ImGui::Text("Static loop"); + UIWidgets::EnhancementRadioButton("Disabled", "gPauseLiveLink", 0); + UIWidgets::EnhancementRadioButton("Idle (standing)", "gPauseLiveLink", 1); + UIWidgets::EnhancementRadioButton("Idle (look around)", "gPauseLiveLink", 2); + UIWidgets::EnhancementRadioButton("Idle (belt)", "gPauseLiveLink", 3); + UIWidgets::EnhancementRadioButton("Idle (shield)", "gPauseLiveLink", 4); + UIWidgets::EnhancementRadioButton("Idle (test sword)", "gPauseLiveLink", 5); + UIWidgets::EnhancementRadioButton("Idle (yawn)", "gPauseLiveLink", 6); + UIWidgets::EnhancementRadioButton("Battle Stance", "gPauseLiveLink", 7); + UIWidgets::EnhancementRadioButton("Walking (no shield)", "gPauseLiveLink", 8); + UIWidgets::EnhancementRadioButton("Walking (holding shield)", "gPauseLiveLink", 9); + UIWidgets::EnhancementRadioButton("Running (no shield)", "gPauseLiveLink", 10); + UIWidgets::EnhancementRadioButton("Running (holding shield)", "gPauseLiveLink", 11); + UIWidgets::EnhancementRadioButton("Hand on hip", "gPauseLiveLink", 12); + UIWidgets::EnhancementRadioButton("Spin attack charge", "gPauseLiveLink", 13); + UIWidgets::EnhancementRadioButton("Look at hand", "gPauseLiveLink", 14); + UIWidgets::PaddedSeparator(); + ImGui::Text("Randomize"); + UIWidgets::EnhancementRadioButton("Random", "gPauseLiveLink", 15); + UIWidgets::Tooltip("Randomize the animation played each time you open the menu"); + UIWidgets::EnhancementRadioButton("Random cycle", "gPauseLiveLink", 16); + UIWidgets::Tooltip("Randomize the animation played on the menu after a certain time"); + UIWidgets::EnhancementRadioButton("Random cycle (Idle)", "gPauseLiveLink", 17); + UIWidgets::Tooltip("Randomize the animation played on the menu after a certain time (Idle animations only)"); + if (CVar_GetS32("gPauseLiveLink", 0) >= 16) { + UIWidgets::EnhancementSliderInt("Frame to wait: %d", "##MinFrameCount", "gMinFrameCount", 1, 1000, "", 0, true); + } + + ImGui::EndMenu(); + } + UIWidgets::PaddedEnhancementCheckbox("N64 Mode", "gN64Mode", true, false); + UIWidgets::Tooltip("Sets aspect ratio to 4:3 and lowers resolution to 240p, the N64's native resolution"); + UIWidgets::PaddedEnhancementCheckbox("Enable 3D Dropped items/projectiles", "gNewDrops", true, false); + UIWidgets::Tooltip("Change most 2D items and projectiles on the overworld to their 3D versions"); + UIWidgets::PaddedEnhancementCheckbox("Disable Black Bar Letterboxes", "gDisableBlackBars", true, false); + UIWidgets::Tooltip("Disables Black Bar Letterboxes during cutscenes and Z-targeting\nNote: there may be minor visual glitches that were covered up by the black bars\nPlease disable this setting before reporting a bug"); + UIWidgets::PaddedEnhancementCheckbox("Dynamic Wallet Icon", "gDynamicWalletIcon", true, false); + UIWidgets::Tooltip("Changes the rupee in the wallet icon to match the wallet size you currently have"); + UIWidgets::PaddedEnhancementCheckbox("Always show dungeon entrances", "gAlwaysShowDungeonMinimapIcon", true, false); + UIWidgets::Tooltip("Always shows dungeon entrance icons on the minimap"); + + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Fixes")) + { + UIWidgets::EnhancementCheckbox("Fix L&R Pause menu", "gUniformLR"); + UIWidgets::Tooltip("Makes the L and R buttons in the pause menu the same color"); + UIWidgets::PaddedEnhancementCheckbox("Fix L&Z Page switch in Pause menu", "gNGCKaleidoSwitcher", true, false); + UIWidgets::Tooltip("Makes L and R switch pages like on the GameCube\nZ opens the Debug Menu instead"); + UIWidgets::PaddedEnhancementCheckbox("Fix Dungeon entrances", "gFixDungeonMinimapIcon", true, false); + UIWidgets::Tooltip("Removes the dungeon entrance icon on the top-left corner of the screen when no dungeon is present on the current map"); + UIWidgets::PaddedEnhancementCheckbox("Fix Two Handed idle animations", "gTwoHandedIdle", true, false); + UIWidgets::Tooltip("Re-enables the two-handed idle animation, a seemingly finished animation that was disabled on accident in the original game"); + UIWidgets::PaddedEnhancementCheckbox("Fix the Gravedigging Tour Glitch", "gGravediggingTourFix", true, false); + UIWidgets::Tooltip("Fixes a bug where the Gravedigging Tour Heart Piece disappears if the area reloads"); + UIWidgets::PaddedEnhancementCheckbox("Fix Deku Nut upgrade", "gDekuNutUpgradeFix", true, false); + UIWidgets::Tooltip("Prevents the Forest Stage Deku Nut upgrade from becoming unobtainable after receiving the Poacher's Saw"); + UIWidgets::PaddedEnhancementCheckbox("Fix Navi text HUD position", "gNaviTextFix", true, false); + UIWidgets::Tooltip("Correctly centers the Navi text prompt on the HUD's C-Up button"); + UIWidgets::PaddedEnhancementCheckbox("Fix Anubis fireballs", "gAnubisFix", true, false); + UIWidgets::Tooltip("Make Anubis fireballs do fire damage when reflected back at them with the Mirror Shield"); + UIWidgets::PaddedEnhancementCheckbox("Fix Megaton Hammer crouch stab", "gCrouchStabHammerFix", true, false); + UIWidgets::Tooltip("Make the Megaton Hammer's crouch stab able to destroy rocks without first swinging it normally"); + if (CVar_GetS32("gCrouchStabHammerFix", 0) == 0) { + CVar_SetS32("gCrouchStabFix", 0); + } else { + UIWidgets::PaddedEnhancementCheckbox("Remove power crouch stab", "gCrouchStabFix", true, false); + UIWidgets::Tooltip("Make crouch stabbing always do the same damage as a regular slash"); + } + + ImGui::EndMenu(); + } + + UIWidgets::Spacer(0); + + if (ImGui::BeginMenu("Restoration")) + { + UIWidgets::EnhancementCheckbox("Red Ganon blood", "gRedGanonBlood"); + UIWidgets::Tooltip("Restore the original red blood from NTSC 1.0/1.1. Disable for green blood"); + UIWidgets::PaddedEnhancementCheckbox("Fish while hovering", "gHoverFishing", true, false); + UIWidgets::Tooltip("Restore a bug from NTSC 1.0 that allows casting the Fishing Rod while using the Hover Boots"); + UIWidgets::PaddedEnhancementCheckbox("N64 Weird Frames", "gN64WeirdFrames", true, false); + UIWidgets::Tooltip("Restores N64 Weird Frames allowing weirdshots to behave the same as N64"); + UIWidgets::PaddedEnhancementCheckbox("Bombchus out of bounds", "gBombchusOOB", true, false); + UIWidgets::Tooltip("Allows bombchus to explode out of bounds\nSimilar to GameCube and Wii VC"); + UIWidgets::PaddedEnhancementCheckbox("Restore old Gold Skulltula cutscene", "gGsCutscene", true, false); + + ImGui::EndMenu(); + } + + UIWidgets::PaddedEnhancementCheckbox("Autosave", "gAutosave", true, false); + UIWidgets::Tooltip("Automatically save the game every time a new area is entered or item is obtained\n" + "To disable saving when obtaining an item, manually set gAutosaveAllItems and gAutosaveMajorItems to 0\n" + "gAutosaveAllItems takes priority over gAutosaveMajorItems if both are set to 1\n" + "gAutosaveMajorItems excludes rupees and health/magic/ammo refills (but includes bombchus)"); + + UIWidgets::Spacer(0); + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); + static ImVec2 buttonSize(200.0f, 0.0f); + if (ImGui::Button(GetWindowButtonText("Cosmetics Editor", CVar_GetS32("gCosmeticsEditorEnabled", 0)).c_str(), buttonSize)) + { + bool currentValue = CVar_GetS32("gCosmeticsEditorEnabled", 0); + CVar_SetS32("gCosmeticsEditorEnabled", !currentValue); + SohImGui::RequestCvarSaveOnNextTick(); + SohImGui::EnableWindow("Cosmetics Editor", CVar_GetS32("gCosmeticsEditorEnabled", 0)); + } + ImGui::PopStyleVar(3); + ImGui::PopStyleColor(1); + + EXPERIMENTAL(); + + const char* fps_cvar = "gInterpolationFPS"; + { + #if defined(__SWITCH__) || defined(__WIIU__) + int minFps = 20; + int maxFps = 60; + #else + int minFps = 20; + int maxFps = 360; + #endif + + int val = CVar_GetS32(fps_cvar, minFps); + val = fmax(fmin(val, maxFps), 20); + + #ifdef __WIIU__ + // only support divisors of 60 on the Wii U + val = 60 / (60 / val); + #endif + + int fps = val; + + if (fps == 20) + { + ImGui::Text("Frame interpolation: Off"); + } + else + { + ImGui::Text("Frame interpolation: %d FPS", fps); + } + + std::string MinusBTNFPSI = " - ##FPSInterpolation"; + std::string PlusBTNFPSI = " + ##FPSInterpolation"; + if (ImGui::Button(MinusBTNFPSI.c_str())) { + #ifdef __WIIU__ + if (val >= 60) val = 30; + else val = 20; + #else + val--; + #endif + CVar_SetS32(fps_cvar, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + #ifdef __WIIU__ + ImGui::PushItemWidth(ImGui::GetWindowSize().x - 79.0f * 2); + #else + ImGui::PushItemWidth(ImGui::GetWindowSize().x - 79.0f); + #endif + if (ImGui::SliderInt("##FPSInterpolation", &val, minFps, maxFps, "", ImGuiSliderFlags_AlwaysClamp)) + { + #ifdef __WIIU__ + // only support divisors of 60 on the Wii U + val = 60 / (60 / val); + #endif + if (val > 360) + { + val = 360; + } + else if (val < 20) + { + val = 20; + } + + CVar_SetS32(fps_cvar, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + ImGui::PopItemWidth(); + UIWidgets::Tooltip("Interpolate extra frames to get smoother graphics\n" + "Set to match your monitor's refresh rate, or a divisor of it\n" + "A higher target FPS than your monitor's refresh rate will just waste resources, " + "and might give a worse result.\n" + "For consistent input lag, set this value and your monitor's refresh rate to a multiple of 20\n" + "Ctrl+Click for keyboard input"); + + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + if (ImGui::Button(PlusBTNFPSI.c_str())) { + #ifdef __WIIU__ + if (val <= 20) val = 30; + else val = 60; + #else + val++; + #endif + CVar_SetS32(fps_cvar, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + } + + if (SohImGui::WindowBackend() == SohImGui::Backend::DX11) + { + UIWidgets::Spacer(0); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f)); + if (ImGui::Button("Match Refresh Rate")) + { + int hz = roundf(SohImGui::WindowRefreshRate()); + if (hz >= 20 && hz <= 360) + { + CVar_SetS32(fps_cvar, hz); + SohImGui::RequestCvarSaveOnNextTick(); + } + } + ImGui::PopStyleVar(1); + UIWidgets::Spacer(0); + } + UIWidgets::EnhancementCheckbox("Disable LOD", "gDisableLOD"); + UIWidgets::Tooltip("Turns off the Level of Detail setting, making models use their higher-poly variants at any distance"); + UIWidgets::PaddedEnhancementCheckbox("Disable Draw Distance", "gDisableDrawDistance", true, false); + UIWidgets::Tooltip("Turns off the objects draw distance, making objects being visible from a longer range"); + if (CVar_GetS32("gDisableDrawDistance", 0) == 0) { + CVar_SetS32("gDisableKokiriDrawDistance", 0); + } else if (CVar_GetS32("gDisableDrawDistance", 0) == 1) { + UIWidgets::PaddedEnhancementCheckbox("Kokiri Draw Distance", "gDisableKokiriDrawDistance", true, false); + UIWidgets::Tooltip("The Kokiri are mystical beings that fade into view when approached\nEnabling this will remove their draw distance"); + } + UIWidgets::PaddedEnhancementCheckbox("Skip Text", "gSkipText", true, false); + UIWidgets::Tooltip("Holding down B skips text\nKnown to cause a cutscene softlock in Water Temple\nSoftlock can be fixed by pressing D-Right in Debug mode"); + UIWidgets::PaddedEnhancementCheckbox("Free Camera", "gFreeCamera", true, false); + UIWidgets::Tooltip("Enables camera control\nNote: You must remap C buttons off of the right stick in the controller config menu, and map the camera stick to the right stick."); + + #ifdef __SWITCH__ + UIWidgets::Spacer(0); + int slot = CVar_GetS32("gSwitchPerfMode", (int)Ship::SwitchProfiles::STOCK); + ImGui::Text("Switch performance mode"); + if (ImGui::BeginCombo("##perf", SWITCH_CPU_PROFILES[slot])) { + for (int sId = 0; sId <= Ship::SwitchProfiles::POWERSAVINGM3; sId++) { + if (ImGui::Selectable(SWITCH_CPU_PROFILES[sId], sId == slot)) { + SPDLOG_INFO("Profile:: %s", SWITCH_CPU_PROFILES[sId]); + CVar_SetS32("gSwitchPerfMode", sId); + Ship::Switch::ApplyOverclock(); + SohImGui::RequestCvarSaveOnNextTick(); + } + + } + ImGui::EndCombo(); + } + #endif + + ImGui::EndMenu(); + } + + ImGui::SetCursorPosY(0.0f); + + if (ImGui::BeginMenu("Cheats")) + { + if (ImGui::BeginMenu("Infinite...")) { + UIWidgets::EnhancementCheckbox("Money", "gInfiniteMoney"); + UIWidgets::PaddedEnhancementCheckbox("Health", "gInfiniteHealth", true, false); + UIWidgets::PaddedEnhancementCheckbox("Ammo", "gInfiniteAmmo", true, false); + UIWidgets::PaddedEnhancementCheckbox("Magic", "gInfiniteMagic", true, false); + UIWidgets::PaddedEnhancementCheckbox("Nayru's Love", "gInfiniteNayru", true, false); + UIWidgets::PaddedEnhancementCheckbox("Epona Boost", "gInfiniteEpona", true, false); + + ImGui::EndMenu(); + } + + UIWidgets::PaddedEnhancementCheckbox("No Clip", "gNoClip", true, false); + UIWidgets::Tooltip("Allows you to walk through walls"); + UIWidgets::PaddedEnhancementCheckbox("Climb Everything", "gClimbEverything", true, false); + UIWidgets::Tooltip("Makes every surface in the game climbable"); + UIWidgets::PaddedEnhancementCheckbox("Moon Jump on L", "gMoonJumpOnL", true, false); + UIWidgets::Tooltip("Holding L makes you float into the air"); + UIWidgets::PaddedEnhancementCheckbox("Super Tunic", "gSuperTunic", true, false); + UIWidgets::Tooltip("Makes every tunic have the effects of every other tunic"); + UIWidgets::PaddedEnhancementCheckbox("Easy ISG", "gEzISG", true, false); + UIWidgets::Tooltip("Passive Infinite Sword Glitch\nIt makes your sword's swing effect and hitbox stay active indefinitely"); + UIWidgets::PaddedEnhancementCheckbox("Unrestricted Items", "gNoRestrictItems", true, false); + UIWidgets::Tooltip("Allows you to use any item at any location"); + UIWidgets::PaddedEnhancementCheckbox("Freeze Time", "gFreezeTime", true, false); + UIWidgets::Tooltip("Freezes the time of day"); + UIWidgets::PaddedEnhancementCheckbox("Drops Don't Despawn", "gDropsDontDie", true, false); + UIWidgets::Tooltip("Drops from enemies, grass, etc. don't disappear after a set amount of time"); + UIWidgets::PaddedEnhancementCheckbox("Fireproof Deku Shield", "gFireproofDekuShield", true, false); + UIWidgets::Tooltip("Prevents the Deku Shield from burning on contact with fire"); + UIWidgets::PaddedEnhancementCheckbox("Shield with Two-Handed Weapons", "gShieldTwoHanded", true, false); + UIWidgets::Tooltip("This allows you to put up your shield with any two-handed weapon in hand except for Deku Sticks"); + UIWidgets::PaddedEnhancementCheckbox("Time Sync", "gTimeSync", true, false); + UIWidgets::Tooltip("This syncs the ingame time with the real world time"); + + { + static int32_t betaQuestEnabled = CVar_GetS32("gEnableBetaQuest", 0); + static int32_t lastBetaQuestEnabled = betaQuestEnabled; + static int32_t betaQuestWorld = CVar_GetS32("gBetaQuestWorld", 0xFFEF); + static int32_t lastBetaQuestWorld = betaQuestWorld; + + if (!isBetaQuestEnabled) { + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); + } + + UIWidgets::PaddedEnhancementCheckbox("Enable Beta Quest", "gEnableBetaQuest", true, false); + UIWidgets::Tooltip("Turns on OoT Beta Quest. *WARNING* This will reset your game."); + betaQuestEnabled = CVar_GetS32("gEnableBetaQuest", 0); + if (betaQuestEnabled) { + if (betaQuestEnabled != lastBetaQuestEnabled) { + betaQuestWorld = 0; + } + + ImGui::Text("Beta Quest World: %d", betaQuestWorld); + + if (ImGui::Button(" - ##BetaQuest")) { + betaQuestWorld--; + } + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + + ImGui::SliderInt("##BetaQuest", &betaQuestWorld, 0, 8, "", ImGuiSliderFlags_AlwaysClamp); + UIWidgets::Tooltip("Set the Beta Quest world to explore. *WARNING* Changing this will reset your game.\nCtrl+Click to type in a value."); + + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + if (ImGui::Button(" + ##BetaQuest")) { + betaQuestWorld++; + } + + if (betaQuestWorld > 8) { + betaQuestWorld = 8; + } + else if (betaQuestWorld < 0) { + betaQuestWorld = 0; + } + } + else { + lastBetaQuestWorld = betaQuestWorld = 0xFFEF; + CVar_SetS32("gBetaQuestWorld", betaQuestWorld); + } + if (betaQuestEnabled != lastBetaQuestEnabled || betaQuestWorld != lastBetaQuestWorld) + { + // Reset the game if the beta quest state or world changed because beta quest happens on redirecting the title screen cutscene. + lastBetaQuestEnabled = betaQuestEnabled; + lastBetaQuestWorld = betaQuestWorld; + CVar_SetS32("gEnableBetaQuest", betaQuestEnabled); + CVar_SetS32("gBetaQuestWorld", betaQuestWorld); + + SohImGui::DispatchConsoleCommand("reset"); + + SohImGui::RequestCvarSaveOnNextTick(); + } + + if (!isBetaQuestEnabled) { + ImGui::PopItemFlag(); + ImGui::PopStyleVar(1); + } + } + + ImGui::EndMenu(); + } + + ImGui::SetCursorPosY(0.0f); + + if (ImGui::BeginMenu("Developer Tools")) + { + UIWidgets::EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled"); + UIWidgets::Tooltip("Enables Debug Mode, allowing you to select maps with L + R + Z, noclip with L + D-pad Right, and open the debug menu with L on the pause screen"); + UIWidgets::PaddedEnhancementCheckbox("OoT Skulltula Debug", "gSkulltulaDebugEnabled", true, false); + UIWidgets::Tooltip("Enables Skulltula Debug, when moving the cursor in the menu above various map icons (boss key, compass, map screen locations, etc) will set the GS bits in that area.\nUSE WITH CAUTION AS IT DOES NOT UPDATE THE GS COUNT."); + UIWidgets::PaddedEnhancementCheckbox("Fast File Select", "gSkipLogoTitle", true, false); + UIWidgets::Tooltip("Load the game to the selected menu or file\n\"Zelda Map Select\" require debug mode else you will fallback to File choose menu\nUsing a file number that don't have save will create a save file only if you toggle on \"Create a new save if none ?\" else it will bring you to the File choose menu"); + if (CVar_GetS32("gSkipLogoTitle", 0)) { + const char* FastFileSelect[5] = { + "File N.1", + "File N.2", + "File N.3", + "File select", + "Zelda Map Select (require OoT Debug Mode)" + }; + ImGui::Text("Loading :"); + UIWidgets::EnhancementCombobox("gSaveFileID", FastFileSelect, 5, 0); + UIWidgets::PaddedEnhancementCheckbox("Create a new save if none", "gCreateNewSave", true, false); + UIWidgets::Tooltip("Enable the creation of a new save file if none exist in the File number selected\nNo file name will be assigned please do in Save editor once you see the first text else your save file name will be named \"00000000\"\nIf disabled you will fall back in File select menu"); + }; + UIWidgets::PaddedSeparator(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0,0)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); + static ImVec2 buttonSize(160.0f, 0.0f); + if (ImGui::Button(GetWindowButtonText("Stats", CVar_GetS32("gStatsEnabled", 0)).c_str(), buttonSize)) + { + bool currentValue = CVar_GetS32("gStatsEnabled", 0); + CVar_SetS32("gStatsEnabled", !currentValue); + SohImGui::ToggleStatisticsWindow(true); + SohImGui::RequestCvarSaveOnNextTick(); + } + UIWidgets::Tooltip("Shows the stats window, with your FPS and frametimes, and the OS you're playing on"); + UIWidgets::Spacer(0); + if (ImGui::Button(GetWindowButtonText("Console", CVar_GetS32("gConsoleEnabled", 0)).c_str(), buttonSize)) + { + bool currentValue = CVar_GetS32("gConsoleEnabled", 0); + CVar_SetS32("gConsoleEnabled", !currentValue); + SohImGui::RequestCvarSaveOnNextTick(); + SohImGui::ToggleConsoleWindow(!currentValue); + } + UIWidgets::Tooltip("Enables the console window, allowing you to input commands, type help for some examples"); + UIWidgets::Spacer(0); + if (ImGui::Button(GetWindowButtonText("Save Editor", CVar_GetS32("gSaveEditorEnabled", 0)).c_str(), buttonSize)) + { + bool currentValue = CVar_GetS32("gSaveEditorEnabled", 0); + CVar_SetS32("gSaveEditorEnabled", !currentValue); + SohImGui::RequestCvarSaveOnNextTick(); + SohImGui::EnableWindow("Save Editor", CVar_GetS32("gSaveEditorEnabled", 0)); + } + UIWidgets::Spacer(0); + if (ImGui::Button(GetWindowButtonText("Collision Viewer", CVar_GetS32("gCollisionViewerEnabled", 0)).c_str(), buttonSize)) + { + bool currentValue = CVar_GetS32("gCollisionViewerEnabled", 0); + CVar_SetS32("gCollisionViewerEnabled", !currentValue); + SohImGui::RequestCvarSaveOnNextTick(); + SohImGui::EnableWindow("Collision Viewer", CVar_GetS32("gCollisionViewerEnabled", 0)); + } + UIWidgets::Spacer(0); + if (ImGui::Button(GetWindowButtonText("Actor Viewer", CVar_GetS32("gActorViewerEnabled", 0)).c_str(), buttonSize)) + { + bool currentValue = CVar_GetS32("gActorViewerEnabled", 0); + CVar_SetS32("gActorViewerEnabled", !currentValue); + SohImGui::RequestCvarSaveOnNextTick(); + SohImGui::EnableWindow("Actor Viewer", CVar_GetS32("gActorViewerEnabled", 0)); + } + ImGui::PopStyleVar(3); + ImGui::PopStyleColor(1); + + ImGui::EndMenu(); + } + + ImGui::SetCursorPosY(0.0f); + + if (ImGui::BeginMenu("Randomizer")) + { + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.22f, 0.38f, 0.56f, 1.0f)); + static ImVec2 buttonSize(200.0f, 0.0f); + if (ImGui::Button(GetWindowButtonText("Randomizer Settings", CVar_GetS32("gRandomizerSettingsEnabled", 0)).c_str(), buttonSize)) + { + bool currentValue = CVar_GetS32("gRandomizerSettingsEnabled", 0); + CVar_SetS32("gRandomizerSettingsEnabled", !currentValue); + SohImGui::RequestCvarSaveOnNextTick(); + SohImGui::EnableWindow("Randomizer Settings", CVar_GetS32("gRandomizerSettingsEnabled", 0)); + } + UIWidgets::Spacer(0); + if (ImGui::Button(GetWindowButtonText("Item Tracker", CVar_GetS32("gItemTrackerEnabled", 0)).c_str(), buttonSize)) + { + bool currentValue = CVar_GetS32("gItemTrackerEnabled", 0); + CVar_SetS32("gItemTrackerEnabled", !currentValue); + SohImGui::RequestCvarSaveOnNextTick(); + SohImGui::EnableWindow("Item Tracker", CVar_GetS32("gItemTrackerEnabled", 0)); + } + ImGui::PopStyleVar(3); + ImGui::PopStyleColor(1); + + ImGui::EndMenu(); + } + } +} diff --git a/soh/soh/GameMenuBar.hpp b/soh/soh/GameMenuBar.hpp new file mode 100644 index 000000000..07280707b --- /dev/null +++ b/soh/soh/GameMenuBar.hpp @@ -0,0 +1,27 @@ +// +// GameMenuBar.hpp +// soh +// +// Created by David Chavez on 24.08.22. +// + +#ifndef GameMenuBar_hpp +#define GameMenuBar_hpp + +#include + +#ifdef __cplusplus +extern "C" { +#endif + void enableBetaQuest(); + void disableBetaQuest(); +#ifdef __cplusplus +} +#endif + +namespace GameMenuBar { + void SetupHooks(); + void Draw(); +} + +#endif /* GameMenuBar_hpp */ diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 66aa22868..d7ae15bcc 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -5,45 +5,45 @@ #include #include -#include "ResourceMgr.h" -#include "DisplayList.h" -#include "PlayerAnimation.h" -#include "Skeleton.h" -#include "Window.h" +#include +#include +#include +#include +#include #include "z64animation.h" #include "z64bgcheck.h" #include "Enhancements/gameconsole.h" #include -#include +#include #ifdef _WIN32 #include #else #include #endif -#include -#include -#include -#include "Lib/stb/stb_image.h" +#include +#include +#include +#include #define DRMP3_IMPLEMENTATION -#include "Lib/dr_libs/mp3.h" +#include #define DRWAV_IMPLEMENTATION -#include "Lib/dr_libs/wav.h" -#include "AudioPlayer.h" +#include +#include #include "Enhancements/controls/GameControlEditor.h" #include "Enhancements/cosmetics/CosmeticsEditor.h" #include "Enhancements/debugconsole.h" #include "Enhancements/debugger/debugger.h" -#include +#include "Enhancements/randomizer/randomizer_item_tracker.h" #include "Enhancements/n64_weird_frame_data.inc" -#include "soh/frame_interpolation.h" +#include "frame_interpolation.h" #include "variables.h" #include "macros.h" #include -#include "Hooks.h" -#include +#include +#include "Enhancements/custom-message/CustomMessageManager.h" -#include "Lib/Fast3D/gfx_pc.h" -#include "Lib/Fast3D/gfx_rendering_api.h" +#include +#include #ifdef __APPLE__ #include @@ -52,15 +52,16 @@ #endif #ifdef __SWITCH__ -#include "SwitchImpl.h" +#include #elif defined(__WIIU__) -#include "WiiUImpl.h" +#include #endif -#include -#include +#include +#include "Enhancements/custom-message/CustomMessageTypes.h" #include -#include +#include "Enhancements/item-tables/ItemTableManager.h" +#include "GameMenuBar.hpp" OTRGlobals* OTRGlobals::Instance; SaveManager* SaveManager::Instance; @@ -321,6 +322,9 @@ extern "C" void InitOTR() { #elif defined(__WIIU__) Ship::WiiU::Init(); #endif + SohImGui::AddSetupHooksDelegate(GameMenuBar::SetupHooks); + SohImGui::RegisterMenuDrawMethod(GameMenuBar::Draw); + OTRGlobals::Instance = new OTRGlobals(); SaveManager::Instance = new SaveManager(); CustomMessageManager::Instance = new CustomMessageManager(); diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 4858c41b2..658044ed8 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -7,7 +7,7 @@ #include #ifdef __cplusplus -#include "Window.h" +#include #include "Enhancements/savestates.h" #include "Enhancements/randomizer/randomizer.h" diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 9bf99ac12..d02584413 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -4,7 +4,7 @@ #include "z64.h" #include "functions.h" #include "macros.h" -#include "Cvar.h" +#include #define NOGDI // avoid various windows defines that conflict with things in z64.h #include "spdlog/spdlog.h" @@ -1599,4 +1599,4 @@ extern "C" void Save_DeleteFile(int fileNum) { extern "C" bool Save_Exist(int fileNum) { return SaveManager::Instance->SaveFile_Exist(fileNum); -} \ No newline at end of file +} diff --git a/soh/soh/SaveManager.h b/soh/soh/SaveManager.h index 06a382baa..1acbcbfc9 100644 --- a/soh/soh/SaveManager.h +++ b/soh/soh/SaveManager.h @@ -23,7 +23,7 @@ typedef struct { #include #include -#include "Lib/nlohmann/json.hpp" +#include class SaveManager { public: diff --git a/soh/soh/UIWidgets.cpp b/soh/soh/UIWidgets.cpp new file mode 100644 index 000000000..d61ddc0f9 --- /dev/null +++ b/soh/soh/UIWidgets.cpp @@ -0,0 +1,523 @@ +// +// UIWidgets.cpp +// soh +// +// Created by David Chavez on 25.08.22. +// + +#include "UIWidgets.hpp" + +#define IMGUI_DEFINE_MATH_OPERATORS +#include +#include +#include + +#include + +namespace UIWidgets { + + // MARK: - Layout Helper + + // Automatically adds newlines to break up text longer than a specified number of characters + // Manually included newlines will still be respected and reset the line length + // If line is midword when it hits the limit, text should break at the last encountered space + char* WrappedText(const char* text, unsigned int charactersPerLine) { + std::string newText(text); + const size_t tipLength = newText.length(); + int lastSpace = -1; + size_t currentLineLength = 0; + for (unsigned int currentCharacter = 0; currentCharacter < tipLength; currentCharacter++) { + if (newText[currentCharacter] == '\n') { + currentLineLength = 0; + lastSpace = -1; + continue; + } else if (newText[currentCharacter] == ' ') { + lastSpace = currentCharacter; + } + + if ((currentLineLength >= charactersPerLine) && (lastSpace >= 0)) { + newText[lastSpace] = '\n'; + currentLineLength = currentCharacter - lastSpace - 1; + lastSpace = -1; + } + currentLineLength++; + } + + return strdup(newText.c_str()); + } + + char* WrappedText(const std::string& text, unsigned int charactersPerLine) { + return WrappedText(text.c_str(), charactersPerLine); + } + + void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha) + { + Color_RGBA8 defaultColors; + defaultColors.r = default_colors.x; + defaultColors.g = default_colors.y; + defaultColors.b = default_colors.z; + defaultColors.a = default_colors.w; + + Color_RGBA8 cvarColor = CVar_GetRGBA(cvarname, defaultColors); + + ColorArray.x = cvarColor.r / 255.0; + ColorArray.y = cvarColor.g / 255.0; + ColorArray.z = cvarColor.b / 255.0; + ColorArray.w = cvarColor.a / 255.0; + } + + void SetLastItemHoverText(const std::string& text) { + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text("%s", WrappedText(text, 60)); + ImGui::EndTooltip(); + } + } + + // Adds a "?" next to the previous ImGui item with a custom tooltip + void InsertHelpHoverText(const std::string& text) { + ImGui::SameLine(); + ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "?"); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text("%s", WrappedText(text, 60)); + ImGui::EndTooltip(); + } + } + + + // MARK: - UI Elements + + void Tooltip(const char* text) { + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("%s", WrappedText(text)); + } + } + + void Spacer(float height) { + ImGui::Dummy(ImVec2(0.0f, height)); + } + + void PaddedSeparator(bool padTop, bool padBottom, float extraVerticalTopPadding, float extraVerticalBottomPadding) { + if (padTop) + Spacer(0); + + ImGui::Separator(); + + if (padBottom) + Spacer(0); + } + + void RenderCross(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz) { + float thickness = ImMax(sz / 5.0f, 1.0f); + sz -= thickness * 0.5f; + pos += ImVec2(thickness * 0.25f, thickness * 0.25f); + + draw_list->PathLineTo(ImVec2(pos.x, pos.y)); + draw_list->PathLineTo(ImVec2(pos.x + sz, pos.y + sz)); + draw_list->PathStroke(col, 0, thickness); + + draw_list->PathLineTo(ImVec2(pos.x + sz, pos.y)); + draw_list->PathLineTo(ImVec2(pos.x, pos.y + sz)); + draw_list->PathStroke(col, 0, thickness); + } + + bool CustomCheckbox(const char* label, bool* v, bool disabled, CheckboxGraphics disabledGraphic) { + ImGuiWindow* window = ImGui::GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); + + const float square_sz = ImGui::GetFrameHeight(); + const ImVec2 pos = window->DC.CursorPos; + const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f)); + ImGui::ItemSize(total_bb, style.FramePadding.y); + if (!ImGui::ItemAdd(total_bb, id)) { + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0)); + return false; + } + + bool hovered, held; + bool pressed = ImGui::ButtonBehavior(total_bb, id, &hovered, &held); + if (pressed) { + *v = !(*v); + ImGui::MarkItemEdited(id); + } + + const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz)); + ImGui::RenderNavHighlight(total_bb, id); + ImGui::RenderFrame(check_bb.Min, check_bb.Max, ImGui::GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); + ImU32 check_col = ImGui::GetColorU32(ImGuiCol_CheckMark); + ImU32 cross_col = ImGui::GetColorU32(ImVec4(0.50f, 0.50f, 0.50f, 1.00f)); + bool mixed_value = (g.LastItemData.InFlags & ImGuiItemFlags_MixedValue) != 0; + if (mixed_value) { + // Undocumented tristate/mixed/indeterminate checkbox (#2644) + // This may seem awkwardly designed because the aim is to make ImGuiItemFlags_MixedValue supported by all widgets (not just checkbox) + ImVec2 pad(ImMax(1.0f, IM_FLOOR(square_sz / 3.6f)), ImMax(1.0f, IM_FLOOR(square_sz / 3.6f))); + window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding); + } else if ((!disabled && *v) || (disabled && disabledGraphic == CheckboxGraphics::Checkmark)) { + const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f)); + ImGui::RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f); + } else if (disabled && disabledGraphic == CheckboxGraphics::Cross) { + const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f)); + RenderCross(window->DrawList, check_bb.Min + ImVec2(pad, pad), cross_col, square_sz - pad * 2.0f); + } + + ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y); + if (g.LogEnabled) + ImGui::LogRenderedText(&label_pos, mixed_value ? "[~]" : *v ? "[x]" : "[ ]"); + if (label_size.x > 0.0f) + ImGui::RenderText(label_pos, label); + + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0)); + return pressed; + } + + void EnhancementCheckbox(const char* text, const char* cvarName, bool disabled, const char* disabledTooltipText, CheckboxGraphics disabledGraphic) { + if (disabled) { + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); + } + bool val = (bool)CVar_GetS32(cvarName, 0); + if (CustomCheckbox(text, &val, disabled, disabledGraphic)) { + CVar_SetS32(cvarName, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + + if (disabled) { + ImGui::PopStyleVar(1); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(disabledTooltipText, "") != 0) { + ImGui::SetTooltip("%s", disabledTooltipText); + } + ImGui::PopItemFlag(); + } + } + + void PaddedEnhancementCheckbox(const char* text, const char* cvarName, bool padTop, bool padBottom, bool disabled, const char* disabledTooltipText, CheckboxGraphics disabledGraphic) { + if (padTop) Spacer(0); + + EnhancementCheckbox(text, cvarName, disabled, disabledTooltipText, disabledGraphic); + + if (padBottom) Spacer(0); + } + + void EnhancementCombo(const std::string& name, const char* cvarName, const std::vector& items, int defaultValue) { + if (ImGui::BeginCombo(name.c_str(), items[static_cast(CVar_GetS32(cvarName, defaultValue))].c_str())) { + for (int settingIndex = 0; settingIndex < (int) items.size(); settingIndex++) { + if (ImGui::Selectable(items[settingIndex].c_str())) { + CVar_SetS32(cvarName, settingIndex); + SohImGui::RequestCvarSaveOnNextTick(); + + } + } + ImGui::EndCombo(); + } + } + + void EnhancementCombobox(const char* name, const char* ComboArray[], size_t arraySize, uint8_t FirstTimeValue) { + if (FirstTimeValue <= 0) { + FirstTimeValue = 0; + } + uint8_t selected = CVar_GetS32(name, FirstTimeValue); + uint8_t DefaultValue = selected; + std::string comboName = std::string("##") + std::string(name); + if (ImGui::BeginCombo(comboName.c_str(), ComboArray[DefaultValue])) { + for (uint8_t i = 0; i < arraySize; i++) { + if (strlen(ComboArray[i]) > 1) { + if (ImGui::Selectable(ComboArray[i], i == selected)) { + CVar_SetS32(name, i); + selected = i; + SohImGui::RequestCvarSaveOnNextTick(); + } + } + } + ImGui::EndCombo(); + } + } + + void PaddedText(const char* text, bool padTop, bool padBottom) { + if (padTop) + Spacer(0); + + ImGui::Text("%s", text); + + if (padBottom) + Spacer(0); + } + + void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue, bool PlusMinusButton) { + int val = CVar_GetS32(cvarName, defaultValue); + ImGui::Text(text, val); + if(PlusMinusButton) { + std::string MinusBTNName = " - ##"; + MinusBTNName += cvarName; + if (ImGui::Button(MinusBTNName.c_str())) { + val--; + CVar_SetS32(cvarName, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + } + + if (ImGui::SliderInt(id, &val, min, max, format)) + { + CVar_SetS32(cvarName, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + + if(PlusMinusButton) { + std::string PlusBTNName = " + ##"; + PlusBTNName += cvarName; + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + if (ImGui::Button(PlusBTNName.c_str())) { + val++; + CVar_SetS32(cvarName, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + } + + if (val < min) + { + val = min; + CVar_SetS32(cvarName, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + + if (val > max) + { + val = max; + CVar_SetS32(cvarName, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + } + + void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton) { + float val = CVar_GetFloat(cvarName, defaultValue); + + if (!isPercentage) + ImGui::Text(text, val); + else + ImGui::Text(text, static_cast(100 * val)); + + Spacer(0); + + if(PlusMinusButton) { + std::string MinusBTNName = " - ##"; + MinusBTNName += cvarName; + if (ImGui::Button(MinusBTNName.c_str())) { + if (!isPercentage) + val -= 0.1f; + else + val -= 0.01f; + CVar_SetFloat(cvarName, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + } + if (PlusMinusButton) { + #ifdef __WIIU__ + ImGui::PushItemWidth(ImGui::GetWindowSize().x - 79.0f * 2); + #else + ImGui::PushItemWidth(ImGui::GetWindowSize().x - 79.0f); + #endif + } + if (ImGui::SliderFloat(id, &val, min, max, format)) + { + CVar_SetFloat(cvarName, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + if (PlusMinusButton) { + ImGui::PopItemWidth(); + } + if(PlusMinusButton) { + std::string PlusBTNName = " + ##"; + PlusBTNName += cvarName; + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + if (ImGui::Button(PlusBTNName.c_str())) { + if (!isPercentage) + val += 0.1f; + else + val += 0.01f; + CVar_SetFloat(cvarName, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + } + + if (val < min) + { + val = min; + CVar_SetFloat(cvarName, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + + if (val > max) + { + val = max; + CVar_SetFloat(cvarName, val); + SohImGui::RequestCvarSaveOnNextTick(); + } + } + + void PaddedEnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue, bool PlusMinusButton, bool padTop, bool padBottom) { + if (padTop) + Spacer(0); + + EnhancementSliderInt(text, id, cvarName, min, max, format, defaultValue, PlusMinusButton); + + if (padBottom) + Spacer(0); + } + + void EnhancementRadioButton(const char* text, const char* cvarName, int id) { + /*Usage : + EnhancementRadioButton("My Visible Name","gMyCVarName", MyID); + First arg is the visible name of the Radio button + Second is the cvar name where MyID will be saved. + Note: the CVar name should be the same to each Buddies. + Example : + EnhancementRadioButton("English", "gLanguages", 0); + EnhancementRadioButton("German", "gLanguages", 1); + EnhancementRadioButton("French", "gLanguages", 2); + */ + std::string make_invisible = "##"; + make_invisible += text; + make_invisible += cvarName; + + int val = CVar_GetS32(cvarName, 0); + if (ImGui::RadioButton(make_invisible.c_str(), id == val)) { + CVar_SetS32(cvarName, id); + SohImGui::RequestCvarSaveOnNextTick(); + } + ImGui::SameLine(); + ImGui::Text("%s", text); + } + + void ResetColor(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha) { + std::string Cvar_RBM = cvarName; + Cvar_RBM += "RBM"; + std::string MakeInvisible = "Reset"; + MakeInvisible += "##"; + MakeInvisible += cvarName; + MakeInvisible += "Reset"; + if (ImGui::Button(MakeInvisible.c_str())) { + colors->x = defaultcolors.x; + colors->y = defaultcolors.y; + colors->z = defaultcolors.z; + if (has_alpha) { colors->w = defaultcolors.w; }; + + Color_RGBA8 colorsRGBA; + colorsRGBA.r = defaultcolors.x; + colorsRGBA.g = defaultcolors.y; + colorsRGBA.b = defaultcolors.z; + if (has_alpha) { colorsRGBA.a = defaultcolors.w; }; + + CVar_SetRGBA(cvarName, colorsRGBA); + CVar_SetS32(Cvar_RBM.c_str(), 0); //On click disable rainbow mode. + SohImGui::RequestCvarSaveOnNextTick(); + } + Tooltip("Revert colors to the game's original colors (GameCube version)\nOverwrites previously chosen color"); + } + + void RandomizeColor(const char* cvarName, ImVec4* colors) { + Color_RGBA8 NewColors = {0,0,0,255}; + std::string Cvar_RBM = cvarName; + Cvar_RBM += "RBM"; + std::string MakeInvisible = "##"; + MakeInvisible += cvarName; + MakeInvisible += "Random"; + std::string FullName = "Random"; + FullName += MakeInvisible; + if (ImGui::Button(FullName.c_str())) { + s16 RND_R = rand() % (255 - 0); + s16 RND_G = rand() % (255 - 0); + s16 RND_B = rand() % (255 - 0); + colors->x = (float)RND_R / 255; + colors->y = (float)RND_G / 255; + colors->z = (float)RND_B / 255; + NewColors.r = fmin(fmax(colors->x, 0), 255); + NewColors.g = fmin(fmax(colors->y, 0), 255); + NewColors.b = fmin(fmax(colors->z, 0), 255); + CVar_SetRGBA(cvarName, NewColors); + CVar_SetS32(Cvar_RBM.c_str(), 0); // On click disable rainbow mode. + SohImGui::RequestCvarSaveOnNextTick(); + } + Tooltip("Chooses a random color\nOverwrites previously chosen color"); + } + + void RainbowColor(const char* cvarName, ImVec4* colors) { + std::string Cvar_RBM = cvarName; + Cvar_RBM += "RBM"; + std::string MakeInvisible = "Rainbow"; + MakeInvisible += "##"; + MakeInvisible += cvarName; + MakeInvisible += "Rainbow"; + + EnhancementCheckbox(MakeInvisible.c_str(), Cvar_RBM.c_str()); + Tooltip("Cycles through colors on a timer\nOverwrites previously chosen color"); + } + + void EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow, bool has_alpha, bool TitleSameLine) { + LoadPickersColors(ColorRGBA, cvarName, default_colors, has_alpha); + + ImGuiColorEditFlags flags = ImGuiColorEditFlags_None; + + if (!TitleSameLine) { + ImGui::Text("%s", text); + flags = ImGuiColorEditFlags_NoLabel; + } + + ImGui::PushID(cvarName); + + if (!has_alpha) { + if (ImGui::ColorEdit3(text, (float*)&ColorRGBA, flags)) + { + Color_RGBA8 colors; + colors.r = ColorRGBA.x * 255.0; + colors.g = ColorRGBA.y * 255.0; + colors.b = ColorRGBA.z * 255.0; + colors.a = ColorRGBA.w * 255.0; + + CVar_SetRGBA(cvarName, colors); + SohImGui::RequestCvarSaveOnNextTick(); + } + } + else + { + if (ImGui::ColorEdit4(text, (float*)&ColorRGBA, flags)) + { + Color_RGBA8 colors; + colors.r = ColorRGBA.x / 255; + colors.g = ColorRGBA.y / 255; + colors.b = ColorRGBA.z / 255; + colors.a = ColorRGBA.w / 255; + + CVar_SetRGBA(cvarName, colors); + SohImGui::RequestCvarSaveOnNextTick(); + } + } + + ImGui::PopID(); + + //ImGui::SameLine(); // Removing that one to gain some width spacing on the HUD editor + ImGui::PushItemWidth(-FLT_MIN); + ResetColor(cvarName, &ColorRGBA, default_colors, has_alpha); + ImGui::SameLine(); + RandomizeColor(cvarName, &ColorRGBA); + if (allow_rainbow) { + if (ImGui::GetContentRegionAvail().x > 185) { + ImGui::SameLine(); + } + RainbowColor(cvarName, &ColorRGBA); + } + ImGui::NewLine(); + ImGui::PopItemWidth(); + } +} diff --git a/soh/soh/UIWidgets.hpp b/soh/soh/UIWidgets.hpp new file mode 100644 index 000000000..6ea62a9fa --- /dev/null +++ b/soh/soh/UIWidgets.hpp @@ -0,0 +1,49 @@ +// +// UIWidgets.hpp +// soh +// +// Created by David Chavez on 25.08.22. +// + +#ifndef UIWidgets_hpp +#define UIWidgets_hpp + +#include +#include +#include +#include + +namespace UIWidgets { + + // MARK: - Enums + + enum class CheckboxGraphics { + Cross, + Checkmark, + None + }; + + char* WrappedText(const char* text, unsigned int charactersPerLine = 60); + char* WrappedText(const std::string& text, unsigned int charactersPerLine); + + void SetLastItemHoverText(const std::string& text); + void InsertHelpHoverText(const std::string& text); + + void Tooltip(const char* text); + void Spacer(float height); + + void PaddedSeparator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f, float extraVerticalBottomPadding = 0.0f); + void EnhancementCheckbox(const char* text, const char* cvarName, bool disabled = false, const char* disabledTooltipText = "", CheckboxGraphics disabledGraphic = CheckboxGraphics::Cross); + void PaddedEnhancementCheckbox(const char* text, const char* cvarName, bool padTop = true, bool padBottom = true, bool disabled = false, const char* disabledTooltipText = "", CheckboxGraphics disabledGraphic = CheckboxGraphics::Cross); + void EnhancementCombo(const std::string& name, const char* cvarName, const std::vector& items, int defaultValue = 0); + void EnhancementCombobox(const char* name, const char* ComboArray[], size_t arraySize, uint8_t FirstTimeValue); + void PaddedText(const char* text, bool padTop = true, bool padBottom = true); + void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = false); + void PaddedEnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = false, bool padTop = true, bool padBottom = true); + void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton = false); + void EnhancementRadioButton(const char* text, const char* cvarName, int id); + + void EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow = true, bool has_alpha=false, bool TitleSameLine=false); +} + +#endif /* UIWidgets_hpp */ diff --git a/soh/soh/frame_interpolation.cpp b/soh/soh/frame_interpolation.cpp index 44c255db1..79ac23d43 100644 --- a/soh/soh/frame_interpolation.cpp +++ b/soh/soh/frame_interpolation.cpp @@ -1,4 +1,4 @@ -#include "Cvar.h" +#include #include #include diff --git a/soh/soh/z_message_OTR.cpp b/soh/soh/z_message_OTR.cpp index c6be43964..1c5e82b43 100644 --- a/soh/soh/z_message_OTR.cpp +++ b/soh/soh/z_message_OTR.cpp @@ -1,13 +1,13 @@ #include "OTRGlobals.h" -#include "ResourceMgr.h" -#include "Scene.h" -#include "Utils/StringHelper.h" +#include +#include +#include #include "global.h" #include "vt.h" -#include +#include #include -#include -#include +#include "Enhancements/custom-message/CustomMessageManager.h" +#include "Enhancements/custom-message/CustomMessageTypes.h" extern "C" MessageTableEntry* sNesMessageEntryTablePtr; extern "C" MessageTableEntry* sGerMessageEntryTablePtr; diff --git a/soh/soh/z_play_otr.cpp b/soh/soh/z_play_otr.cpp index 1a07ceb7e..52b71c905 100644 --- a/soh/soh/z_play_otr.cpp +++ b/soh/soh/z_play_otr.cpp @@ -1,10 +1,10 @@ -#include "OTRGlobals.h" -#include "ResourceMgr.h" -#include "Scene.h" -#include "Utils/StringHelper.h" +#include "OTRGlobals.h" +#include +#include +#include #include "global.h" #include "vt.h" -#include "Vertex.h" +#include extern "C" void Gameplay_InitScene(GlobalContext * globalCtx, s32 spawn); extern "C" void Gameplay_InitEnvironment(GlobalContext * globalCtx, s16 skyboxId); @@ -76,4 +76,4 @@ void OTRGameplay_InitScene(GlobalContext* globalCtx, s32 spawn) { auto data2 = ResourceMgr_LoadVtxByCRC(0x68d4ea06044e228f);*/ volatile int a = 0; -} \ No newline at end of file +} diff --git a/soh/soh/z_scene_otr.cpp b/soh/soh/z_scene_otr.cpp index 73953c681..97c0b8040 100644 --- a/soh/soh/z_scene_otr.cpp +++ b/soh/soh/z_scene_otr.cpp @@ -1,15 +1,15 @@ -#include "OTRGlobals.h" -#include "ResourceMgr.h" -#include "Scene.h" -#include "Utils/StringHelper.h" +#include "OTRGlobals.h" +#include +#include +#include #include "global.h" #include "vt.h" -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include extern Ship::Resource* OTRGameplay_LoadFile(GlobalContext* globalCtx, const char* fileName); extern "C" s32 Object_Spawn(ObjectContext* objectCtx, s16 objectId); diff --git a/soh/src/code/audio_playback.c b/soh/src/code/audio_playback.c index b2017b514..2c7ff425d 100644 --- a/soh/src/code/audio_playback.c +++ b/soh/src/code/audio_playback.c @@ -1,5 +1,5 @@ #include "global.h" -#include "Cvar.h" +#include extern bool gUseLegacySD; diff --git a/soh/src/code/audio_synthesis.c b/soh/src/code/audio_synthesis.c index 67f7033ea..72dbb25ec 100644 --- a/soh/src/code/audio_synthesis.c +++ b/soh/src/code/audio_synthesis.c @@ -1,6 +1,6 @@ #include "ultra64.h" #include "global.h" -#include "mixer.h" +#include #define DEFAULT_LEN_1CH 0x1A0 #define DEFAULT_LEN_2CH 0x340 diff --git a/soh/src/code/code_800F9280.c b/soh/src/code/code_800F9280.c index 6ca2ad75d..5fa3d50fa 100644 --- a/soh/src/code/code_800F9280.c +++ b/soh/src/code/code_800F9280.c @@ -1,7 +1,7 @@ #include "ultra64.h" #include "global.h" -#include "ultra64/abi.h" -#include "mixer.h" +#include +#include typedef struct { u8 unk_0; diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 6b311fd4c..f831bc830 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -4,7 +4,7 @@ #include #include "soh/Enhancements/gameconsole.h" -#include "../libultraship/ImGuiImpl.h" +#include #include "soh/frame_interpolation.h" #include diff --git a/soh/src/overlays/gamestates/ovl_title/z_title.c b/soh/src/overlays/gamestates/ovl_title/z_title.c index 73da17185..de83f8c2a 100644 --- a/soh/src/overlays/gamestates/ovl_title/z_title.c +++ b/soh/src/overlays/gamestates/ovl_title/z_title.c @@ -10,7 +10,7 @@ #include "alloca.h" #include "textures/nintendo_rogo_static/nintendo_rogo_static.h" #include -#include "GameVersions.h" +#include #include const char* GetGameVersionString(); From fba8fc2b74607e85567b383361f19f7c79a89396 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Sat, 3 Sep 2022 00:20:07 -0400 Subject: [PATCH 07/20] Fix Ganons Trials coming from old save files. Fixes #1365 --- soh/soh/Enhancements/randomizer/randomizer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index b8442e241..cb0ef6e5b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1136,6 +1136,8 @@ void Randomizer::ParseRequiredTrialsFile(const char* spoilerFileName) { return; } + this->trialsRequired.clear(); + try { json spoilerFileJson; spoilerFileStream >> spoilerFileJson; From a07ea091f00adbb817f6f373d1e7204a32924c93 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Sat, 3 Sep 2022 00:20:50 -0400 Subject: [PATCH 08/20] Fixes crash when entering Ganon's Castle lobby on linux. --- soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c b/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c index 6d0b51db2..b2dc185d7 100644 --- a/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c +++ b/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c @@ -88,7 +88,7 @@ s32 DemoKekkai_CheckEventFlag(s32 params) { if ((params < KEKKAI_TOWER) || (params > KEKKAI_FOREST)) { return true; } - if (gSaveContext.n64ddFlag) { + if (gSaveContext.n64ddFlag && params > KEKKAI_TOWER) { return Flags_GetRandomizerInf(trialParamToRandInf(params)); } return Flags_GetEventChkInf(eventFlags[params]); From 8118947ab059b4ffec91ed87620f777e1b0ef09e Mon Sep 17 00:00:00 2001 From: louist103 <35883445+louist103@users.noreply.github.com> Date: Sat, 3 Sep 2022 01:15:43 -0400 Subject: [PATCH 09/20] Windows crash handler. (#1383) * Windows crash handler. * Fix naming convention. --- libultraship/libultraship/CrashHandler.cpp | 437 +++++++++++++++------ libultraship/libultraship/CrashHandler.h | 23 +- soh/src/code/main.c | 2 + 3 files changed, 333 insertions(+), 129 deletions(-) diff --git a/libultraship/libultraship/CrashHandler.cpp b/libultraship/libultraship/CrashHandler.cpp index f8d66beab..f454ddfdc 100644 --- a/libultraship/libultraship/CrashHandler.cpp +++ b/libultraship/libultraship/CrashHandler.cpp @@ -1,6 +1,9 @@ #include "spdlog/spdlog.h" #include "Utils/StringHelper.h" #include "CrashHandler.h" +#include "Window.h" + +extern "C" void DeinitOTR(void); #if defined(__linux__) #include @@ -10,163 +13,343 @@ #include #include -extern "C" void DeinitOTR(void); static void PrintRegisters(ucontext_t* ctx) { - char regbuffer[1024]; - SPDLOG_CRITICAL("Registers:"); + char regbuffer[1024]; + SPDLOG_CRITICAL("Registers:"); #if defined(__x86_64__) - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RAX]); - SPDLOG_CRITICAL("RAX: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RDI]); - SPDLOG_CRITICAL("RDI: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RSI]); - SPDLOG_CRITICAL("RSI: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RDX]); - SPDLOG_CRITICAL("RDX: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RCX]); - SPDLOG_CRITICAL("RCX: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R8]); - SPDLOG_CRITICAL("R8 : {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R9]); - SPDLOG_CRITICAL("R9 : {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R10]); - SPDLOG_CRITICAL("R10: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R11]); - SPDLOG_CRITICAL("R11: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RSP]); - SPDLOG_CRITICAL("RSP: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RBX]); - SPDLOG_CRITICAL("RBX: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RBP]); - SPDLOG_CRITICAL("RBP: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R12]); - SPDLOG_CRITICAL("R12: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R13]); - SPDLOG_CRITICAL("R13: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R14]); - SPDLOG_CRITICAL("R14: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R15]); - SPDLOG_CRITICAL("R15: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RIP]); - SPDLOG_CRITICAL("RIP: {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_EFL]); - SPDLOG_CRITICAL("EFLAGS: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RAX]); + SPDLOG_CRITICAL("RAX: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RDI]); + SPDLOG_CRITICAL("RDI: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RSI]); + SPDLOG_CRITICAL("RSI: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RDX]); + SPDLOG_CRITICAL("RDX: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RCX]); + SPDLOG_CRITICAL("RCX: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R8]); + SPDLOG_CRITICAL("R8 : {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R9]); + SPDLOG_CRITICAL("R9 : {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R10]); + SPDLOG_CRITICAL("R10: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R11]); + SPDLOG_CRITICAL("R11: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RSP]); + SPDLOG_CRITICAL("RSP: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RBX]); + SPDLOG_CRITICAL("RBX: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RBP]); + SPDLOG_CRITICAL("RBP: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R12]); + SPDLOG_CRITICAL("R12: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R13]); + SPDLOG_CRITICAL("R13: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R14]); + SPDLOG_CRITICAL("R14: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_R15]); + SPDLOG_CRITICAL("R15: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_RIP]); + SPDLOG_CRITICAL("RIP: {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer), "0x%016llX", ctx->uc_mcontext.gregs[REG_EFL]); + SPDLOG_CRITICAL("EFLAGS: {} ", regbuffer); #else - snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EDI]); - SPDLOG_CRITICAL("EDI : {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_ESI]); - SPDLOG_CRITICAL("ESI : {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EBP]); - SPDLOG_CRITICAL("EBP : {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_ESP]); - SPDLOG_CRITICAL("ESP : {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EBX]); - SPDLOG_CRITICAL("EBX : {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EDX]); - SPDLOG_CRITICAL("EDX : {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_ECX]); - SPDLOG_CRITICAL("ECX : {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EAX]); - SPDLOG_CRITICAL("EAX : {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EIP]); - SPDLOG_CRITICAL("EIP : {} ", regbuffer); - snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EFL]); - SPDLOG_CRITICAL("EFL : {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EDI]); + SPDLOG_CRITICAL("EDI : {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_ESI]); + SPDLOG_CRITICAL("ESI : {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EBP]); + SPDLOG_CRITICAL("EBP : {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_ESP]); + SPDLOG_CRITICAL("ESP : {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EBX]); + SPDLOG_CRITICAL("EBX : {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EDX]); + SPDLOG_CRITICAL("EDX : {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_ECX]); + SPDLOG_CRITICAL("ECX : {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EAX]); + SPDLOG_CRITICAL("EAX : {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EIP]); + SPDLOG_CRITICAL("EIP : {} ", regbuffer); + snprintf(regbuffer, std::size(regbuffer),"0x%08lX", ctx->uc_mcontext.gregs[REG_EFL]); + SPDLOG_CRITICAL("EFL : {} ", regbuffer); #endif } -static void ErrorHandler(int sig, siginfo_t* sigInfo, void* data) -{ - std::array arr; - ucontext_t* ctx = static_cast(data); - constexpr size_t nMaxFrames = arr.size(); - size_t size = backtrace(arr.data(), nMaxFrames); - char** symbols = backtrace_symbols(arr.data(), nMaxFrames); +static void ErrorHandler(int sig, siginfo_t* sigInfo, void* data) { + std::array arr; + ucontext_t* ctx = static_cast(data); + constexpr size_t nMaxFrames = arr.size(); + size_t size = backtrace(arr.data(), nMaxFrames); + char** symbols = backtrace_symbols(arr.data(), nMaxFrames); - SPDLOG_CRITICAL("(Signal: {})\n", sig); + SPDLOG_CRITICAL("(Signal: {})", sig); - switch (sig) { - case SIGILL: - SPDLOG_CRITICAL("ILLEGAL INSTRUCTION"); - break; - case SIGABRT: - SPDLOG_CRITICAL("ABORT"); - break; - case SIGFPE: - SPDLOG_CRITICAL("ERRONEUS ARITHEMETIC OPERATION"); - break; - case SIGSEGV: - SPDLOG_CRITICAL("INVALID ACCESS TO STORAGE"); - break; - } + switch (sig) { + case SIGILL: + SPDLOG_CRITICAL("ILLEGAL INSTRUCTION"); + break; + case SIGABRT: + SPDLOG_CRITICAL("ABORT"); + break; + case SIGFPE: + SPDLOG_CRITICAL("ERRONEUS ARITHEMETIC OPERATION"); + break; + case SIGSEGV: + SPDLOG_CRITICAL("INVALID ACCESS TO STORAGE"); + break; + } - PrintRegisters(ctx); + PrintRegisters(ctx); - SPDLOG_CRITICAL("Traceback:\n"); - for (size_t i = 1; i < size; i++) - { - Dl_info info; - int gotAddress = dladdr(arr[i], &info); - std::string functionName(symbols[i]); + SPDLOG_CRITICAL("Traceback:"); + for (size_t i = 1; i < size; i++) { + Dl_info info; + int gotAddress = dladdr(arr[i], &info); + std::string functionName(symbols[i]); - if (gotAddress != 0 && info.dli_sname != nullptr) - { + if (gotAddress != 0 && info.dli_sname != nullptr) { FILE* pipe; - int32_t status; - char* demangled = abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, &status); - const char* nameFound = info.dli_sname; + int32_t status; + char* demangled = abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, &status); + const char* nameFound = info.dli_sname; - if (status == 0) - { - nameFound = demangled; - } + if (status == 0) { + nameFound = demangled; + } #if 0 - char command[256]; + char command[256]; char addrLine[128]; snprintf(command, sizeof(command), "addr2line -e soh.elf %s + 0x%lX", nameFound, (uintptr_t)arr[i] - (uintptr_t)info.dli_saddr); - pipe = popen(command, "r"); + pipe = popen(command, "r"); fgets(addrLine, 128, pipe); - #endif - + #endif + functionName = StringHelper::Sprintf("%s (+0x%X)", nameFound, - (char*)arr[i] - (char*)info.dli_saddr); - free(demangled); - } + (char*)arr[i] - (char*)info.dli_saddr); + free(demangled); + } - SPDLOG_CRITICAL("{} {}", i, functionName.c_str()); - } + SPDLOG_CRITICAL("{} {}", i, functionName.c_str()); + } - free(symbols); - DeinitOTR(); - exit(1); + free(symbols); + DeinitOTR(); + exit(1); } static void ShutdownHandler(int sig, siginfo_t* sigInfo, void* data) { - DeinitOTR(); - exit(1); + DeinitOTR(); + exit(1); } extern "C" void SetupHandlerLinux() { - struct sigaction action; - struct sigaction shutdownAction; + struct sigaction action; + struct sigaction shutdownAction; - action.sa_flags = SA_SIGINFO; - action.sa_sigaction = ErrorHandler; - - sigaction(SIGILL, &action, nullptr); - sigaction(SIGABRT, &action, nullptr); - sigaction(SIGFPE, &action, nullptr); - sigaction(SIGSEGV, &action, nullptr); - - shutdownAction.sa_flags = SA_SIGINFO; - shutdownAction.sa_sigaction = ShutdownHandler; - sigaction(SIGINT, &shutdownAction, nullptr); - sigaction(SIGTERM, &shutdownAction, nullptr); - sigaction(SIGQUIT, &shutdownAction, nullptr); - sigaction(SIGKILL, &shutdownAction, nullptr); + action.sa_flags = SA_SIGINFO; + action.sa_sigaction = ErrorHandler; + sigaction(SIGILL, &action, nullptr); + sigaction(SIGABRT, &action, nullptr); + sigaction(SIGFPE, &action, nullptr); + sigaction(SIGSEGV, &action, nullptr); + shutdownAction.sa_flags = SA_SIGINFO; + shutdownAction.sa_sigaction = ShutdownHandler; + sigaction(SIGINT, &shutdownAction, nullptr); + sigaction(SIGTERM, &shutdownAction, nullptr); + sigaction(SIGQUIT, &shutdownAction, nullptr); + sigaction(SIGKILL, &shutdownAction, nullptr); } +#elif _WIN32 + +#if defined(_WIN32) && !defined(_WIN64) +#define WINDOWS_32_BIT +#endif + +static void PrintRegisters(CONTEXT* ctx) { + SPDLOG_CRITICAL("Register dump"); + char regBuff[50]; +#if defined(_M_AMD64) + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->Rax); + SPDLOG_CRITICAL("RAX: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->Rcx); + SPDLOG_CRITICAL("RCX: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->Rdx); + SPDLOG_CRITICAL("RDX: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->Rbx); + SPDLOG_CRITICAL("RBX: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->Rsp); + SPDLOG_CRITICAL("RSP: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->Rbp); + SPDLOG_CRITICAL("RBP: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->Rsi); + SPDLOG_CRITICAL("RSI: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->Rdi); + SPDLOG_CRITICAL("RDI: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->R9); + SPDLOG_CRITICAL("R9: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->R10); + SPDLOG_CRITICAL("R10: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->R11); + SPDLOG_CRITICAL("R11: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->R12); + SPDLOG_CRITICAL("R12: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->R13); + SPDLOG_CRITICAL("R13: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->R14); + SPDLOG_CRITICAL("R14: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->R15); + SPDLOG_CRITICAL("R15: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%016llX", ctx->Rip); + SPDLOG_CRITICAL("RIP: {}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%08lX", ctx->EFlags); + SPDLOG_CRITICAL("EFLAGS: {}", regBuff); +#elif WINDOWS_32_BIT + snprintf(regBuff, std::size(regBuff), "0x%08lX", ctx->Edi); + SPDLOG_CRITICAL("EDI: 0x{}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%08lX", ctx->Esi); + SPDLOG_CRITICAL("ESI: 0x{}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%08lX", ctx->Ebx); + SPDLOG_CRITICAL("EBX: 0x{}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%08lX", ctx->Ecx); + SPDLOG_CRITICAL("ECX: 0x{}", ctx->Ecx); + + snprintf(regBuff, std::size(regBuff), "0x%08lX", ctx->Eax); + SPDLOG_CRITICAL("EAX: 0x{}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%08lX", ctx->Ebp); + SPDLOG_CRITICAL("EBP: 0x{}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%08lX", ctx->Esp); + SPDLOG_CRITICAL("ESP: 0x{}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%08lX", ctx->EFlags); + SPDLOG_CRITICAL("EFLAGS: 0x{}", regBuff); + + snprintf(regBuff, std::size(regBuff), "0x%08lX", ctx->Eip); + SPDLOG_CRITICAL("EIP: 0x{}", regBuff); +#endif +} + +static void printStack(CONTEXT* ctx) { + BOOL result; + HANDLE process; + HANDLE thread; + HMODULE hModule; + ULONG frame; + DWORD64 displacement; + DWORD disp; + +#if defined(_M_AMD64) + STACKFRAME64 stack; + memset(&stack, 0, sizeof(STACKFRAME64)); +#elif WINDOWS_32_BIT + STACKFRAME stack; + memset(&stack, 0, sizeof(STACKFRAME)); + stack.AddrPC.Offset = (*ctx).Eip; + stack.AddrPC.Mode = AddrModeFlat; + stack.AddrStack.Offset = (*ctx).Esp; + stack.AddrStack.Mode = AddrModeFlat; + stack.AddrFrame.Offset = (*ctx).Ebp; + stack.AddrFrame.Mode = AddrModeFlat; +#endif + + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME + sizeof(TCHAR)]; + char module[512]; + + PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; + + CONTEXT ctx2; + memcpy(&ctx2, ctx, sizeof(CONTEXT)); + + PrintRegisters(&ctx2); + + process = GetCurrentProcess(); + thread = GetCurrentThread(); + SymInitialize(process, nullptr, true); + + + constexpr DWORD machineType = +#if defined(_M_AMD64) + IMAGE_FILE_MACHINE_AMD64; +#elif WINDOWS_32_BIT + IMAGE_FILE_MACHINE_I386; +#endif + + displacement = 0; + for (frame = 0;; frame++) { + result = StackWalk(machineType, process, thread, &stack, &ctx2, nullptr, SymFunctionTableAccess, + SymGetModuleBase, nullptr); + if (!result) { + break; + } + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + symbol->MaxNameLen = MAX_SYM_NAME; + SymFromAddr(process, (ULONG64)stack.AddrPC.Offset, &displacement, symbol); +#if defined(_M_AMD64) + IMAGEHLP_LINE64 line; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); +#elif WINDOWS_32_BIT + IMAGEHLP_LINE line; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE); +#endif + if (SymGetLineFromAddr(process, stack.AddrPC.Offset, &disp, &line)) { + SPDLOG_CRITICAL("{} in {}: line: {}: ", symbol->Name, line.FileName, line.LineNumber); + } + else { + char addrString[25]; + snprintf(addrString, std::size(addrString), "0x%016llX", symbol->Address); + SPDLOG_CRITICAL("at {}, addr 0x{}", symbol->Name, addrString); + hModule = nullptr; + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCTSTR)(stack.AddrPC.Offset), &hModule); + + if (hModule != nullptr) { + GetModuleFileNameA(hModule, module, sizeof(module)); + } + SPDLOG_CRITICAL("In {}", module); + } + } + Ship::Window::GetInstance()->GetLogger()->flush(); + spdlog::shutdown(); + DeinitOTR(); +} + +extern "C" LONG seh_filter(struct _EXCEPTION_POINTERS* ex) { + char exceptionString[20]; + + snprintf(exceptionString, std::size(exceptionString), "0x%x", ex->ExceptionRecord->ExceptionCode); + + SPDLOG_CRITICAL("EXCEPTION {} occurred", exceptionString); + printStack(ex->ContextRecord); + MessageBox(nullptr, L"SoH Has crashed. Please upload the logs to the support channel in discord.", L"Crash", MB_OK | MB_ICONERROR); + + return EXCEPTION_EXECUTE_HANDLER; +} + + #endif diff --git a/libultraship/libultraship/CrashHandler.h b/libultraship/libultraship/CrashHandler.h index e068a4e38..103034ea4 100644 --- a/libultraship/libultraship/CrashHandler.h +++ b/libultraship/libultraship/CrashHandler.h @@ -13,6 +13,25 @@ void SetupHandlerLinux(void); } #endif -#endif // __linux__ +#elif _WIN32 // __linux__ ^^^^ _WIN32 vvvvv +#include +#include -#endif // CRASH_HANDLER_H \ No newline at end of file +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +LONG seh_filter(struct _EXCEPTION_POINTERS* ex); + +#ifdef __cplusplus +} +#endif + +#pragma comment(lib, "Dbghelp.lib") +#endif + +#endif // CRASH_HANDLER_H diff --git a/soh/src/code/main.c b/soh/src/code/main.c index 8e9fe1776..07e54b5be 100644 --- a/soh/src/code/main.c +++ b/soh/src/code/main.c @@ -42,6 +42,8 @@ int main(int argc, char** argv) { #ifdef __linux__ SetupHandlerLinux(); +#elif _WIN32 + SetUnhandledExceptionFilter(seh_filter); #endif GameConsole_Init(); From a5804ca2b23508ecaf270d4b8b1548fe776a7685 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Sat, 3 Sep 2022 01:21:56 -0400 Subject: [PATCH 10/20] Makes `Item_Give` safe to use with a NULL globalCtx. This should allow it's use for giving items to Link's Pocket during rando save initialization. --- soh/src/code/z_parameter.c | 78 +++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 18 deletions(-) diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index ac751cca3..4d4807442 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1575,6 +1575,17 @@ void func_80084BF4(GlobalContext* globalCtx, u16 flag) { } } +/** + * @brief Adds the given item to Link's inventory. + * + * NOTE: This function has been edited to be safe to use with a NULL globalCtx. + * If you need to add to this function, be sure you check if the globalCtx is not + * NULL before doing any operations requiring it. + * + * @param globalCtx + * @param item + * @return u8 + */ u8 Item_Give(GlobalContext* globalCtx, u8 item) { static s16 sAmmoRefillCounts[] = { 5, 10, 20, 30, 5, 10, 30, 0, 5, 20, 1, 5, 20, 50, 200, 10 }; s16 i; @@ -1654,7 +1665,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { if (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KNIFE) { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; - Interface_LoadItemIcon1(globalCtx, 0); + if (globalCtx != NULL) { + Interface_LoadItemIcon1(globalCtx, 0); + } } } @@ -1662,7 +1675,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; gSaveContext.equips.equipment &= 0xFFF0; gSaveContext.equips.equipment |= 0x0002; - Interface_LoadItemIcon1(globalCtx, 0); + if (globalCtx != NULL) { + Interface_LoadItemIcon1(globalCtx, 0); + } } return ITEM_NONE; @@ -1677,7 +1692,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { return ITEM_NONE; } else if ((item == ITEM_KEY_BOSS) || (item == ITEM_COMPASS) || (item == ITEM_DUNGEON_MAP)) { // Boss Key, Compass, and Dungeon Map exceptions for rando. - if (gSaveContext.n64ddFlag) { + // Rando should never be able to get here for Link's Pocket unless something goes wrong, + // but we check for a globalCtx here so the game won't crash if we do somehow get here. + if (gSaveContext.n64ddFlag && globalCtx != NULL) { if (globalCtx->sceneNum == 13) { // ganon's castle -> ganon's tower gSaveContext.inventory.dungeonItems[10] |= 1; } else if (globalCtx->sceneNum == 92) { // Desert Colossus -> Spirit Temple. @@ -1691,7 +1708,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { return ITEM_NONE; } else if (item == ITEM_KEY_SMALL) { // Small key exceptions for rando with keysanity off. - if (gSaveContext.n64ddFlag) { + // Rando should never be able to get here for Link's Pocket unless something goes wrong, + // but we check for a globalCtx here so the game won't crash if we do somehow get here. + if (gSaveContext.n64ddFlag && globalCtx != NULL) { if (globalCtx->sceneNum == 10) { // ganon's tower -> ganon's castle if (gSaveContext.inventory.dungeonKeys[13] < 0) { gSaveContext.inventory.dungeonKeys[13] = 1; @@ -1828,7 +1847,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) { if (gSaveContext.equips.buttonItems[i] == ITEM_HOOKSHOT) { gSaveContext.equips.buttonItems[i] = ITEM_LONGSHOT; - Interface_LoadItemIcon1(globalCtx, i); + if (globalCtx != NULL) { + Interface_LoadItemIcon1(globalCtx, i); + } } } // update the adult/child equips when rando'd (accounting for equp swapped hookshot as child) @@ -1836,7 +1857,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { for (i = 1; i < ARRAY_COUNT(gSaveContext.adultEquips.buttonItems); i++) { if (gSaveContext.adultEquips.buttonItems[i] == ITEM_HOOKSHOT) { gSaveContext.adultEquips.buttonItems[i] = ITEM_LONGSHOT; - Interface_LoadItemIcon1(globalCtx, i); + if (globalCtx != NULL) { + Interface_LoadItemIcon1(globalCtx, i); + } } } } @@ -1844,7 +1867,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { for (i = 1; i < ARRAY_COUNT(gSaveContext.childEquips.buttonItems); i++) { if (gSaveContext.childEquips.buttonItems[i] == ITEM_HOOKSHOT) { gSaveContext.childEquips.buttonItems[i] = ITEM_LONGSHOT; - Interface_LoadItemIcon1(globalCtx, i); + if (globalCtx != NULL) { + Interface_LoadItemIcon1(globalCtx, i); + } } } } @@ -1989,7 +2014,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { for (i = 1; i < ARRAY_COUNT(gSaveContext.adultEquips.buttonItems); i++) { if (gSaveContext.adultEquips.buttonItems[i] == ITEM_OCARINA_FAIRY) { gSaveContext.adultEquips.buttonItems[i] = ITEM_OCARINA_TIME; - Interface_LoadItemIcon1(globalCtx, i); + if (globalCtx != NULL) { + Interface_LoadItemIcon1(globalCtx, i); + } } } } @@ -1997,7 +2024,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { for (i = 1; i < ARRAY_COUNT(gSaveContext.childEquips.buttonItems); i++) { if (gSaveContext.childEquips.buttonItems[i] == ITEM_OCARINA_FAIRY) { gSaveContext.childEquips.buttonItems[i] = ITEM_OCARINA_TIME; - Interface_LoadItemIcon1(globalCtx, i); + if (globalCtx != NULL) { + Interface_LoadItemIcon1(globalCtx, i); + } } } } @@ -2021,14 +2050,20 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { return ITEM_NONE; } else if (item == ITEM_HEART) { osSyncPrintf("回復ハート回復ハート回復ハート\n"); // "Recovery Heart" - Health_ChangeBy(globalCtx, 0x10); + if (globalCtx != NULL) { + Health_ChangeBy(globalCtx, 0x10); + } return item; } else if (item == ITEM_MAGIC_SMALL) { if (gSaveContext.unk_13F0 != 10) { - Magic_Fill(globalCtx); + if (globalCtx != NULL) { + Magic_Fill(globalCtx); + } } - func_80087708(globalCtx, 12, 5); + if (globalCtx != NULL) { + func_80087708(globalCtx, 12, 5); + } if (!(gSaveContext.infTable[25] & 0x100)) { gSaveContext.infTable[25] |= 0x100; @@ -2038,10 +2073,13 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { return item; } else if (item == ITEM_MAGIC_LARGE) { if (gSaveContext.unk_13F0 != 10) { - Magic_Fill(globalCtx); + if (globalCtx != NULL) { + Magic_Fill(globalCtx); + } + } + if (globalCtx != NULL) { + func_80087708(globalCtx, 24, 5); } - - func_80087708(globalCtx, 24, 5); if (!(gSaveContext.infTable[25] & 0x100)) { gSaveContext.infTable[25] |= 0x100; @@ -2080,7 +2118,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { for (int buttonIndex = 1; buttonIndex < ARRAY_COUNT(gSaveContext.equips.buttonItems); buttonIndex++) { if ((temp + i) == gSaveContext.equips.cButtonSlots[buttonIndex - 1]) { gSaveContext.equips.buttonItems[buttonIndex] = item; - Interface_LoadItemIcon2(globalCtx, buttonIndex); + if (globalCtx != NULL) { + Interface_LoadItemIcon2(globalCtx, buttonIndex); + } gSaveContext.buttonStatus[BUTTON_STATUS_INDEX(buttonIndex)] = BTN_ENABLED; break; } @@ -2115,7 +2155,9 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { if (temp == gSaveContext.equips.buttonItems[i]) { if (item != ITEM_SOLD_OUT) { gSaveContext.equips.buttonItems[i] = item; - Interface_LoadItemIcon1(globalCtx, i); + if (globalCtx != NULL) { + Interface_LoadItemIcon1(globalCtx, i); + } } else { gSaveContext.equips.buttonItems[i] = ITEM_NONE; } @@ -2132,7 +2174,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { INV_CONTENT(item) = item; // Autosave after getting items by default (cvars are not shown in the UI) - if (CVar_GetS32("gAutosave", 0)) { + if (CVar_GetS32("gAutosave", 0) && globalCtx != NULL) { if (CVar_GetS32("gAutosaveAllItems", 1)) { Gameplay_PerformSave(globalCtx); } From edb5261b07c3b22af2591ced7fbc1783f4312d3a Mon Sep 17 00:00:00 2001 From: Ada <60364512+GreatArgorath@users.noreply.github.com> Date: Wed, 17 Aug 2022 13:20:15 +0100 Subject: [PATCH 11/20] Fixes ToT Fog --- libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp index cca872f99..23b72a944 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp @@ -2134,6 +2134,10 @@ static void gfx_run_dl(Gfx* cmd) { switch (opcode) { // RSP commands: + case G_LOAD_UCODE: + rsp.fog_mul = 0; + rsp.fog_offset = 0; + break; case G_MARKER: { cmd++; From b14fb37b814f06fa8b75d8ce9312abf1f501ebfe Mon Sep 17 00:00:00 2001 From: Ada <60364512+GreatArgorath@users.noreply.github.com> Date: Wed, 17 Aug 2022 14:47:43 +0100 Subject: [PATCH 12/20] Update libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp Co-authored-by: David Chavez --- libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp index 23b72a944..9fde7e276 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_pc.cpp @@ -2134,7 +2134,7 @@ static void gfx_run_dl(Gfx* cmd) { switch (opcode) { // RSP commands: - case G_LOAD_UCODE: + case G_LOAD_UCODE: rsp.fog_mul = 0; rsp.fog_offset = 0; break; From d2fa0d648544a2149cf7d6053cafd50c20437724 Mon Sep 17 00:00:00 2001 From: Baoulettes Date: Mon, 22 Aug 2022 04:19:02 +0200 Subject: [PATCH 13/20] Rando: Fix Fast File Select seed loading (#1252) * FixRandoLoading * better methode --- soh/src/overlays/gamestates/ovl_title/z_title.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soh/src/overlays/gamestates/ovl_title/z_title.c b/soh/src/overlays/gamestates/ovl_title/z_title.c index de83f8c2a..7c63ef35c 100644 --- a/soh/src/overlays/gamestates/ovl_title/z_title.c +++ b/soh/src/overlays/gamestates/ovl_title/z_title.c @@ -301,6 +301,9 @@ void Title_Init(GameState* thisx) { saveloading = true; gSaveContext.fileNum = selectedfile; Sram_OpenSave(); + Randomizer_LoadSettings(""); + Randomizer_LoadHintLocations(""); + Randomizer_LoadItemLocations("", true); gSaveContext.gameMode = 0; gSaveContext.magic = gSaveContext.magic; SET_NEXT_GAMESTATE(&this->state, Gameplay_Init, GlobalContext); From 2015e3a041e5f5ae066ea61be43b4bbbea0f83d1 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Sat, 3 Sep 2022 01:48:07 -0400 Subject: [PATCH 14/20] Converts Song from Impa to use `Item_Give` --- soh/src/code/z_sram.c | 68 +------------------------------------------ 1 file changed, 1 insertion(+), 67 deletions(-) diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index c131f172f..6d4b68bc0 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -858,73 +858,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { s32 giid = getItem.getItemId; if (getItem.modIndex == MOD_NONE) { - if (getItem.itemId >= ITEM_MEDALLION_FOREST && getItem.itemId <= ITEM_ZORA_SAPPHIRE) { - GiveLinkDungeonReward(getItem.getItemId); - } else if (getItem.itemId >= ITEM_SONG_MINUET && getItem.itemId <= ITEM_SONG_STORMS) { - GiveLinkSong(getItem.getItemId); - } else if (giid == GI_RUPEE_GREEN || giid == GI_RUPEE_BLUE || giid == GI_RUPEE_RED || - giid == GI_RUPEE_PURPLE || giid == GI_RUPEE_GOLD) { - GiveLinkRupeesByGetItemId(giid); - } else if (giid == GI_BOMBCHUS_10 || giid == GI_BOMBCHUS_5 || giid == GI_BOMBCHUS_20) { - GiveLinkBombchus(giid); - } else if (giid == GI_STICKS_1 || giid == GI_STICKS_5 || giid == GI_STICKS_10) { - GiveLinkDekuSticksByGetItemId(giid); - } else if (giid == GI_NUTS_5 || giid == GI_NUTS_10) { - GiveLinkDekuNutsByGetItemId(giid); - } else if (giid == GI_BEAN) { - GiveLinkBeans(); - } else if (giid == GI_SWORD_KOKIRI) { - GiveLinkKokiriSword(); - } else if (giid == GI_SWORD_BGS) { - GiveLinkBiggoronSword(); - } else if (giid == GI_SWORD_KNIFE) { - GiveLinkGiantsKnife(); - } else if (giid == GI_SHIELD_DEKU) { - GiveLinkDekuShield(); - } else if (giid == GI_SHIELD_HYLIAN) { - GiveLinkHylianShield(); - } else if (giid == GI_SHIELD_MIRROR) { - GiveLinkMirrorShield(); - } else if (giid == GI_TUNIC_GORON) { - GiveLinkGoronTunic(); - } else if (giid == GI_TUNIC_ZORA) { - GiveLinkZoraTunic(); - } else if (giid == GI_BOOTS_IRON) { - GiveLinkIronBoots(); - } else if (giid == GI_BOOTS_HOVER) { - GiveLinkHoverBoots(); - } else if (giid == GI_SLINGSHOT || giid == GI_BULLET_BAG_40 || giid == GI_BULLET_BAG_50) { - GiveLinkBulletBagUpgrade(giid); - } else if (giid == GI_BOW || giid == GI_QUIVER_40 || giid == GI_QUIVER_50) { - GiveLinkQuiverUpgrade(giid); - } else if (giid == GI_BOMB_BAG_20 || giid == GI_BOMB_BAG_30 || giid == GI_BOMB_BAG_40) { - GiveLinkBombBagUpgrade(giid); - } else if (giid == GI_BRACELET || giid == GI_GAUNTLETS_SILVER || giid == GI_GAUNTLETS_GOLD) { - GiveLinkStrengthUpgrade(giid); - } else if (giid == GI_SCALE_SILVER || giid == GI_SCALE_GOLD) { - GiveLinkScaleUpgrade(giid); - } else if (giid == GI_WALLET_ADULT || giid == GI_WALLET_GIANT) { - GiveLinkWalletUpgrade(giid); - } else if (giid == GI_STONE_OF_AGONY) { - GiveLinkStoneOfAgony(); - } else if (giid == GI_GERUDO_CARD) { - GiveLinkGerudoCard(); - } else if (giid == GI_HEART_PIECE) { - GiveLinkPieceOfHeart(); - } else if (giid == GI_HEART_CONTAINER) { - GiveLinkHeartContainer(); - } else if (giid == GI_STICK_UPGRADE_20 || giid == GI_STICK_UPGRADE_30) { - GiveLinkDekuStickUpgrade(giid); - } else if (giid == GI_NUT_UPGRADE_30 || giid == GI_NUT_UPGRADE_40) { - GiveLinkDekuNutUpgrade(giid); - } else if (giid == GI_SKULL_TOKEN) { - GiveLinkSkullToken(); - } else if (giid >= GI_POCKET_EGG && giid <= GI_CLAIM_CHECK || giid == GI_COJIRO) { - GiveLinkAdultTradeItem(giid); - } else { - s32 iid = getItem.itemId; - if (iid != -1) INV_CONTENT(iid) = iid; - } + Item_Give(NULL, getItem.itemId); } else if (getItem.modIndex == MOD_RANDOMIZER) { Randomizer_Item_Give(NULL, getItem); } From 6daf357fd95d4a500b0b47273306d1a29e9b3701 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Sat, 3 Sep 2022 02:13:20 -0400 Subject: [PATCH 15/20] fix include fix build (#1385) Co-authored-by: briaguya --- soh/src/code/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/src/code/main.c b/soh/src/code/main.c index 07e54b5be..7a6d6c6d9 100644 --- a/soh/src/code/main.c +++ b/soh/src/code/main.c @@ -3,7 +3,7 @@ #include #include "soh/OTRGlobals.h" -#include "../libultraship/CrashHandler.h" +#include s32 gScreenWidth = SCREEN_WIDTH; From 36cc9d562c4c15e92801c1a45746f85ec1f629cf Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Sat, 3 Sep 2022 02:34:21 -0400 Subject: [PATCH 16/20] Adds more options for Link's starting item. --- .../randomizer/3drando/settings.cpp | 2 ++ .../Enhancements/randomizer/randomizer.cpp | 24 ++++++++++++++++++- .../Enhancements/randomizer/randomizerTypes.h | 3 ++- soh/src/code/z_sram.c | 14 +++++++---- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index dd9f6d2de..dba8859e9 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -2592,6 +2592,8 @@ namespace Settings { NightGSExpectSuns.SetSelectedIndex(cvarSettings[RSK_SKULLS_SUNS_SONG]); + LinksPocketItem.SetSelectedIndex(cvarSettings[RSK_LINKS_POCKET]); + // RANDOTODO implement chest shuffle with keysanity // ShuffleChestMinigame.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_CHEST_MINIGAME]); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 3f5ae1bb4..fdb705095 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -567,12 +567,13 @@ std::unordered_map SpoilerfileSettingNameToEn { "Open Settings:Token Count", RSK_RAINBOW_BRIDGE_TOKEN_COUNT }, { "Open Settings:Random Ganon's Trials", RSK_RANDOM_TRIALS }, { "Open Settings:Trial Count", RSK_TRIAL_COUNT }, + { "Shuffle Settings:Link's Pocket", RSK_LINKS_POCKET}, { "Shuffle Settings:Shuffle Gerudo Card", RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD }, { "Shuffle Settings:Scrub Shuffle", RSK_SHUFFLE_SCRUBS }, { "Shuffle Settings:Shuffle Cows", RSK_SHUFFLE_COWS }, { "Shuffle Settings:Tokensanity", RSK_SHUFFLE_TOKENS }, { "Shuffle Settings:Shuffle Adult Trade", RSK_SHUFFLE_ADULT_TRADE }, - { "Shuffle Settings:Shuffle Magic Beans", RSK_SHUFFLE_MAGIC_BEANS}, + { "Shuffle Settings:Shuffle Magic Beans", RSK_SHUFFLE_MAGIC_BEANS }, { "Start with Deku Shield", RSK_STARTING_DEKU_SHIELD }, { "Start with Kokiri Sword", RSK_STARTING_KOKIRI_SWORD }, { "Start with Fairy Ocarina", RSK_STARTING_OCARINA }, @@ -969,6 +970,17 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) { gSaveContext.randoSettings[index].value = 3; } break; + case RSK_LINKS_POCKET: + if (it.value() == "Dungeon Reward") { + gSaveContext.randoSettings[index].value = 0; + } else if (it.value() == "Advancement") { + gSaveContext.randoSettings[index].value = 1; + } else if (it.value() == "Anything") { + gSaveContext.randoSettings[index].value = 2; + } else if (it.value() == "Nothing") { + gSaveContext.randoSettings[index].value = 3; + } + break; } index++; } @@ -3457,6 +3469,9 @@ void GenerateRandomizerImgui() { cvarSettings[RSK_ENABLE_GLITCH_CUTSCENES] = CVar_GetS32("gRandomizeEnableGlitchCutscenes", 0); cvarSettings[RSK_SKULLS_SUNS_SONG] = CVar_GetS32("gRandomizeGsExpectSunsSong", 0); + // Link's Pocket has to have a dungeon reward if the other rewards are shuffled to end of dungeon. + cvarSettings[RSK_LINKS_POCKET] = CVar_GetS32("gRandomizeShuffleDungeonReward", 0) != 0 ? + CVar_GetS32("gRandomizeLinksPocket", 0) : 0; // todo: this efficently when we build out cvar array support std::set excludedLocations; @@ -4506,6 +4521,13 @@ void DrawRandoEditor(bool& open) { ImGui::TableNextColumn(); window->DC.CurrLineTextBaseOffset = 0.0f; ImGui::BeginChild("ChildStartingEquipment", ImVec2(0, -8)); + // Don't display this option if Dungeon Rewards are Shuffled to End of Dungeon. + // TODO: Show this but disabled when we have options for disabled Comboboxes. + if (CVar_GetS32("gRandomizeShuffleDungeonReward", 0) != 0) { + ImGui::Text(Settings::LinksPocketItem.GetName().c_str()); + SohImGui::EnhancementCombobox("gRandomizeLinksPocket", randoLinksPocket, 4, 0); + PaddedSeparator(); + } SohImGui::EnhancementCheckbox(Settings::StartingKokiriSword.GetName().c_str(), "gRandomizeStartingKokiriSword"); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index bd7e25a46..064cdc499 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -1018,7 +1018,8 @@ typedef enum { RSK_SKULLS_SUNS_SONG, RSK_SHUFFLE_ADULT_TRADE, RSK_SHUFFLE_MAGIC_BEANS, - RSK_BOMBCHUS_IN_LOGIC + RSK_BOMBCHUS_IN_LOGIC, + RSK_LINKS_POCKET } RandomizerSettingKey; typedef enum { diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 6d4b68bc0..19e384be6 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -560,10 +560,16 @@ void GiveLinkAdultTradeItem(GetItemID giid) { INV_CONTENT(ITEM_TRADE_ADULT) = item; } -void GiveLinksPocketMedallion() { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LINKS_POCKET, RG_NONE); +void GiveLinksPocketItem() { + if (Randomizer_GetSettingValue(RSK_LINKS_POCKET) < 3) { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LINKS_POCKET, RG_NONE); - GiveLinkDungeonReward(getItemEntry.getItemId); + if (getItemEntry.modIndex == MOD_NONE) { + Item_Give(NULL, getItemEntry.itemId); + } else if (getItemEntry.modIndex == MOD_RANDOMIZER) { + Randomizer_Item_Give(NULL, getItemEntry); + } + } } /** @@ -802,7 +808,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { } // Give Link's pocket item - GiveLinksPocketMedallion(); + GiveLinksPocketItem(); int openForest = Randomizer_GetSettingValue(RSK_FOREST); switch (openForest) { From 350d0b91ede4f5931d0d90a0f0ac2d65a8fc5a72 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Sat, 3 Sep 2022 02:47:42 -0400 Subject: [PATCH 17/20] Removes unneeded `GiveLinkItem` functions. --- soh/src/code/z_sram.c | 470 +----------------------------------------- 1 file changed, 3 insertions(+), 467 deletions(-) diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 19e384be6..20d255bca 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -54,31 +54,6 @@ void GiveLinkRupees(int numOfRupees) { } } -void GiveLinkRupeesByGetItemId(GetItemID giid) { - if (giid == GI_RUPEE_GREEN) { - GiveLinkRupees(1); - } else if (giid == GI_RUPEE_BLUE) { - GiveLinkRupees(5); - } else if (giid == GI_RUPEE_RED) { - GiveLinkRupees(20); - } else if (giid == GI_RUPEE_PURPLE) { - GiveLinkRupees(50); - } else if (giid == GI_RUPEE_GOLD) { - GiveLinkRupees(100); - } -} - -void GiveLinkBombchus(GetItemID giid) { - INV_CONTENT(ITEM_BOMBCHU) = ITEM_BOMBCHU; - if (giid == GI_BOMBCHUS_5) { - AMMO(ITEM_BOMBCHU) += 5; - } else if (giid == GI_BOMBCHUS_10) { - AMMO(ITEM_BOMBCHU) += 10; - } else if (giid == GI_BOMBCHUS_20) { - AMMO(ITEM_BOMBCHU) += 20; - } -} - void GiveLinkDekuSticks(int howManySticks) { int maxStickCount; if (CUR_UPG_VALUE(UPG_STICKS) == 0) { @@ -100,16 +75,6 @@ void GiveLinkDekuSticks(int howManySticks) { } } -void GiveLinkDekuSticksByGetItemId(GetItemID giid) { - if (giid == GI_STICKS_1) { - GiveLinkDekuSticks(1); - } else if (giid == GI_STICKS_5) { - GiveLinkDekuSticks(5); - } else if (giid == GI_STICKS_10) { - GiveLinkDekuSticks(10); - } -} - void GiveLinkDekuNuts(int howManyNuts) { int maxNutCount; if (CUR_UPG_VALUE(UPG_NUTS) == 0) { @@ -131,435 +96,6 @@ void GiveLinkDekuNuts(int howManyNuts) { } } -void GiveLinkDekuNutsByGetItemId(GetItemID giid) { - if (giid == GI_NUTS_5) { - GiveLinkDekuNuts(5); - } else if (giid == GI_NUTS_10) { - GiveLinkDekuNuts(10); - } -} - -void GiveLinkBeans() { - INV_CONTENT(ITEM_BEAN) = ITEM_BEAN; - AMMO(ITEM_BEAN)++; -} - -void GiveLinkKokiriSword() { - uint32_t bitMask = 1 << 0; - gSaveContext.inventory.equipment |= bitMask; -} - -void GiveLinkGiantsKnife() { - gSaveContext.bgsFlag = 0; - gSaveContext.swordHealth = 8; - uint32_t bitMask = 1 << 2; - gSaveContext.inventory.equipment |= bitMask; -} - -void GiveLinkBiggoronSword() { - gSaveContext.bgsFlag = 1; - gSaveContext.swordHealth = 8; - uint32_t bitMask = 1 << 2; - gSaveContext.inventory.equipment |= bitMask; -} - -void GiveLinkDekuShield() { - uint32_t bitMask = 1 << 4; - gSaveContext.inventory.equipment |= bitMask; -} - -void GiveLinkHylianShield() { - uint32_t bitMask = 1 << 5; - gSaveContext.inventory.equipment |= bitMask; -} - -void GiveLinkMirrorShield() { - uint32_t bitMask = 1 << 6; - gSaveContext.inventory.equipment |= bitMask; -} - -void GiveLinkGoronTunic() { - uint32_t bitMask = 1 << 9; - gSaveContext.inventory.equipment |= bitMask; -} - -void GiveLinkZoraTunic() { - uint32_t bitMask = 1 << 10; - gSaveContext.inventory.equipment |= bitMask; -} - -void GiveLinkIronBoots() { - uint32_t bitMask = 1 << 13; - gSaveContext.inventory.equipment |= bitMask; -} - -void GiveLinkHoverBoots() { - uint32_t bitMask = 1 << 14; - gSaveContext.inventory.equipment |= bitMask; -} - -void GiveLinkStoneOfAgony() { - uint32_t bitMask = 1 << QUEST_STONE_OF_AGONY; - gSaveContext.inventory.questItems |= bitMask; -} - -void GiveLinkGerudoCard() { - uint32_t bitMask = 1 << QUEST_GERUDO_CARD; - gSaveContext.inventory.questItems |= bitMask; -} - -void GiveLinkPieceOfHeart() { - int32_t pohCount = (gSaveContext.inventory.questItems & 0xF0000000) >> 28; - pohCount++; - gSaveContext.inventory.questItems |= (pohCount << 28); -} - -void GiveLinkHeartContainer() { - gSaveContext.healthCapacity += 16; - gSaveContext.health += 16; -} - -void GiveLinkBulletBagUpgrade(GetItemID giid) { - if (giid == GI_SLINGSHOT) { - INV_CONTENT(ITEM_SLINGSHOT) = ITEM_SLINGSHOT; - AMMO(ITEM_SLINGSHOT) = 30; - Inventory_ChangeUpgrade(UPG_BULLET_BAG, 1); - } else if (giid == GI_BULLET_BAG_40) { - Inventory_ChangeUpgrade(UPG_BULLET_BAG, 2); - AMMO(ITEM_SLINGSHOT) = 40; - } else if (giid == GI_BULLET_BAG_50) { - Inventory_ChangeUpgrade(UPG_BULLET_BAG, 3); - AMMO(ITEM_SLINGSHOT) = 50; - } -} - -void GiveLinkQuiverUpgrade(GetItemID giid) { - if (giid == GI_BOW) { - INV_CONTENT(ITEM_BOW) = ITEM_BOW; - Inventory_ChangeUpgrade(UPG_QUIVER, 1); - AMMO(ITEM_BOW) = 30; - } else if (giid == GI_QUIVER_40) { - Inventory_ChangeUpgrade(UPG_QUIVER, 2); - AMMO(ITEM_BOW) = 40; - } else if (giid == GI_QUIVER_50) { - Inventory_ChangeUpgrade(UPG_QUIVER, 3); - AMMO(ITEM_BOW) = 50; - } -} - -void GiveLinkBombBagUpgrade(GetItemID giid) { - if (giid == GI_BOMB_BAG_20) { - INV_CONTENT(ITEM_BOMB) = ITEM_BOMB; - Inventory_ChangeUpgrade(UPG_BOMB_BAG, 1); - AMMO(ITEM_BOMB) = 20; - } else if (giid == GI_BOMB_BAG_30) { - Inventory_ChangeUpgrade(UPG_BOMB_BAG, 2); - AMMO(ITEM_BOMB) = 30; - } else if (giid == GI_BOMB_BAG_40) { - Inventory_ChangeUpgrade(UPG_BOMB_BAG, 3); - AMMO(ITEM_BOMB) = 40; - } -} - -void GiveLinkStrengthUpgrade(GetItemID giid) { - if (giid == GI_BRACELET) { - Inventory_ChangeUpgrade(UPG_STRENGTH, 1); - } else if (giid == GI_GAUNTLETS_SILVER) { - Inventory_ChangeUpgrade(UPG_STRENGTH, 2); - } else if (giid == GI_GAUNTLETS_GOLD) { - Inventory_ChangeUpgrade(UPG_STRENGTH, 3); - } -} - -void GiveLinkScaleUpgrade(GetItemID giid) { - if (giid == GI_SCALE_SILVER) { - Inventory_ChangeUpgrade(UPG_SCALE, 1); - } else if (giid == GI_SCALE_GOLD) { - Inventory_ChangeUpgrade(UPG_SCALE, 2); - } -} - -void GiveLinkWalletUpgrade(GetItemID giid) { - if (giid == GI_WALLET_ADULT) { - Inventory_ChangeUpgrade(UPG_WALLET, 1); - } else if (giid == GI_WALLET_GIANT) { - Inventory_ChangeUpgrade(UPG_WALLET, 2); - } -} - -void GiveLinkDekuStickUpgrade(GetItemID giid) { - if (giid == GI_STICK_UPGRADE_20) { - INV_CONTENT(ITEM_STICK) = ITEM_STICK; - Inventory_ChangeUpgrade(UPG_STICKS, 2); - AMMO(ITEM_STICK) = 20; - } else if (giid == GI_STICK_UPGRADE_30) { - Inventory_ChangeUpgrade(UPG_STICKS, 3); - AMMO(ITEM_STICK) = 30; - } -} - -void GiveLinkDekuNutUpgrade(GetItemID giid) { - if (giid == GI_NUT_UPGRADE_30) { - INV_CONTENT(ITEM_NUT) = ITEM_NUT; - Inventory_ChangeUpgrade(UPG_NUTS, 2); - AMMO(ITEM_NUT) = 30; - } else if (giid == GI_NUT_UPGRADE_40) { - Inventory_ChangeUpgrade(UPG_NUTS, 3); - AMMO(ITEM_NUT) = 40; - } -} - -void GiveLinkSkullToken() { - gSaveContext.inventory.questItems |= gBitFlags[QUEST_SKULL_TOKEN]; - gSaveContext.inventory.gsTokens++; -} - -void GiveLinkMagic(GetItemID giid) { - if (giid == RG_MAGIC_SINGLE) { - gSaveContext.magicLevel = 1; - gSaveContext.magicAcquired = true; - gSaveContext.doubleMagic = false; - } else if (giid == RG_MAGIC_DOUBLE) { - gSaveContext.magicLevel = 2; - gSaveContext.magicAcquired = true; - gSaveContext.doubleMagic = true; - } -} - -void GiveLinkDoubleDefense() { - gSaveContext.doubleDefense = 1; - gSaveContext.inventory.defenseHearts = 20; -} - -void GiveLinkSong(GetItemID getItemId) { - uint32_t bitMask; - - switch (getItemId) { - case RG_ZELDAS_LULLABY: - bitMask = 1 << QUEST_SONG_LULLABY; - break; - case RG_SUNS_SONG: - bitMask = 1 << QUEST_SONG_SUN; - break; - case RG_EPONAS_SONG: - bitMask = 1 << QUEST_SONG_EPONA; - break; - case RG_SONG_OF_STORMS: - bitMask = 1 << QUEST_SONG_STORMS; - break; - case RG_SONG_OF_TIME: - bitMask = 1 << QUEST_SONG_TIME; - break; - case RG_SARIAS_SONG: - bitMask = 1 << QUEST_SONG_SARIA; - break; - case RG_MINUET_OF_FOREST: - bitMask = 1 << QUEST_SONG_MINUET; - break; - case RG_BOLERO_OF_FIRE: - bitMask = 1 << QUEST_SONG_BOLERO; - break; - case RG_SERENADE_OF_WATER: - bitMask = 1 << QUEST_SONG_SERENADE; - break; - case RG_NOCTURNE_OF_SHADOW: - bitMask = 1 << QUEST_SONG_NOCTURNE; - break; - case RG_REQUIEM_OF_SPIRIT: - bitMask = 1 << QUEST_SONG_REQUIEM; - break; - case RG_PRELUDE_OF_LIGHT: - bitMask = 1 << QUEST_SONG_PRELUDE; - break; - } - - gSaveContext.inventory.questItems |= bitMask; -} - -void GiveLinkDungeonReward(uint16_t getItemId) { - s16 item; - - u8 medallion = 0; - - switch (getItemId) { - case RG_FOREST_MEDALLION: - item = ITEM_MEDALLION_FOREST; - medallion = 1; - break; - case RG_FIRE_MEDALLION: - item = ITEM_MEDALLION_FIRE; - medallion = 1; - break; - case RG_WATER_MEDALLION: - item = ITEM_MEDALLION_WATER; - medallion = 1; - break; - case RG_SHADOW_MEDALLION: - item = ITEM_MEDALLION_SHADOW; - medallion = 1; - break; - case RG_SPIRIT_MEDALLION: - item = ITEM_MEDALLION_SPIRIT; - medallion = 1; - break; - case RG_LIGHT_MEDALLION: - item = ITEM_MEDALLION_LIGHT; - medallion = 1; - break; - case RG_KOKIRI_EMERALD: - item = ITEM_KOKIRI_EMERALD; - break; - case RG_GORON_RUBY: - item = ITEM_GORON_RUBY; - break; - case RG_ZORA_SAPPHIRE: - item = ITEM_ZORA_SAPPHIRE; - break; - } - - if (medallion == 1) { - gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_MEDALLION_FOREST + QUEST_MEDALLION_FOREST]; - } else { - gSaveContext.inventory.questItems |= gBitFlags[item - ITEM_KOKIRI_EMERALD + QUEST_KOKIRI_EMERALD]; - } -} - -void GiveLinkDungeonItem(GetItemID getItemId) { - int mapIndex; - - switch (getItemId) { - case RG_DEKU_TREE_MAP: - case RG_DEKU_TREE_COMPASS: - mapIndex = SCENE_YDAN; - break; - case RG_DODONGOS_CAVERN_MAP: - case RG_DODONGOS_CAVERN_COMPASS: - mapIndex = SCENE_DDAN; - break; - case RG_JABU_JABUS_BELLY_MAP: - case RG_JABU_JABUS_BELLY_COMPASS: - mapIndex = SCENE_BDAN; - break; - case RG_FOREST_TEMPLE_MAP: - case RG_FOREST_TEMPLE_COMPASS: - case RG_FOREST_TEMPLE_SMALL_KEY: - case RG_FOREST_TEMPLE_BOSS_KEY: - mapIndex = SCENE_BMORI1; - break; - case RG_FIRE_TEMPLE_MAP: - case RG_FIRE_TEMPLE_COMPASS: - case RG_FIRE_TEMPLE_SMALL_KEY: - case RG_FIRE_TEMPLE_BOSS_KEY: - mapIndex = SCENE_HIDAN; - break; - case RG_WATER_TEMPLE_MAP: - case RG_WATER_TEMPLE_COMPASS: - case RG_WATER_TEMPLE_SMALL_KEY: - case RG_WATER_TEMPLE_BOSS_KEY: - mapIndex = SCENE_MIZUSIN; - break; - case RG_SPIRIT_TEMPLE_MAP: - case RG_SPIRIT_TEMPLE_COMPASS: - case RG_SPIRIT_TEMPLE_SMALL_KEY: - case RG_SPIRIT_TEMPLE_BOSS_KEY: - mapIndex = SCENE_JYASINZOU; - break; - case RG_SHADOW_TEMPLE_MAP: - case RG_SHADOW_TEMPLE_COMPASS: - case RG_SHADOW_TEMPLE_SMALL_KEY: - case RG_SHADOW_TEMPLE_BOSS_KEY: - mapIndex = SCENE_HAKADAN; - break; - case RG_BOTTOM_OF_THE_WELL_MAP: - case RG_BOTTOM_OF_THE_WELL_COMPASS: - case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: - mapIndex = SCENE_HAKADANCH; - break; - case RG_ICE_CAVERN_MAP: - case RG_ICE_CAVERN_COMPASS: - mapIndex = SCENE_ICE_DOUKUTO; - break; - case RG_GANONS_CASTLE_BOSS_KEY: - mapIndex = SCENE_GANON; - break; - case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY: - mapIndex = SCENE_MEN; - break; - case RG_GERUDO_FORTRESS_SMALL_KEY: - mapIndex = SCENE_GERUDOWAY; - break; - case RG_GANONS_CASTLE_SMALL_KEY: - mapIndex = SCENE_GANONTIKA; - break; - } - - if ((getItemId >= RG_GERUDO_FORTRESS_SMALL_KEY) && (getItemId <= RG_GANONS_CASTLE_SMALL_KEY)) { - if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { - gSaveContext.inventory.dungeonKeys[mapIndex] = 1; - } else { - gSaveContext.inventory.dungeonKeys[mapIndex]++; - } - } else { - int bitmask; - if ((getItemId >= RG_DEKU_TREE_MAP) && (getItemId <= RG_ICE_CAVERN_MAP)) { - bitmask = gBitFlags[2]; - } else if ((getItemId >= RG_DEKU_TREE_COMPASS) && (getItemId <= RG_ICE_CAVERN_COMPASS)) { - bitmask = gBitFlags[1]; - } else { - bitmask = gBitFlags[0]; - } - - gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask; - } -} - -void GiveLinkAdultTradeItem(GetItemID giid) { - ItemID item; - switch (giid) { - case GI_POCKET_EGG: - item = ITEM_POCKET_EGG; - break; - case GI_POCKET_CUCCO: - item = ITEM_POCKET_CUCCO; - break; - case GI_COJIRO: - item = ITEM_COJIRO; - break; - case GI_ODD_MUSHROOM: - item = ITEM_ODD_MUSHROOM; - break; - case GI_ODD_POTION: - item = ITEM_ODD_POTION; - break; - case GI_SAW: - item = ITEM_SAW; - break; - case GI_SWORD_BROKEN: - item = ITEM_SWORD_BROKEN; - break; - case GI_PRESCRIPTION: - item = ITEM_PRESCRIPTION; - break; - case GI_FROG: - item = ITEM_FROG; - break; - case GI_EYEDROPS: - item = ITEM_EYEDROPS; - break; - case GI_CLAIM_CHECK: - item = ITEM_CLAIM_CHECK; - break; - } - if ((item == ITEM_SAW) && CVar_GetS32("gDekuNutUpgradeFix", 0) == 0) { - gSaveContext.itemGetInf[1] |= 0x8000; - } - - if (item >= ITEM_POCKET_EGG) { - gSaveContext.adultTradeItems |= ADULT_TRADE_FLAG(item); - } - INV_CONTENT(ITEM_TRADE_ADULT) = item; -} - void GiveLinksPocketItem() { if (Randomizer_GetSettingValue(RSK_LINKS_POCKET) < 3) { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LINKS_POCKET, RG_NONE); @@ -837,8 +373,8 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { break; } - if(Randomizer_GetSettingValue(RSK_STARTING_KOKIRI_SWORD)) GiveLinkKokiriSword(); - if(Randomizer_GetSettingValue(RSK_STARTING_DEKU_SHIELD)) GiveLinkDekuShield(); + if(Randomizer_GetSettingValue(RSK_STARTING_KOKIRI_SWORD)) Item_Give(NULL, ITEM_SWORD_KOKIRI); + if(Randomizer_GetSettingValue(RSK_STARTING_DEKU_SHIELD)) Item_Give(NULL, ITEM_SHIELD_DEKU); if(Randomizer_GetSettingValue(RSK_STARTING_OCARINA)) { INV_CONTENT(ITEM_OCARINA_FAIRY) = ITEM_OCARINA_FAIRY; @@ -973,7 +509,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { gSaveContext.sceneFlags[12].collect |= (1 << 0x0C); if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { - GiveLinkGerudoCard(); + Item_Give(NULL, ITEM_GERUDO_CARD); } } From 3a6d7fcfd042880c7d14018ec267230b33c2993f Mon Sep 17 00:00:00 2001 From: briaguya Date: Sat, 3 Sep 2022 04:23:25 -0400 Subject: [PATCH 18/20] and make it build --- .../Enhancements/debugger/ImGuiHelpers.cpp | 32 -- soh/soh/Enhancements/debugger/ImGuiHelpers.h | 10 - .../Enhancements/debugger/debugSaveEditor.cpp | 3 +- .../Enhancements/randomizer/randomizer.cpp | 296 +++++++++--------- .../randomizer/randomizer_check_objects.cpp | 2 +- .../randomizer/randomizer_item_tracker.cpp | 25 +- soh/src/code/z_en_item00.c | 2 +- 7 files changed, 165 insertions(+), 205 deletions(-) delete mode 100644 soh/soh/Enhancements/debugger/ImGuiHelpers.cpp delete mode 100644 soh/soh/Enhancements/debugger/ImGuiHelpers.h diff --git a/soh/soh/Enhancements/debugger/ImGuiHelpers.cpp b/soh/soh/Enhancements/debugger/ImGuiHelpers.cpp deleted file mode 100644 index d0ccab0eb..000000000 --- a/soh/soh/Enhancements/debugger/ImGuiHelpers.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "ImGuiHelpers.h" -#include "../../../../libultraship/libultraship/ImGuiImpl.h" - -// Adds a text tooltip for the previous ImGui item -void SetLastItemHoverText(const std::string& text) { - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text(SohImGui::BreakTooltip(text, 60).c_str()); - ImGui::EndTooltip(); - } -} - -// Adds a "?" next to the previous ImGui item with a custom tooltip -void InsertHelpHoverText(const std::string& text) { - ImGui::SameLine(); - ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "?"); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text(SohImGui::BreakTooltip(text, 60).c_str()); - ImGui::EndTooltip(); - } -} - -void PaddedSeparator(bool padTop, bool padBottom, float extraVerticalPadding) { - if (padTop) { - ImGui::Dummy(ImVec2(0.0f, extraVerticalPadding)); - } - ImGui::Separator(); - if (padBottom) { - ImGui::Dummy(ImVec2(0.0f, extraVerticalPadding)); - } -} diff --git a/soh/soh/Enhancements/debugger/ImGuiHelpers.h b/soh/soh/Enhancements/debugger/ImGuiHelpers.h deleted file mode 100644 index 91df059aa..000000000 --- a/soh/soh/Enhancements/debugger/ImGuiHelpers.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "../libultraship/Lib/ImGui/imgui.h" - -#include - -void SetLastItemHoverText(const std::string& text); - -void InsertHelpHoverText(const std::string& text); - -void PaddedSeparator(bool padTop = true, bool padBottom = true, float extraVerticalPadding = 0); diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index dc365c69e..3765f5d6b 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1,5 +1,6 @@ #include "debugSaveEditor.h" #include "../../util.h" +#include "../../OTRGlobals.h" #include #include "../../UIWidgets.hpp" @@ -623,7 +624,7 @@ void DrawInventoryTab() { gSaveContext.inventory.items[selectedIndex] = slotEntry.id; // Set adult trade item flag if you're playing adult trade shuffle in rando if (gSaveContext.n64ddFlag && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE); + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) && selectedIndex == SLOT_TRADE_ADULT && slotEntry.id >= ITEM_POCKET_EGG && slotEntry.id <= ITEM_CLAIM_CHECK) { gSaveContext.adultTradeItems |= ADULT_TRADE_FLAG(slotEntry.id); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 4744bfd8d..a81fdb839 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3567,7 +3567,7 @@ void DrawRandoEditor(bool& open) { bool disableEditingRandoSettings = CVar_GetS32("gRandoGenerating", 0) || CVar_GetS32("gOnFileSelectNameEntry", 0); ImGui::PushItemFlag(ImGuiItemFlags_Disabled, disableEditingRandoSettings); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * (disableEditingRandoSettings ? 0.5f : 1.0f)); - SohImGui::EnhancementCheckbox("Enable Randomizer", "gRandomizer"); + UIWidgets::EnhancementCheckbox("Enable Randomizer", "gRandomizer"); if (CVar_GetS32("gRandomizer", 0)) { ImGui::Dummy(ImVec2(0.0f, 0.0f)); @@ -3585,7 +3585,7 @@ void DrawRandoEditor(bool& open) { // ImGui::Text("Settings File: %s", presetfilepath.c_str()); } - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGuiWindow* window = ImGui::GetCurrentWindow(); static ImVec2 cellPadding(8.0f, 8.0f); @@ -3611,7 +3611,7 @@ void DrawRandoEditor(bool& open) { // Forest ImGui::Text(Settings::OpenForest.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Closed - Kokiri sword & shield are required to access " "the Deku Tree, and completing the Deku Tree is required to " "access the Hyrule Field exit.\n" @@ -3623,26 +3623,26 @@ void DrawRandoEditor(bool& open) { "Open - Mido no longer blocks the path to the Deku Tree. Kokiri " "boy no longer blocks the path out of the forest." ); - SohImGui::EnhancementCombobox("gRandomizeForest", randoForest, 3, 0); + UIWidgets::EnhancementCombobox("gRandomizeForest", randoForest, 3, 0); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Kakariko Gate ImGui::Text(Settings::OpenKakariko.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Closed - The gate will remain closed until Zelda's letter " "is shown to the guard.\n" "\n" "Open - The gate is always open. The happy mask shop " "will open immediately after obtaining Zelda's letter." ); - SohImGui::EnhancementCombobox("gRandomizeKakarikoGate", randoKakarikoGate, 2, 0); + UIWidgets::EnhancementCombobox("gRandomizeKakarikoGate", randoKakarikoGate, 2, 0); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Door of Time ImGui::Text(Settings::OpenDoorOfTime.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Closed - The Ocarina of Time, the Song of Time and all " "three spiritual stones are required to open the Door of Time.\n" "\n" @@ -3651,13 +3651,13 @@ void DrawRandoEditor(bool& open) { "\n" "Open - The Door of Time is permanently open with no requirements." ); - SohImGui::EnhancementCombobox("gRandomizeDoorOfTime", randoDoorOfTime, 3, 0); + UIWidgets::EnhancementCombobox("gRandomizeDoorOfTime", randoDoorOfTime, 3, 0); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Zora's Fountain ImGui::Text(Settings::ZorasFountain.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Closed - King Zora obstructs the way to Zora's Fountain. " "Ruto's letter must be shown as child Link in order to move " "him in both time periods.\n" @@ -3668,9 +3668,9 @@ void DrawRandoEditor(bool& open) { "Open - King Zora has already mweeped out of the way in both " "time periods. Ruto's Letter is removed from the item pool." ); - SohImGui::EnhancementCombobox("gRandomizeZorasFountain", randoZorasFountain, 3, 0); + UIWidgets::EnhancementCombobox("gRandomizeZorasFountain", randoZorasFountain, 3, 0); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGui::EndChild(); @@ -3682,7 +3682,7 @@ void DrawRandoEditor(bool& open) { // Gerudo Fortress ImGui::Text("Gerudo Fortress Carpenters"); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Sets the amount of carpenters required to repair the bridge " "in Gerudo Valley.\n" "\n" @@ -3692,13 +3692,13 @@ void DrawRandoEditor(bool& open) { "\n" "Open - The bridge is repaired from the start." ); - SohImGui::EnhancementCombobox("gRandomizeGerudoFortress", randoGerudoFortress, 3, 0); + UIWidgets::EnhancementCombobox("gRandomizeGerudoFortress", randoGerudoFortress, 3, 0); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Rainbow Bridge ImGui::Text("Rainbow Bridge Requirements"); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Alters the requirements to open the bridge to Ganon's Castle.\n" "\n" "Vanilla - Obtain the Shadow Medallion, Spirit Medallion and Light Arrows.\n" @@ -3719,7 +3719,7 @@ void DrawRandoEditor(bool& open) { "Tokens - Obtain the specified amount of Skulltula tokens." ); - SohImGui::EnhancementCombobox("gRandomizeRainbowBridge", randoRainbowBridge, 7, 0); + UIWidgets::EnhancementCombobox("gRandomizeRainbowBridge", randoRainbowBridge, 7, 0); ImGui::PopItemWidth(); switch (CVar_GetS32("gRandomizeRainbowBridge", 0)) { case 0: @@ -3728,37 +3728,37 @@ void DrawRandoEditor(bool& open) { break; case 2: ImGui::Dummy(ImVec2(0.0f, 0.0f)); - SohImGui::EnhancementSliderInt("Stone Count: %d", "##RandoStoneCount", + UIWidgets::EnhancementSliderInt("Stone Count: %d", "##RandoStoneCount", "gRandomizeStoneCount", 1, 3, "", 3, true); break; case 3: ImGui::Dummy(ImVec2(0.0f, 0.0f)); - SohImGui::EnhancementSliderInt("Medallion Count: %d", "##RandoMedallionCount", + UIWidgets::EnhancementSliderInt("Medallion Count: %d", "##RandoMedallionCount", "gRandomizeMedallionCount", 1, 6, "", 6, true); break; case 4: ImGui::Dummy(ImVec2(0.0f, 0.0f)); - SohImGui::EnhancementSliderInt("Reward Count: %d", "##RandoRewardCount", + UIWidgets::EnhancementSliderInt("Reward Count: %d", "##RandoRewardCount", "gRandomizeRewardCount", 1, 9, "", 9, true); break; case 5: ImGui::Dummy(ImVec2(0.0f, 0.0f)); - SohImGui::EnhancementSliderInt("Dungeon Count: %d", "##RandoDungeonCount", + UIWidgets::EnhancementSliderInt("Dungeon Count: %d", "##RandoDungeonCount", "gRandomizeDungeonCount", 1, 8, "", 8, true); break; case 6: ImGui::Dummy(ImVec2(0.0f, 0.0f)); - SohImGui::EnhancementSliderInt("Token Count: %d", "##RandoTokenCount", + UIWidgets::EnhancementSliderInt("Token Count: %d", "##RandoTokenCount", "gRandomizeTokenCount", 1, 100, "", 100, true); break; } - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Ganon's Trials ImGui::PushItemWidth(-FLT_MIN); ImGui::Text("Ganon's Trials"); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Sets the number of Ganon's Trials required to dispel the barrier.\n" "\n" "Skip - No Trials are required and the barrier is already dispelled.\n" @@ -3768,16 +3768,16 @@ void DrawRandoEditor(bool& open) { "\n" "Random Number - A Random number and set of trials will be required." ); - SohImGui::EnhancementCombobox("gRandomizeGanonTrial", randoGanonsTrial, 3, 0); + UIWidgets::EnhancementCombobox("gRandomizeGanonTrial", randoGanonsTrial, 3, 0); ImGui::PopItemWidth(); if (CVar_GetS32("gRandomizeGanonTrial", 0) == 1) { ImGui::Dummy(ImVec2(0.0f, 0.0f)); - SohImGui::EnhancementSliderInt("Ganon's Trial Count: %d", "##RandoTrialCount", + UIWidgets::EnhancementSliderInt("Ganon's Trial Count: %d", "##RandoTrialCount", "gRandomizeGanonTrialCount", 1, 6, "", 6, true); - InsertHelpHoverText("Set the number of trials required to enter Ganon's Tower."); + UIWidgets::InsertHelpHoverText("Set the number of trials required to enter Ganon's Tower."); } - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGui::EndChild(); @@ -3789,7 +3789,7 @@ void DrawRandoEditor(bool& open) { ImGui::Text("Coming soon"); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGui::PopItemWidth(); ImGui::EndChild(); @@ -3819,7 +3819,7 @@ void DrawRandoEditor(bool& open) { // Shuffle Songs ImGui::Text(Settings::ShuffleSongs.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Song locations - Songs will only appear at locations that normally teach songs.\n" "\n" "Dungeon rewards - Songs appear after beating a major dungeon boss.\n" @@ -3831,13 +3831,13 @@ void DrawRandoEditor(bool& open) { "\n" "Anywhere - Songs can appear at any location." ); - SohImGui::EnhancementCombobox("gRandomizeShuffleSongs", randoShuffleSongs, 3, 0); + UIWidgets::EnhancementCombobox("gRandomizeShuffleSongs", randoShuffleSongs, 3, 0); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Shuffle Tokens ImGui::Text(Settings::Tokensanity.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Shuffles Golden Skulltula Tokens into the item pool. This means " "Golden Skulltulas can contain other items as well.\n" "\n" @@ -3849,53 +3849,53 @@ void DrawRandoEditor(bool& open) { "\n" "All Tokens - Shuffle all 100 GS tokens." ); - SohImGui::EnhancementCombobox("gRandomizeShuffleTokens", randoTokensanity, 4, 0); + UIWidgets::EnhancementCombobox("gRandomizeShuffleTokens", randoTokensanity, 4, 0); ImGui::Dummy(ImVec2(0,0)); - SohImGui::EnhancementCheckbox("Nighttime GS expect Sun's Song", "gRandomizeGsExpectSunsSong"); - InsertHelpHoverText( + UIWidgets::EnhancementCheckbox("Nighttime GS expect Sun's Song", "gRandomizeGsExpectSunsSong"); + UIWidgets::InsertHelpHoverText( "All Golden Skulltulas that require nighttime to appear will only be " "expected to be collected after getting Sun's Song." ); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Shuffle Kokiri Sword // Disabled when Start with Kokiri Sword is active bool disableShuffleKokiriSword = CVar_GetS32("gRandomizeStartingKokiriSword", 0); const char* disableShuffleKokiriSwordText = "This option is disabled because \"Start with Kokiri Sword\" is enabled."; - SohImGui::EnhancementCheckbox(Settings::ShuffleKokiriSword.GetName().c_str(), "gRandomizeShuffleKokiriSword", + UIWidgets::EnhancementCheckbox(Settings::ShuffleKokiriSword.GetName().c_str(), "gRandomizeShuffleKokiriSword", disableShuffleKokiriSword, disableShuffleKokiriSwordText); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Shuffles the Kokiri Sword into the item pool.\n" "\n" "This will require the use of sticks until the Kokiri Sword is found." ); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Shuffle Ocarinas // Disabled when Start with Ocarina is active bool disableShuffleOcarinas = CVar_GetS32("gRandomizeStartingOcarina", 0); const char* disableShuffleOcarinasText = "This option is disabled because \"Start with Fairy Ocarina\" is enabled."; - SohImGui::EnhancementCheckbox(Settings::ShuffleOcarinas.GetName().c_str(), "gRandomizeShuffleOcarinas", + UIWidgets::EnhancementCheckbox(Settings::ShuffleOcarinas.GetName().c_str(), "gRandomizeShuffleOcarinas", disableShuffleOcarinas, disableShuffleOcarinasText); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Enabling this shuffles the Fairy Ocarina and the Ocarina of Time into the item pool.\n" "\n" "This will require finding an Ocarina before being able to play songs." ); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Shuffle Weird Egg // Disabled when Skip Child Zelda is active bool disableShuffleWeirdEgg = CVar_GetS32("gRandomizeSkipChildZelda", 0); const char* disableShuffleWeirdEggText = "This option is disabled because \"Skip Child Zelda\" is enabled."; - SohImGui::EnhancementCheckbox(Settings::ShuffleWeirdEgg.GetName().c_str(), "gRandomizeShuffleWeirdEgg", + UIWidgets::EnhancementCheckbox(Settings::ShuffleWeirdEgg.GetName().c_str(), "gRandomizeShuffleWeirdEgg", disableShuffleWeirdEgg, disableShuffleWeirdEggText); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Shuffles the Weird Egg from Malon in to the item pool. Enabling " "\"Skip Child Zelda\" disables this feature.\n" "\n" @@ -3907,19 +3907,19 @@ void DrawRandoEditor(bool& open) { " - Happy Mask Shop sidequest\n" ); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Shuffle Gerudo Membership Card - SohImGui::EnhancementCheckbox(Settings::ShuffleGerudoToken.GetName().c_str(), + UIWidgets::EnhancementCheckbox(Settings::ShuffleGerudoToken.GetName().c_str(), "gRandomizeShuffleGerudoToken"); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Shuffles the Gerudo Membership Card into the item pool.\n" "\n" "The Gerudo Card is required to enter the Gerudo Training Grounds, opening " "the gate to Haunted Wasteland and the Horseback Archery minigame." ); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGui::PopItemWidth(); ImGui::EndChild(); @@ -3932,7 +3932,7 @@ void DrawRandoEditor(bool& open) { // Shuffle Scrubs ImGui::Text(Settings::Scrubsanity.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Off - Scrubs will not be shuffled. The 3 Scrubs that give one-time items in the vanilla game " "(PoH, Deku Nut capacity, and Deku Stick capacity) will have random items.\n" "\n" @@ -3941,27 +3941,27 @@ void DrawRandoEditor(bool& open) { "Expensive - Scrubs will be shuffled and their item will cost the vanilla price.\n" "\n" "Random - Scrubs will be shuffled and their item will cost will be between 0-95 rupees.\n"); - SohImGui::EnhancementCombobox("gRandomizeShuffleScrubs", randoShuffleScrubs, 4, 0); + UIWidgets::EnhancementCombobox("gRandomizeShuffleScrubs", randoShuffleScrubs, 4, 0); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Shuffle Cows - SohImGui::EnhancementCheckbox(Settings::ShuffleCows.GetName().c_str(), "gRandomizeShuffleCows"); - InsertHelpHoverText("Cows give a randomized item from the pool upon performing Epona's Song in front of them."); + UIWidgets::EnhancementCheckbox(Settings::ShuffleCows.GetName().c_str(), "gRandomizeShuffleCows"); + UIWidgets::InsertHelpHoverText("Cows give a randomized item from the pool upon performing Epona's Song in front of them."); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); - SohImGui::EnhancementCheckbox(Settings::ShuffleMagicBeans.GetName().c_str(), "gRandomizeShuffleBeans"); - InsertHelpHoverText( + UIWidgets::EnhancementCheckbox(Settings::ShuffleMagicBeans.GetName().c_str(), "gRandomizeShuffleBeans"); + UIWidgets::InsertHelpHoverText( "Enabling this adds a pack of 10 beans to the item pool and changes the Magic Bean " "Salesman to sell a random item at a price of 60 rupees." ); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Shuffle Frog Song Rupees - SohImGui::EnhancementCheckbox(Settings::ShuffleFrogSongRupees.GetName().c_str(), "gRandomizeShuffleFrogSongRupees"); - InsertHelpHoverText( + UIWidgets::EnhancementCheckbox(Settings::ShuffleFrogSongRupees.GetName().c_str(), "gRandomizeShuffleFrogSongRupees"); + UIWidgets::InsertHelpHoverText( "Shuffles 5 Purple Rupees into to the item pool, and allows\n" "you to earn items by playing songs at the Frog Choir.\n" "\n" @@ -3969,12 +3969,12 @@ void DrawRandoEditor(bool& open) { "the Song of Storms and the frog song minigame." ); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Shuffle Adult Trade Quest - SohImGui::EnhancementCheckbox(Settings::ShuffleAdultTradeQuest.GetName().c_str(), + UIWidgets::EnhancementCheckbox(Settings::ShuffleAdultTradeQuest.GetName().c_str(), "gRandomizeShuffleAdultTrade"); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Adds all of the adult trade quest items into the pool, each of which " "can be traded for a unique reward.\n" "\n" @@ -3985,7 +3985,7 @@ void DrawRandoEditor(bool& open) { "If disabled, only the Claim Check will be found in the pool." ); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGui::PopItemWidth(); ImGui::EndChild(); @@ -3998,7 +3998,7 @@ void DrawRandoEditor(bool& open) { // Shuffle Dungeon Rewards ImGui::Text(Settings::ShuffleRewards.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Shuffles the location of spiritual stones and medallions.\n" "\n" "End of dungeons - Spiritual stones and medallions will be given as rewards " @@ -4010,13 +4010,13 @@ void DrawRandoEditor(bool& open) { "\n" "Anywhere - Spiritual stones and medallions can appear anywhere." ); - SohImGui::EnhancementCombobox("gRandomizeShuffleDungeonReward", randoShuffleDungeonRewards, 4, 0); + UIWidgets::EnhancementCombobox("gRandomizeShuffleDungeonReward", randoShuffleDungeonRewards, 4, 0); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Maps & Compasses ImGui::Text(Settings::MapsAndCompasses.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Start with - You will start with Maps & Compasses from all dungeons.\n" "\n" "Vanilla - Maps & Compasses will appear in their vanilla locations.\n" @@ -4029,13 +4029,13 @@ void DrawRandoEditor(bool& open) { "\n" "Anywhere - Maps & Compasses can appear anywhere in the world." ); - SohImGui::EnhancementCombobox("gRandomizeStartingMapsCompasses", randoShuffleMapsAndCompasses, 6, 2); + UIWidgets::EnhancementCombobox("gRandomizeStartingMapsCompasses", randoShuffleMapsAndCompasses, 6, 2); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Keysanity ImGui::Text(Settings::Keysanity.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Start with - You will start with all Small Keys from all dungeons.\n" "\n" "Vanilla - Small Keys will appear in their vanilla locations.\n" @@ -4048,13 +4048,13 @@ void DrawRandoEditor(bool& open) { "\n" "Anywhere - Small Keys can appear anywhere in the world." ); - SohImGui::EnhancementCombobox("gRandomizeKeysanity", randoShuffleSmallKeys, 6, 2); + UIWidgets::EnhancementCombobox("gRandomizeKeysanity", randoShuffleSmallKeys, 6, 2); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Gerudo Keys ImGui::Text(Settings::GerudoKeys.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Vanilla - Thieve's Hideout Keys will appear in their vanilla locations.\n" "\n" "Any dungeon - Thieve's Hideout Keys can only appear inside of any dungon.\n" @@ -4063,13 +4063,13 @@ void DrawRandoEditor(bool& open) { "\n" "Anywhere - Thieve's Hideout Keys can appear anywhere in the world." ); - SohImGui::EnhancementCombobox("gRandomizeGerudoKeys", randoShuffleGerudoFortressKeys, 4, 0); + UIWidgets::EnhancementCombobox("gRandomizeGerudoKeys", randoShuffleGerudoFortressKeys, 4, 0); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Boss Keysanity ImGui::Text(Settings::BossKeysanity.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Start with - You will start with Boss keys from all dungeons.\n" "\n" "Vanilla - Boss Keys will appear in their vanilla locations.\n" @@ -4082,13 +4082,13 @@ void DrawRandoEditor(bool& open) { "\n" "Anywhere - Boss Keys can appear anywhere in the world." ); - SohImGui::EnhancementCombobox("gRandomizeBossKeysanity", randoShuffleBossKeys, 6, 2); + UIWidgets::EnhancementCombobox("gRandomizeBossKeysanity", randoShuffleBossKeys, 6, 2); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Ganon's Boss Key ImGui::Text(Settings::GanonsBossKey.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Vanilla - Ganon's Boss Key will appear in the vanilla location.\n" "\n" "Own dungeon - Ganon's Boss Key can appear anywhere inside Ganon's Castle.\n" @@ -4101,9 +4101,9 @@ void DrawRandoEditor(bool& open) { "\n" "Anywhere - Ganon's Boss Key Key can appear anywhere in the world." ); - SohImGui::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 6, 1); + UIWidgets::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, 6, 1); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGui::PopItemWidth(); ImGui::EndChild(); @@ -4130,53 +4130,53 @@ void DrawRandoEditor(bool& open) { ImGui::BeginChild("ChildTimeSavers", ImVec2(0, -8)); // Cuccos to return - SohImGui::EnhancementSliderInt("Cuccos to return: %d", "##RandoCuccosToReturn", + UIWidgets::EnhancementSliderInt("Cuccos to return: %d", "##RandoCuccosToReturn", "gRandomizeCuccosToReturn", 0, 7, "", 7, true); - InsertHelpHoverText("The amount of cuccos needed to claim the reward from Anju the cucco lady"); + UIWidgets::InsertHelpHoverText("The amount of cuccos needed to claim the reward from Anju the cucco lady"); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Big Poe Target Count - SohImGui::EnhancementSliderInt("Big Poe Target Count: %d", "##RandoBigPoeTargetCount", + UIWidgets::EnhancementSliderInt("Big Poe Target Count: %d", "##RandoBigPoeTargetCount", "gRandomizeBigPoeTargetCount", 1, 10, "", 10, true); - InsertHelpHoverText("The Poe collector will give a reward for turning in this many Big Poes."); + UIWidgets::InsertHelpHoverText("The Poe collector will give a reward for turning in this many Big Poes."); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Skip child stealth // Disabled when Skip Child Zelda is active bool disableChildStealth = CVar_GetS32("gRandomizeSkipChildZelda", 0); const char* disableChildStealthText = "This option is disabled because \"Skip Child Zelda\" is enabled"; - SohImGui::EnhancementCheckbox(Settings::SkipChildStealth.GetName().c_str(), "gRandomizeSkipChildStealth", disableChildStealth, disableChildStealthText); - InsertHelpHoverText("The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards."); + UIWidgets::EnhancementCheckbox(Settings::SkipChildStealth.GetName().c_str(), "gRandomizeSkipChildStealth", disableChildStealth, disableChildStealthText); + UIWidgets::InsertHelpHoverText("The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards."); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Skip child zelda - SohImGui::EnhancementCheckbox("Skip Child Zelda", "gRandomizeSkipChildZelda"); - InsertHelpHoverText("Start with Zelda's Letter and the item Impa would normally give you and skip the sequence up " + UIWidgets::EnhancementCheckbox("Skip Child Zelda", "gRandomizeSkipChildZelda"); + UIWidgets::InsertHelpHoverText("Start with Zelda's Letter and the item Impa would normally give you and skip the sequence up " "until after meeting Zelda. Disables the ability to shuffle Weird Egg."); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Skip Epona race - SohImGui::EnhancementCheckbox(Settings::SkipEponaRace.GetName().c_str(), "gRandomizeSkipEponaRace"); - InsertHelpHoverText("Epona can be summoned with Epona's Song without needing to race Ingo."); + UIWidgets::EnhancementCheckbox(Settings::SkipEponaRace.GetName().c_str(), "gRandomizeSkipEponaRace"); + UIWidgets::InsertHelpHoverText("Epona can be summoned with Epona's Song without needing to race Ingo."); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Skip tower escape - SohImGui::EnhancementCheckbox(Settings::SkipTowerEscape.GetName().c_str(), "gRandomizeSkipTowerEscape"); - InsertHelpHoverText("The tower escape sequence between Ganondorf and Ganon will be skipped."); + UIWidgets::EnhancementCheckbox(Settings::SkipTowerEscape.GetName().c_str(), "gRandomizeSkipTowerEscape"); + UIWidgets::InsertHelpHoverText("The tower escape sequence between Ganondorf and Ganon will be skipped."); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Complete mask quest - SohImGui::EnhancementCheckbox(Settings::CompleteMaskQuest.GetName().c_str(), + UIWidgets::EnhancementCheckbox(Settings::CompleteMaskQuest.GetName().c_str(), "gRandomizeCompleteMaskQuest"); - InsertHelpHoverText("Once the happy mask shop is opened, all masks will be available to be borrowed."); + UIWidgets::InsertHelpHoverText("Once the happy mask shop is opened, all masks will be available to be borrowed."); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGui::EndChild(); @@ -4188,7 +4188,7 @@ void DrawRandoEditor(bool& open) { // Item Pool Settings ImGui::Text(Settings::ItemPoolValue.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Sets how many major items appear in the item pool.\n" "\n" "Plentiful - Extra major items are added to the pool.\n" @@ -4199,12 +4199,12 @@ void DrawRandoEditor(bool& open) { "\n" "Minimal - Most excess items are removed." ); - SohImGui::EnhancementCombobox("gRandomizeItemPool", randoItemPool, 4, 1); - PaddedSeparator(); + UIWidgets::EnhancementCombobox("gRandomizeItemPool", randoItemPool, 4, 1); + UIWidgets::PaddedSeparator(); // Ice Traps ImGui::Text(Settings::IceTrapValue.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Sets how many items are replaced by ice traps.\n" "\n" "Off - No ice traps.\n" @@ -4218,13 +4218,13 @@ void DrawRandoEditor(bool& open) { "Onslaught - All junk items will be replaced by Ice Traps, even those " "in the base pool." ); - SohImGui::EnhancementCombobox("gRandomizeIceTraps", randoIceTraps, 5, 1); + UIWidgets::EnhancementCombobox("gRandomizeIceTraps", randoIceTraps, 5, 1); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Gossip Stone Hints ImGui::Text(Settings::GossipStoneHints.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Allows Gossip Stones to provide hints on item locations. Hints mentioning " "\"Way of the Hero\" indicate a location that holds an item required to beat " "the seed.\n" @@ -4236,13 +4236,13 @@ void DrawRandoEditor(bool& open) { "Need Stone of Agony - Hints are only available after obtaining the Stone of Agony.\n" "\n" "Need Mask of Truth - Hints are only available whilst wearing the Mask of Truth.\n"); - SohImGui::EnhancementCombobox("gRandomizeGossipStoneHints", randoGossipStoneHints, 4, 1); + UIWidgets::EnhancementCombobox("gRandomizeGossipStoneHints", randoGossipStoneHints, 4, 1); if (CVar_GetS32("gRandomizeGossipStoneHints", 1) != 0) { // Hint Clarity ImGui::Dummy(ImVec2(0.0f, 0.0f)); ImGui::Indent(); ImGui::Text(Settings::ClearerHints.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Sets the difficulty of hints.\n" "\n" "Obscure - Hints are unique for each item, but the writing may be cryptic.\n" @@ -4254,12 +4254,12 @@ void DrawRandoEditor(bool& open) { "Clear - Hints are clearly written and are unique for each item.\n" "Ex: Kokiri Sword > the Kokiri Sword" ); - SohImGui::EnhancementCombobox("gRandomizeHintClarity", randoHintClarity, 3, 2); + UIWidgets::EnhancementCombobox("gRandomizeHintClarity", randoHintClarity, 3, 2); // Hint Distribution ImGui::Dummy(ImVec2(0.0f, 0.0f)); ImGui::Text(Settings::HintDistribution.GetName().c_str()); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Sets how many hints will be useful.\n" "\n" "Useless - Only junk hints.\n" @@ -4270,11 +4270,11 @@ void DrawRandoEditor(bool& open) { "\n" "Very Strong - Many powerful hints." ); - SohImGui::EnhancementCombobox("gRandomizeHintDistribution", randoHintDistribution, 4, 1); + UIWidgets::EnhancementCombobox("gRandomizeHintDistribution", randoHintDistribution, 4, 1); ImGui::Unindent(); } - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGui::PopItemWidth(); ImGui::EndChild(); @@ -4285,14 +4285,14 @@ void DrawRandoEditor(bool& open) { ImGui::BeginChild("ChildAdditionalFeatures", ImVec2(0, -8)); ImGui::PushItemWidth(-FLT_MIN); - SohImGui::EnhancementCheckbox("Full Wallets", "gRandomizeFullWallets"); - InsertHelpHoverText("Start with a full wallet. All wallet upgrades come filled with rupees."); + UIWidgets::EnhancementCheckbox("Full Wallets", "gRandomizeFullWallets"); + UIWidgets::InsertHelpHoverText("Start with a full wallet. All wallet upgrades come filled with rupees."); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Bombchus in Logic - SohImGui::EnhancementCheckbox(Settings::BombchusInLogic.GetName().c_str(), "gRandomizeBombchusInLogic"); - InsertHelpHoverText( + UIWidgets::EnhancementCheckbox(Settings::BombchusInLogic.GetName().c_str(), "gRandomizeBombchusInLogic"); + UIWidgets::InsertHelpHoverText( "Bombchus are properly considered in logic.\n" "\n" "The first Bombchu pack will always be 20, and subsequent packs will be " @@ -4302,23 +4302,23 @@ void DrawRandoEditor(bool& open) { "Bombchu Bowling is opened by obtaining Bombchus." ); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); - SohImGui::EnhancementCheckbox("WIP - Blue Fire Arrows", "gRandomizeBlueIceArrows", true, "In development"); - InsertHelpHoverText( + UIWidgets::EnhancementCheckbox("WIP - Blue Fire Arrows", "gRandomizeBlueIceArrows", true, "In development"); + UIWidgets::InsertHelpHoverText( "Ice Arrows act like Blue Fire, making them able to melt red ice. " "Item placement logic will respect this option, so it might be required to use this to progress." ); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); - SohImGui::EnhancementCheckbox("WIP - Sunlight Arrows", "gRandomizeSunlightArrows", true, "In development"); - InsertHelpHoverText( + UIWidgets::EnhancementCheckbox("WIP - Sunlight Arrows", "gRandomizeSunlightArrows", true, "In development"); + UIWidgets::InsertHelpHoverText( "Light Arrows can be used to light up the sun switches instead of using the Mirror Shield. " "Item placement logic will respect this option, so it might be required to use this to progress." ); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGui::PopItemWidth(); ImGui::EndChild(); @@ -4386,7 +4386,7 @@ void DrawRandoEditor(bool& open) { excludedLocationString += ","; } CVar_SetString("gRandomizeExcludedLocations", excludedLocationString.c_str()); - SohImGui::needs_save = true; + SohImGui::RequestCvarSaveOnNextTick(); } ImGui::SameLine(); ImGui::Text(locationIt.rcShortName.c_str()); @@ -4427,7 +4427,7 @@ void DrawRandoEditor(bool& open) { excludedLocationString += ","; } CVar_SetString("gRandomizeExcludedLocations", excludedLocationString.c_str()); - SohImGui::needs_save = true; + SohImGui::RequestCvarSaveOnNextTick(); } ImGui::SameLine(); ImGui::Text(locationIt.rcShortName.c_str()); @@ -4455,19 +4455,19 @@ void DrawRandoEditor(bool& open) { ImGui::TableNextColumn(); ImGui::PushItemWidth(170.0); ImGui::Text("Logic Rules"); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "Glitchless - No glitches are required, but may require some minor tricks.\n" "\n" "No logic - Item placement is completely random. MAY BE IMPOSSIBLE TO BEAT." ); - SohImGui::EnhancementCombobox("gRandomizeLogicRules", randoLogicRules, 2, 0); + UIWidgets::EnhancementCombobox("gRandomizeLogicRules", randoLogicRules, 2, 0); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); // Enable Glitch-Useful Cutscenes - SohImGui::EnhancementCheckbox(Settings::EnableGlitchCutscenes.GetName().c_str(), + UIWidgets::EnhancementCheckbox(Settings::EnableGlitchCutscenes.GetName().c_str(), "gRandomizeEnableGlitchCutscenes"); - InsertHelpHoverText( + UIWidgets::InsertHelpHoverText( "The cutscenes of the Poes in Forest Temple and Darunia in Fire Temple will not be skipped. " "These cutscenes are only useful for glitched gameplay and can be safely skipped otherwise."); @@ -4525,17 +4525,17 @@ void DrawRandoEditor(bool& open) { // TODO: Show this but disabled when we have options for disabled Comboboxes. if (CVar_GetS32("gRandomizeShuffleDungeonReward", 0) != 0) { ImGui::Text(Settings::LinksPocketItem.GetName().c_str()); - SohImGui::EnhancementCombobox("gRandomizeLinksPocket", randoLinksPocket, 4, 0); - PaddedSeparator(); + UIWidgets::EnhancementCombobox("gRandomizeLinksPocket", randoLinksPocket, 4, 0); + UIWidgets::PaddedSeparator(); } - SohImGui::EnhancementCheckbox(Settings::StartingKokiriSword.GetName().c_str(), + UIWidgets::EnhancementCheckbox(Settings::StartingKokiriSword.GetName().c_str(), "gRandomizeStartingKokiriSword"); - PaddedSeparator(); - SohImGui::EnhancementCheckbox(Settings::StartingDekuShield.GetName().c_str(), + UIWidgets::PaddedSeparator(); + UIWidgets::EnhancementCheckbox(Settings::StartingDekuShield.GetName().c_str(), "gRandomizeStartingDekuShield"); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGui::EndChild(); @@ -4544,11 +4544,11 @@ void DrawRandoEditor(bool& open) { window->DC.CurrLineTextBaseOffset = 0.0f; ImGui::BeginChild("ChildStartingItems", ImVec2(0, -8)); - SohImGui::EnhancementCheckbox(Settings::StartingOcarina.GetName().c_str(), "gRandomizeStartingOcarina"); - PaddedSeparator(); - SohImGui::EnhancementCheckbox(Settings::StartingConsumables.GetName().c_str(), + UIWidgets::EnhancementCheckbox(Settings::StartingOcarina.GetName().c_str(), "gRandomizeStartingOcarina"); + UIWidgets::PaddedSeparator(); + UIWidgets::EnhancementCheckbox(Settings::StartingConsumables.GetName().c_str(), "gRandomizeStartingConsumables"); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGui::EndChild(); @@ -4559,7 +4559,7 @@ void DrawRandoEditor(bool& open) { ImGui::Text("Coming soon"); - PaddedSeparator(); + UIWidgets::PaddedSeparator(); ImGui::EndChild(); ImGui::EndTable(); diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index 67327985b..0f3031887 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include /* typedef struct { diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 38fdcc43c..3696fa67f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -7,6 +7,7 @@ #include #include #include +#include extern "C" { #include @@ -349,7 +350,7 @@ void DrawEquip(ItemTrackerItem item) { ImGui::Image(SohImGui::GetTextureByName(hasEquip && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); - SetLastItemHoverText(SohUtils::GetItemName(item.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(item.id)); } void DrawQuest(ItemTrackerItem item) { @@ -365,7 +366,7 @@ void DrawQuest(ItemTrackerItem item) { ImGui::EndGroup(); - SetLastItemHoverText(SohUtils::GetQuestItemName(item.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetQuestItemName(item.id)); }; void DrawItem(ItemTrackerItem item) { @@ -416,7 +417,7 @@ void DrawItem(ItemTrackerItem item) { DrawItemCount(item); ImGui::EndGroup(); - SetLastItemHoverText(SohUtils::GetItemName(item.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(item.id)); } void DrawBottle(ItemTrackerItem item) { @@ -431,7 +432,7 @@ void DrawBottle(ItemTrackerItem item) { ImGui::Image(SohImGui::GetTextureByName(hasItem && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); - SetLastItemHoverText(SohUtils::GetItemName(item.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(item.id)); }; void DrawDungeonItem(ItemTrackerItem item) { @@ -469,7 +470,7 @@ void DrawDungeonItem(ItemTrackerItem item) { } ImGui::EndGroup(); - SetLastItemHoverText(SohUtils::GetItemName(item.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(item.id)); } void DrawSong(ItemTrackerItem item) { @@ -480,7 +481,7 @@ void DrawSong(ItemTrackerItem item) { ImGui::SetCursorScreenPos(ImVec2(p.x + 6, p.y)); ImGui::Image(SohImGui::GetTextureByName(hasSong && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize / 1.5, iconSize), ImVec2(0, 0), ImVec2(1, 1)); - SetLastItemHoverText(SohUtils::GetQuestItemName(item.id)); + UIWidgets::SetLastItemHoverText(SohUtils::GetQuestItemName(item.id)); } void DrawNotes(bool resizeable = false) { @@ -645,7 +646,7 @@ void LabeledComboBoxRightAligned(const char* label, const char* cvar, std::vecto for (int i = 0; i < options.size(); i++) { if (ImGui::Selectable(options[i].c_str())) { CVar_SetS32(cvar, i); - SohImGui::needs_save = true; + SohImGui::RequestCvarSaveOnNextTick(); shouldUpdateVectors = true; } } @@ -662,7 +663,7 @@ void PaddedEnhancementCheckbox(const char* text, const char* cvarName, s32 defau bool val = (bool)CVar_GetS32(cvarName, defaultValue); if (ImGui::Checkbox(text, &val)) { CVar_SetS32(cvarName, val); - SohImGui::needs_save = true; + SohImGui::RequestCvarSaveOnNextTick(); shouldUpdateVectors = true; } if (padBottom) { @@ -856,7 +857,7 @@ void DrawItemTrackerOptions(bool& open) { CVar_SetFloat("gItemTrackerBgColorG", ChromaKeyBackground.y); CVar_SetFloat("gItemTrackerBgColorB", ChromaKeyBackground.z); CVar_SetFloat("gItemTrackerBgColorA", ChromaKeyBackground.w); - SohImGui::needs_save = true; + SohImGui::RequestCvarSaveOnNextTick(); } ImGui::PopItemWidth(); @@ -871,9 +872,9 @@ void DrawItemTrackerOptions(bool& open) { LabeledComboBoxRightAligned("Combo Button 2", "gItemTrackerComboButton2", { "A", "B", "C-Up", "C-Down", "C-Left", "C-Right", "L", "Z", "R", "Start", "D-Up", "D-Down", "D-Left", "D-Right" }, 8); } } - PaddedSeparator(); - SohImGui::EnhancementSliderInt("Icon size : %dpx", "##ITEMTRACKERICONSIZE", "gItemTrackerIconSize", 25, 128, "", 36, true); - SohImGui::EnhancementSliderInt("Icon margins : %dpx", "##ITEMTRACKERSPACING", "gItemTrackerIconSpacing", -5, 50, "", 12, true); + UIWidgets::PaddedSeparator(); + UIWidgets::EnhancementSliderInt("Icon size : %dpx", "##ITEMTRACKERICONSIZE", "gItemTrackerIconSize", 25, 128, "", 36, true); + UIWidgets::EnhancementSliderInt("Icon margins : %dpx", "##ITEMTRACKERSPACING", "gItemTrackerIconSpacing", -5, 50, "", 12, true); PaddedEnhancementCheckbox("Display \"Current/Max\" values", "gItemTrackerDisplayCurrentMax", 0); if (CVar_GetS32("gItemTrackerDisplayCurrentMax", 0) == 0) { PaddedEnhancementCheckbox("Align count to left side", "gItemTrackerCurrentOnLeft", 0); diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 7d955e77d..986d5a135 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -519,7 +519,7 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) { if (!gSaveContext.n64ddFlag) { func_8002F554(&this->actor, globalCtx, getItemId); } else { - getItem = Randomizer_GetRandomizedItem(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); + getItem = Randomizer_GetItemFromActor(this->actor.id, globalCtx->sceneNum, this->ogParams, getItemId); GiveItemEntryFromActorWithFixedRange(&this->actor, globalCtx, getItem); } } From ea4e0652e7c3a3ba114af032bc0d683bbc1972fa Mon Sep 17 00:00:00 2001 From: briaguya Date: Sat, 3 Sep 2022 04:41:43 -0400 Subject: [PATCH 19/20] bring back new rando dropdown --- soh/soh/GameMenuBar.cpp | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp index cf843cc8b..26b4b1ffb 100644 --- a/soh/soh/GameMenuBar.cpp +++ b/soh/soh/GameMenuBar.cpp @@ -1350,7 +1350,7 @@ namespace GameMenuBar { SohImGui::RequestCvarSaveOnNextTick(); SohImGui::EnableWindow("Randomizer Settings", CVar_GetS32("gRandomizerSettingsEnabled", 0)); } - UIWidgets::Spacer(0); + ImGui::Dummy(ImVec2(0.0f, 0.0f)); if (ImGui::Button(GetWindowButtonText("Item Tracker", CVar_GetS32("gItemTrackerEnabled", 0)).c_str(), buttonSize)) { bool currentValue = CVar_GetS32("gItemTrackerEnabled", 0); @@ -1358,9 +1358,42 @@ namespace GameMenuBar { SohImGui::RequestCvarSaveOnNextTick(); SohImGui::EnableWindow("Item Tracker", CVar_GetS32("gItemTrackerEnabled", 0)); } + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + if (ImGui::Button(GetWindowButtonText("Item Tracker Settings", CVar_GetS32("gItemTrackerSettingsEnabled", 0)).c_str(), buttonSize)) + { + bool currentValue = CVar_GetS32("gItemTrackerSettingsEnabled", 0); + CVar_SetS32("gItemTrackerSettingsEnabled", !currentValue); + SohImGui::RequestCvarSaveOnNextTick(); + SohImGui::EnableWindow("Item Tracker Settings", CVar_GetS32("gItemTrackerSettingsEnabled", 0)); + } ImGui::PopStyleVar(3); ImGui::PopStyleColor(1); + UIWidgets::PaddedSeparator(); + + if (ImGui::BeginMenu("Rando Enhancements")) + { + UIWidgets::EnhancementCheckbox("Rando-Relevant Navi Hints", "gRandoRelevantNavi"); + UIWidgets::Tooltip( + "Replace Navi's overworld quest hints with rando-related gameplay hints." + ); + UIWidgets::PaddedEnhancementCheckbox("Random Rupee Names", "gRandomizeRupeeNames", true, false); + UIWidgets::Tooltip( + "When obtaining rupees, randomize what the rupee is called in the textbox." + ); + UIWidgets::PaddedEnhancementCheckbox("Key Colors Match Dungeon", "gRandoMatchKeyColors", true, false); + UIWidgets::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.\n\nThis only " + "applies to seeds with keys and boss keys shuffled to Any Dungeon, Overworld, or Anywhere."); + UIWidgets::PaddedEnhancementCheckbox("Quest Item Fanfares", "gRandoQuestItemFanfares", true, false); + UIWidgets::Tooltip( + "Play unique fanfares when obtaining quest items " + "(medallions/stones/songs). Note that these fanfares are longer than usual." + ); + ImGui::EndMenu(); + } + ImGui::EndMenu(); } } From f1dc980de84766053a8fe28420ca1701d4367432 Mon Sep 17 00:00:00 2001 From: aMannus Date: Sat, 3 Sep 2022 11:16:43 +0200 Subject: [PATCH 20/20] Fixed autobreak after ImGui cleanup --- soh/soh/UIWidgets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/UIWidgets.cpp b/soh/soh/UIWidgets.cpp index d61ddc0f9..148a820c2 100644 --- a/soh/soh/UIWidgets.cpp +++ b/soh/soh/UIWidgets.cpp @@ -25,7 +25,7 @@ namespace UIWidgets { std::string newText(text); const size_t tipLength = newText.length(); int lastSpace = -1; - size_t currentLineLength = 0; + int currentLineLength = 0; for (unsigned int currentCharacter = 0; currentCharacter < tipLength; currentCharacter++) { if (newText[currentCharacter] == '\n') { currentLineLength = 0;