From 2570bf56ea765ea6ed15f07b9603b410b027f0c2 Mon Sep 17 00:00:00 2001 From: Caladius Date: Sat, 10 Aug 2024 22:06:13 -0400 Subject: [PATCH] Search Enhancement (#2) * 90% complete, Commit for review. * Updated remaining Menu Entries, Reverted Backends and other Window Buttons for now. Motion Blur copied to Search Menu. * Did I mention I dislike this clang thing? lol * Updating MotionBlur options and reverting soem things. * Integrates .disabled and .disabledTooltip to the constructors. Allows for multiple qualifications to be checked against for disabling widgets and for setting the tooltip accordingly. * Updated Disabled Reasoning * Better Disabled State registration system * Clean up from testing --- mm/2s2h/Enhancements/Graphics/MotionBlur.cpp | 15 +- mm/2s2h/Menu.cpp | 610 +++------ mm/2s2h/search/SearchMenu.h | 1214 ++++++++++++++++++ 3 files changed, 1412 insertions(+), 427 deletions(-) create mode 100644 mm/2s2h/search/SearchMenu.h diff --git a/mm/2s2h/Enhancements/Graphics/MotionBlur.cpp b/mm/2s2h/Enhancements/Graphics/MotionBlur.cpp index d7afd78e13..4ecf51035b 100644 --- a/mm/2s2h/Enhancements/Graphics/MotionBlur.cpp +++ b/mm/2s2h/Enhancements/Graphics/MotionBlur.cpp @@ -23,15 +23,11 @@ void MotionBlur_RenderMenuOptions() { "This notably reduces the overall motion blur strength but smooths out the trails." }); if (CVarGetInteger("gEnhancements.Graphics.MotionBlur.Mode", 0) == 0) { - UIWidgets::Checkbox("On/Off", (bool*)&R_MOTION_BLUR_ENABLED); - if (R_MOTION_BLUR_ENABLED) { - int32_t motionBlurStrength = R_MOTION_BLUR_ALPHA; - if (UIWidgets::SliderInt("Strength", &motionBlurStrength, 0, 255)) { - R_MOTION_BLUR_ALPHA = motionBlurStrength; - } - } + UIWidgets::CVarCheckbox("On/Off", "gEnhancements.Graphics.MotionBlur.Toggle", + { .tooltip = "Enables Motion Blur." }); } - if (CVarGetInteger("gEnhancements.Graphics.MotionBlur.Mode", 0) == 2) { + if (CVarGetInteger("gEnhancements.Graphics.MotionBlur.Mode", 0) == 2 || + CVarGetInteger("gEnhancements.Graphics.MotionBlur.Toggle", 0) == 1) { UIWidgets::CVarSliderInt("Strength", "gEnhancements.Graphics.MotionBlur.Strength", 0, 255, 180); } } @@ -40,7 +36,8 @@ extern "C" void MotionBlur_Override(u8* status, s32* alpha) { if (CVarGetInteger("gEnhancements.Graphics.MotionBlur.Mode", 0) == 1) { *status = 0; *alpha = 0; - } else if (CVarGetInteger("gEnhancements.Graphics.MotionBlur.Mode", 0) == 2) { + } else if (CVarGetInteger("gEnhancements.Graphics.MotionBlur.Mode", 0) == 2 || + CVarGetInteger("gEnhancements.Graphics.MotionBlur.Toggle", 0) == 1) { if (*status == 0) *status = 2; *alpha = CVarGetInteger("gEnhancements.Graphics.MotionBlur.Strength", 180); diff --git a/mm/2s2h/Menu.cpp b/mm/2s2h/Menu.cpp index 33599b5ac0..13ad7dd530 100644 --- a/mm/2s2h/Menu.cpp +++ b/mm/2s2h/Menu.cpp @@ -15,6 +15,8 @@ #include "DeveloperTools/EventLog.h" #include "2s2h/BenGui/HudEditor.h" +#include "2s2h/search/SearchMenu.h" + extern "C" { #include "z64.h" #include "functions.h" @@ -22,18 +24,6 @@ extern PlayState* gPlayState; } std::vector windowTypeSizes = { {} }; -static const std::unordered_map textureFilteringMap = { - { FILTER_THREE_POINT, "Three-Point" }, - { FILTER_LINEAR, "Linear" }, - { FILTER_NONE, "None" }, -}; - -static const std::unordered_map debugSaveOptions = { - { DEBUG_SAVE_INFO_COMPLETE, "100\% save" }, - { DEBUG_SAVE_INFO_VANILLA_DEBUG, "Vanilla debug save" }, - { DEBUG_SAVE_INFO_NONE, "Empty save" }, -}; - static const std::unordered_map audioBackendsMap = { { Ship::AudioBackend::WASAPI, "Windows Audio Session API" }, { Ship::AudioBackend::SDL, "SDL" }, @@ -45,21 +35,6 @@ static std::unordered_map windowBackendsMap = { Ship::WindowBackend::FAST3D_SDL_METAL, "Metal" }, }; -static const std::unordered_map clockTypeOptions = { - { CLOCK_TYPE_ORIGINAL, "Original" }, - { CLOCK_TYPE_TEXT_BASED, "Text only" }, -}; - -static const std::unordered_map alwaysWinDoggyraceOptions = { - { ALWAYS_WIN_DOGGY_RACE_OFF, "Off" }, - { ALWAYS_WIN_DOGGY_RACE_MASKOFTRUTH, "When owning Mask of Truth" }, - { ALWAYS_WIN_DOGGY_RACE_ALWAYS, "Always" }, -}; - -const char* logLevels[] = { - "trace", "debug", "info", "warn", "error", "critical", "off", -}; - namespace BenGui { extern std::shared_ptr mHudEditorWindow; @@ -77,53 +52,63 @@ extern Ship::WindowBackend configWindowBackend; extern void UpdateWindowBackendObjects(); +char searchText[30] = ""; +uint32_t enhSize = sizeof(enhancementList) / sizeof(enhancementList[0]); + +void DrawSearchSettings() { + ImGui::Text("Search: "); + ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_FrameBg, menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)]); + ImGui::InputText("##search", searchText, sizeof(searchText)); + ImGui::PopStyleColor(1); + std::string str(searchText); + + if (str == "") { + ImGui::Text("Start typing to see results."); + return; + } + ImGui::BeginChild("Search Results"); + for (int i = 0; i < enhSize; i++) { + std::string ctr(enhancementList[i].cVarText); + std::transform(str.begin(), str.end(), str.begin(), ::tolower); + str.erase(std::remove(str.begin(), str.end(), ' '), str.end()); + std::transform(ctr.begin(), ctr.end(), ctr.begin(), ::tolower); + ctr.erase(std::remove(ctr.begin(), ctr.end(), ' '), ctr.end()); + if (ctr.find(str) != std::string::npos) { + SearchMenuGetItem(i); + } + } + ImGui::EndChild(); +} + void DrawGeneralSettings() { + SearchMenuGetItem(MENU_ITEM_MENU_THEME); + #if not defined(__SWITCH__) and not defined(__WIIU__) - UIWidgets::CVarCheckbox( - "Menubar Controller Navigation", CVAR_IMGUI_CONTROLLER_NAV, - { .tooltip = "Allows controller navigation of the SOH menu bar (Settings, Enhancements,...)\nCAUTION: " - "This will disable game inputs while the menubar is visible.\n\nD-pad to move between " - "items, A to select, and X to grab focus on the menu bar" }); - bool cursor = Ship::Context::GetInstance()->GetWindow()->ShouldForceCursorVisibility(); - if (UIWidgets::Checkbox("Cursor Always Visible", &cursor, - { .tooltip = "Makes the cursor always visible, even in full screen." })) { - Ship::Context::GetInstance()->GetWindow()->SetForceCursorVisibility(cursor); - } + SearchMenuGetItem(MENU_ITEM_MENUBAR_CONTROLLER_NAV); + SearchMenuGetItem(MENU_ITEM_CURSOR_VISIBILITY); + // bool cursor = Ship::Context::GetInstance()->GetWindow()->ShouldForceCursorVisibility(); + // if (UIWidgets::Checkbox("Cursor Always Visible", &cursor, + // { .tooltip = "Makes the cursor always visible, even in full screen." })) { + // Ship::Context::GetInstance()->GetWindow()->SetForceCursorVisibility(cursor); + // } #endif - UIWidgets::CVarCheckbox("Hide Menu Hotkey Text", "gSettings.DisableMenuShortcutNotify", - { .tooltip = "Prevents showing the text telling you the shortcut to open the menu\n" - "when the menu isn't open." }); + SearchMenuGetItem(MENU_ITEM_HOTKEY_TEXT); } void DrawAudioSettings() { - UIWidgets::CVarSliderFloat("Master Volume: %.0f %%", "gSettings.Audio.MasterVolume", 0.0f, 1.0f, 1.0f, - { .showButtons = false, .format = "", .isPercentage = true }); - - if (UIWidgets::CVarSliderFloat("Main Music Volume: %.0f %%", "gSettings.Audio.MainMusicVolume", 0.0f, 1.0f, 1.0f, - { .showButtons = false, .format = "", .isPercentage = true })) { - AudioSeq_SetPortVolumeScale(SEQ_PLAYER_BGM_MAIN, CVarGetFloat("gSettings.Audio.MainMusicVolume", 1.0f)); - } - if (UIWidgets::CVarSliderFloat("Sub Music Volume: %.0f %%", "gSettings.Audio.SubMusicVolume", 0.0f, 1.0f, 1.0f, - { .showButtons = false, .format = "", .isPercentage = true })) { - AudioSeq_SetPortVolumeScale(SEQ_PLAYER_BGM_SUB, CVarGetFloat("gSettings.Audio.SubMusicVolume", 1.0f)); - } - if (UIWidgets::CVarSliderFloat("Sound Effects Volume: %.0f %%", "gSettings.Audio.SoundEffectsVolume", 0.0f, 1.0f, - 1.0f, { .showButtons = false, .format = "", .isPercentage = true })) { - AudioSeq_SetPortVolumeScale(SEQ_PLAYER_SFX, CVarGetFloat("gSettings.Audio.SoundEffectsVolume", 1.0f)); - } - if (UIWidgets::CVarSliderFloat("Fanfare Volume: %.0f %%", "gSettings.Audio.FanfareVolume", 0.0f, 1.0f, 1.0f, - { .showButtons = false, .format = "", .isPercentage = true })) { - AudioSeq_SetPortVolumeScale(SEQ_PLAYER_FANFARE, CVarGetFloat("gSettings.Audio.FanfareVolume", 1.0f)); - } - if (UIWidgets::CVarSliderFloat("Ambience Volume: %.0f %%", "gSettings.Audio.AmbienceVolume", 0.0f, 1.0f, 1.0f, - { .showButtons = false, .format = "", .isPercentage = true })) { - AudioSeq_SetPortVolumeScale(SEQ_PLAYER_AMBIENCE, CVarGetFloat("gSettings.Audio.AmbienceVolume", 1.0f)); - } + SearchMenuGetItem(MENU_ITEM_MASTER_VOLUME); + SearchMenuGetItem(MENU_ITEM_MAIN_MUSIC_VOLUME); + SearchMenuGetItem(MENU_ITEM_SUB_MUSIC_VOLUME); + SearchMenuGetItem(MENU_ITEM_SOUND_EFFECT_VOLUME); + SearchMenuGetItem(MENU_ITEM_FANFARE_VOLUME); + SearchMenuGetItem(MENU_ITEM_AMBIENT_VOLUME); auto currentAudioBackend = Ship::Context::GetInstance()->GetAudio()->GetAudioBackend(); if (UIWidgets::Combobox( "Audio API", ¤tAudioBackend, audioBackendsMap, - { .tooltip = "Sets the audio API used by the game. Requires a relaunch to take effect.", + { .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + .tooltip = "Sets the audio API used by the game. Requires a relaunch to take effect.", .disabled = Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1, .disabledTooltip = "Only one audio API is available on this platform." })) { Ship::Context::GetInstance()->GetAudio()->SetAudioBackend(currentAudioBackend); @@ -131,83 +116,22 @@ void DrawAudioSettings() { } void DrawGraphicsSettings() { - bool fs = Ship::Context::GetInstance()->GetWindow()->IsFullscreen(); - if (UIWidgets::Checkbox("Toggle Fullscreen", &fs)) { - Ship::Context::GetInstance()->GetWindow()->ToggleFullscreen(); - } + SearchMenuGetItem(MENU_ITEM_TOGGLE_FULLSCREEN); #ifndef __APPLE__ - if (UIWidgets::CVarSliderFloat("Internal Resolution: %f %%", CVAR_INTERNAL_RESOLUTION, 0.5f, 2.0f, 1.0f)) { - Ship::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(CVarGetFloat(CVAR_INTERNAL_RESOLUTION, 1)); - }; - UIWidgets::Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but effective " - "form of anti-aliasing"); + SearchMenuGetItem(MENU_ITEM_INTERNAL_RESOLUTION); #endif #ifndef __WIIU__ - if (UIWidgets::CVarSliderInt((CVarGetInteger(CVAR_MSAA_VALUE, 1) == 1) ? "Anti-aliasing (MSAA): Off" - : "Anti-aliasing (MSAA): %d", - CVAR_MSAA_VALUE, 1, 8, 1)) { - Ship::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger(CVAR_MSAA_VALUE, 1)); - }; - UIWidgets::Tooltip("Activates MSAA (multi-sample anti-aliasing) from 2x up to 8x, to smooth the edges of rendered " - "geometry.\n" - "Higher sample count will result in smoother edges on models, but may reduce performance."); + SearchMenuGetItem(MENU_ITEM_MSAA); #endif - - { // FPS Slider - constexpr unsigned int minFps = 20; - static unsigned int maxFps; - if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) { - maxFps = 360; - } else { - maxFps = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); - } - unsigned int currentFps = std::max(std::min(OTRGlobals::Instance->GetInterpolationFPS(), maxFps), minFps); - bool matchingRefreshRate = - CVarGetInteger("gMatchRefreshRate", 0) && - Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() != Ship::WindowBackend::FAST3D_DXGI_DX11; - UIWidgets::CVarSliderInt((currentFps == 20) ? "FPS: Original (20)" : "FPS: %d", "gInterpolationFPS", minFps, - maxFps, 20, { .disabled = matchingRefreshRate }); - if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) { - UIWidgets::Tooltip( - "Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is " - "purely visual and does not impact game logic, execution of glitches etc.\n\n A higher target " - "FPS than your monitor's refresh rate will waste resources, and might give a worse result."); - } else { - UIWidgets::Tooltip( - "Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is " - "purely visual and does not impact game logic, execution of glitches etc."); - } - } // END FPS Slider - - if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) { - // UIWidgets::Spacer(0); - if (ImGui::Button("Match Refresh Rate")) { - int hz = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); - if (hz >= 20 && hz <= 360) { - CVarSetInteger("gInterpolationFPS", hz); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - } - } - } else { - UIWidgets::CVarCheckbox("Match Refresh Rate", "gMatchRefreshRate"); - } - UIWidgets::Tooltip("Matches interpolation value to the current game's window refresh rate"); - + SearchMenuGetItem(MENU_ITEM_FRAME_RATE); + SearchMenuGetItem(MENU_ITEM_MATCH_REFRESH_RATE); if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) { - UIWidgets::CVarSliderInt(CVarGetInteger("gExtraLatencyThreshold", 80) == 0 ? "Jitter fix: Off" - : "Jitter fix: >= %d FPS", - "gExtraLatencyThreshold", 0, 360, 80); - 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."); + SearchMenuGetItem(MENU_ITEM_JITTER_FIX); } - - // UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); // #endregion */ - if (UIWidgets::Combobox("Renderer API (Needs reload)", &configWindowBackend, availableWindowBackendsMap, - { .tooltip = "Sets the renderer API used by the game. Requires a relaunch to take effect.", + { .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + .tooltip = "Sets the renderer API used by the game. Requires a relaunch to take effect.", .disabled = availableWindowBackends->size() <= 1, .disabledTooltip = "Only one renderer API is available on this platform." })) { Ship::Context::GetInstance()->GetConfig()->SetInt("Window.Backend.Id", @@ -219,23 +143,22 @@ void DrawGraphicsSettings() { } if (Ship::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) { - UIWidgets::CVarCheckbox("Enable Vsync", CVAR_VSYNC_ENABLED); + SearchMenuGetItem(MENU_ITEM_ENABLE_VSYNC); } if (Ship::Context::GetInstance()->GetWindow()->SupportsWindowedFullscreen()) { - UIWidgets::CVarCheckbox("Windowed fullscreen", CVAR_SDL_WINDOWED_FULLSCREEN); + SearchMenuGetItem(MENU_ITEM_ENABLE_WINDOWED_FULLSCREEN); } if (Ship::Context::GetInstance()->GetWindow()->GetGui()->SupportsViewports()) { - UIWidgets::CVarCheckbox( - "Allow multi-windows", CVAR_ENABLE_MULTI_VIEWPORTS, - { .tooltip = "Allows multiple windows to be opened at once. Requires a reload to take effect." }); + SearchMenuGetItem(MENU_ITEM_ENABLE_MULTI_VIEWPORT); } - UIWidgets::CVarCombobox("Texture Filter (Needs reload)", CVAR_TEXTURE_FILTER, textureFilteringMap); + SearchMenuGetItem(MENU_ITEM_TEXTURE_FILTER); } void DrawControllerSettings() { + // SearchMenuGetItem(MENU_ITEM_INPUT_EDITOR); UIWidgets::WindowButton("Popout Input Editor", "gWindows.BenInputEditor", mBenInputEditorWindow, { .tooltip = "Enables the separate Input Editor window." }); if (!CVarGetInteger("gWindows.BenInputEditor", 0)) { @@ -246,39 +169,21 @@ void DrawControllerSettings() { // Camera void DrawCameraEnhancements1() { ImGui::SeparatorText("Fixes"); - UIWidgets::CVarCheckbox( - "Fix Targetting Camera Snap", "gEnhancements.Camera.FixTargettingCameraSnap", - { .tooltip = "Fixes the camera snap that occurs when you are moving and press the targetting button." }); + SearchMenuGetItem(MENU_ITEM_FIX_TARGET_CAMERA_SNAP); } void DrawCameraEnhancements2() { ImGui::SeparatorText("Free Look"); - if (UIWidgets::CVarCheckbox( - "Free Look", "gEnhancements.Camera.FreeLook.Enable", - { .tooltip = "Enables free look 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.", - .disabled = CVarGetInteger("gEnhancements.Camera.DebugCam.Enable", 0) != 0 })) { - RegisterCameraFreeLook(); - } - + SearchMenuGetItem(MENU_ITEM_ENABLE_FREE_LOOK); if (CVarGetInteger("gEnhancements.Camera.FreeLook.Enable", 0)) { - UIWidgets::CVarCheckbox("Invert Camera X Axis", "gEnhancements.Camera.RightStick.InvertXAxis", - { .tooltip = "Inverts the Camera X Axis" }); - UIWidgets::CVarCheckbox("Invert Camera Y Axis", "gEnhancements.Camera.RightStick.InvertYAxis", - { .tooltip = "Inverts the Camera Y Axis", .defaultValue = true }); - UIWidgets::CVarSliderFloat("Third-Person Horizontal Sensitivity: %.0f", - "gEnhancements.Camera.RightStick.CameraSensitivity.X", 0.01f, 5.0f, 1.0f); - UIWidgets::CVarSliderFloat("Third-Person Vertical Sensitivity: %.0f", - "gEnhancements.Camera.RightStick.CameraSensitivity.Y", 0.01f, 5.0f, 1.0f); - - UIWidgets::CVarSliderInt("Camera Distance: %d", "gEnhancements.Camera.FreeLook.MaxCameraDistance", 100, 900, - 185); - UIWidgets::CVarSliderInt("Camera Transition Speed: %d", "gEnhancements.Camera.FreeLook.TransitionSpeed", 1, 900, - 25); - UIWidgets::CVarSliderFloat("Max Camera Height Angle: %.0f°", "gEnhancements.Camera.FreeLook.MaxPitch", -89.0f, - 89.0f, 72.0f); - UIWidgets::CVarSliderFloat("Min Camera Height Angle: %.0f°", "gEnhancements.Camera.FreeLook.MinPitch", -89.0f, - 89.0f, -49.0f); + SearchMenuGetItem(MENU_ITEM_INVERT_CAMERA_X_AXIS); + SearchMenuGetItem(MENU_ITEM_INVERT_CAMERA_Y_AXIS); + SearchMenuGetItem(MENU_ITEM_THIRD_PERSON_CAMERA_X_SENSITIVITY); + SearchMenuGetItem(MENU_ITEM_THIRD_PERSON_CAMERA_Y_SENSITIVITY); + SearchMenuGetItem(MENU_ITEM_FREE_LOOK_CAMERA_DISTANCE); + SearchMenuGetItem(MENU_ITEM_FREE_LOOK_TRANSITION_SPEED); + SearchMenuGetItem(MENU_ITEM_FREE_LOOK_MAX_PITCH); + SearchMenuGetItem(MENU_ITEM_FREE_LOOK_MIN_PITCH); f32 maxY = CVarGetFloat("gEnhancements.Camera.FreeLook.MaxPitch", 72.0f); f32 minY = CVarGetFloat("gEnhancements.Camera.FreeLook.MinPitch", -49.0f); CVarSetFloat("gEnhancements.Camera.FreeLook.MaxPitch", std::max(maxY, minY)); @@ -288,244 +193,153 @@ void DrawCameraEnhancements2() { void DrawCameraEnhancements3() { ImGui::SeparatorText("'Debug' Camera"); - if (UIWidgets::CVarCheckbox("Debug Camera", "gEnhancements.Camera.DebugCam.Enable", - { .tooltip = "Enables free camera control.", - .disabled = CVarGetInteger("gEnhancements.Camera.FreeLook.Enable", 0) != 0 })) { - RegisterDebugCam(); - } - + SearchMenuGetItem(MENU_ITEM_ENABLE_DEBUG_CAMERA); if (CVarGetInteger("gEnhancements.Camera.DebugCam.Enable", 0)) { - UIWidgets::CVarCheckbox("Invert Camera X Axis", "gEnhancements.Camera.RightStick.InvertXAxis", - { .tooltip = "Inverts the Camera X Axis" }); - UIWidgets::CVarCheckbox("Invert Camera Y Axis", "gEnhancements.Camera.RightStick.InvertYAxis", - { .tooltip = "Inverts the Camera Y Axis", .defaultValue = true }); - UIWidgets::CVarSliderFloat("Third-Person Horizontal Sensitivity: %.0f", - "gEnhancements.Camera.RightStick.CameraSensitivity.X", 0.01f, 5.0f, 1.0f); - UIWidgets::CVarSliderFloat("Third-Person Vertical Sensitivity: %.0f", - "gEnhancements.Camera.RightStick.CameraSensitivity.Y", 0.01f, 5.0f, 1.0f); - - UIWidgets::CVarCheckbox( - "Enable Roll (Six Degrees Of Freedom)", "gEnhancements.Camera.DebugCam.6DOF", - { .tooltip = "This allows for all six degrees of movement with the camera, NOTE: Yaw will work " - "differently in " - "this system, instead rotating around the focal point, rather than a polar axis." }); - UIWidgets::CVarSliderFloat("Camera Speed: %.0f", "gEnhancements.Camera.DebugCam.CameraSpeed", 0.1f, 3.0f, 0.5f); + SearchMenuGetItem(MENU_ITEM_INVERT_CAMERA_X_AXIS); + SearchMenuGetItem(MENU_ITEM_INVERT_CAMERA_Y_AXIS); + SearchMenuGetItem(MENU_ITEM_THIRD_PERSON_CAMERA_X_SENSITIVITY); + SearchMenuGetItem(MENU_ITEM_THIRD_PERSON_CAMERA_Y_SENSITIVITY); + SearchMenuGetItem(MENU_ITEM_ENABLE_CAMERA_ROLL); + SearchMenuGetItem(MENU_ITEM_CAMERA_SPEED); } } // Cheats void DrawCheatEnhancements() { - UIWidgets::CVarCheckbox("Infinite Health", "gCheats.InfiniteHealth"); - UIWidgets::CVarCheckbox("Infinite Magic", "gCheats.InfiniteMagic"); - UIWidgets::CVarCheckbox("Infinite Rupees", "gCheats.InfiniteRupees"); - UIWidgets::CVarCheckbox("Infinite Consumables", "gCheats.InfiniteConsumables"); - if (UIWidgets::CVarCheckbox( - "Longer Deku Flower Glide", "gCheats.LongerFlowerGlide", - { .tooltip = "Allows Deku Link to glide longer, no longer dropping after a certain distance" })) { - RegisterLongerFlowerGlide(); - } - UIWidgets::CVarCheckbox("No Clip", "gCheats.NoClip"); - UIWidgets::CVarCheckbox("Unbreakable Razor Sword", "gCheats.UnbreakableRazorSword"); - UIWidgets::CVarCheckbox("Unrestricted Items", "gCheats.UnrestrictedItems"); - if (UIWidgets::CVarCheckbox("Moon Jump on L", "gCheats.MoonJumpOnL", - { .tooltip = "Holding L makes you float into the air" })) { - RegisterMoonJumpOnL(); - } + SearchMenuGetItem(MENU_ITEM_CHEATS_INFINITE_HEALTH); + SearchMenuGetItem(MENU_ITEM_CHEATS_INFINITE_MAGIC); + SearchMenuGetItem(MENU_ITEM_CHEATS_INFINITE_RUPEES); + SearchMenuGetItem(MENU_ITEM_CHEATS_INFINITE_CONSUMABLES); + SearchMenuGetItem(MENU_ITEM_CHEATS_LONG_FLOWER_GLIDE); + SearchMenuGetItem(MENU_ITEM_CHEATS_NO_CLIP); + SearchMenuGetItem(MENU_ITEM_CHEATS_INFINITE_RAZOR_SWORD); + SearchMenuGetItem(MENU_ITEM_CHEATS_UNRESTRICTED_ITEMS); + SearchMenuGetItem(MENU_ITEM_CHEATS_MOON_JUMP_ON_L); } // Gameplay void DrawGameplayEnhancements() { ImGui::SeparatorText("Player"); - if (UIWidgets::CVarCheckbox("Fast Deku Flower Launch", "gEnhancements.Player.FastFlowerLaunch", - { .tooltip = "Speeds up the time it takes to be able to get maximum height from " - "launching out of a deku flower" })) { - RegisterFastFlowerLaunch(); - } - UIWidgets::CVarCheckbox("Instant Putaway", "gEnhancements.Player.InstantPutaway", - { .tooltip = "Allows Link to instantly puts away held item without waiting." }); - UIWidgets::CVarSliderInt("Climb speed", "gEnhancements.PlayerMovement.ClimbSpeed", 1, 5, 1, - { .tooltip = "Increases the speed at which Link climbs vines and ladders." }); - UIWidgets::CVarCheckbox("Dpad Equips", "gEnhancements.Dpad.DpadEquips", - { .tooltip = "Allows you to equip items to your d-pad" }); - UIWidgets::CVarCombobox("Always Win Doggy Race", "gEnhancements.Minigames.AlwaysWinDoggyRace", - alwaysWinDoggyraceOptions); + SearchMenuGetItem(MENU_ITEM_FAST_FLOWER_LAUNCH); + SearchMenuGetItem(MENU_ITEM_INSTANT_PUTAWAY); + SearchMenuGetItem(MENU_ITEM_CLIMB_SPEED); + SearchMenuGetItem(MENU_ITEM_DPAD_EQUIPS); + SearchMenuGetItem(MENU_ITEM_ALWAYS_WIN_DOGGY_RACE); } void DrawGameModesEnhancements() { ImGui::SeparatorText("Modes"); - UIWidgets::CVarCheckbox("Play As Kafei", "gModes.PlayAsKafei", - { .tooltip = "Requires scene reload to take effect." }); - if (UIWidgets::CVarCheckbox("Time Moves When You Move", "gModes.TimeMovesWhenYouMove")) { - RegisterTimeMovesWhenYouMove(); - } + SearchMenuGetItem(MENU_ITEM_PLAY_AS_KAFEI); + SearchMenuGetItem(MENU_ITEM_TIME_MOVES_WHEN_YOU_MOVE); } void DrawSaveTimeEnhancements() { ImGui::SeparatorText("Saving"); - UIWidgets::CVarCheckbox("Persistent Owl Saves", "gEnhancements.Saving.PersistentOwlSaves", - { .tooltip = "Continuing a save will not remove the owl save. Playing Song of " - "Time, allowing the moon to crash or finishing the " - "game will remove the owl save and become the new last save." }); - UIWidgets::CVarCheckbox( - "Pause Menu Save", "gEnhancements.Saving.PauseSave", - { .tooltip = "Re-introduce the pause menu save system. Pressing B in the pause menu will give you the " - "option to create a persistent Owl Save from your current location.\n\nWhen loading back " - "into the game, you will be placed either at the entrance of the dungeon you saved in, or " - "in South Clock Town." }); - if (UIWidgets::CVarCheckbox( - "Autosave", "gEnhancements.Saving.Autosave", - { .tooltip = "Automatically create a persistent Owl Save on the chosen interval.\n\nWhen loading " - "back into the game, you will be placed either at the entrance of the dungeon you " - "saved in, or in South Clock Town." })) { - RegisterAutosave(); - } - UIWidgets::CVarSliderInt("Autosave Interval (minutes): %d", "gEnhancements.Saving.AutosaveInterval", 1, 60, 5, - { .disabled = !CVarGetInteger("gEnhancements.Saving.Autosave", 0) }); + SearchMenuGetItem(MENU_ITEM_PERSIST_OWL_SAVES); + SearchMenuGetItem(MENU_ITEM_PAUSE_MENU_SAVE); + SearchMenuGetItem(MENU_ITEM_AUTOSAVE); + SearchMenuGetItem(MENU_ITEM_AUTOSAVE_INTERVAL); ImGui::SeparatorText("Time Cycle"); - UIWidgets::CVarCheckbox("Do not reset Bottle content", "gEnhancements.Cycle.DoNotResetBottleContent", - { .tooltip = "Playing the Song Of Time will not reset the bottles' content." }); - UIWidgets::CVarCheckbox("Do not reset Consumables", "gEnhancements.Cycle.DoNotResetConsumables", - { .tooltip = "Playing the Song Of Time will not reset the consumables." }); - UIWidgets::CVarCheckbox("Do not reset Razor Sword", "gEnhancements.Cycle.DoNotResetRazorSword", - { .tooltip = "Playing the Song Of Time will not reset the Sword back to Kokiri Sword." }); - UIWidgets::CVarCheckbox("Do not reset Rupees", "gEnhancements.Cycle.DoNotResetRupees", - { .tooltip = "Playing the Song Of Time will not reset the your rupees." }); + SearchMenuGetItem(MENU_ITEM_DISABLE_BOTTLE_RESET); + SearchMenuGetItem(MENU_ITEM_DISABLE_CONSUMABLE_RESET); + SearchMenuGetItem(MENU_ITEM_DISABLE_RAZOR_SWORD_RESET); + SearchMenuGetItem(MENU_ITEM_DISABLE_RUPEE_RESET); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(255, 255, 0, 255)); ImGui::SeparatorText("Unstable"); ImGui::PopStyleColor(); - UIWidgets::CVarCheckbox( - "Disable Save Delay", "gEnhancements.Saving.DisableSaveDelay", - { .tooltip = "Removes the arbitrary 2 second timer for saving from the original game. This is known to " - "cause issues when attempting the 0th Day Glitch" }); + SearchMenuGetItem(MENU_ITEM_DISABLE_SAVE_DELAY); } // Graphics void DrawGraphicsEnhancements() { ImGui::SeparatorText("Clock"); - UIWidgets::CVarCombobox("Clock Type", "gEnhancements.Graphics.ClockType", clockTypeOptions); - UIWidgets::CVarCheckbox("24 Hours Clock", "gEnhancements.Graphics.24HoursClock"); - MotionBlur_RenderMenuOptions(); + SearchMenuGetItem(MENU_ITEM_CLOCK_OPTIONS); + SearchMenuGetItem(MENU_ITEM_MILITARY_CLOCK); + + ImGui::SeparatorText("Motion Blur"); + SearchMenuGetItem(MENU_ITEM_MOTION_BLUR_MODE); + SearchMenuGetItem(MENU_ITEM_MOTION_BLUE_INTERPOLATE); + if (CVarGetInteger("gEnhancements.Graphics.MotionBlur.Mode", 0) == 0) { + SearchMenuGetItem(MENU_ITEM_MOTION_BLUR_ENABLE); + } else if (CVarGetInteger("gEnhancements.Graphics.MotionBlur.Mode", 0) == 1) { + CVarSetInteger("gEnhancements.Graphics.MotionBlur.Toggle", 0); + } + if (CVarGetInteger("gEnhancements.Graphics.MotionBlur.Mode", 0) == 2 || + CVarGetInteger("gEnhancements.Graphics.MotionBlur.Toggle", 0) == 1) { + SearchMenuGetItem(MENU_ITEM_MOTION_BLUR_STRENGTH); + } + ImGui::SeparatorText("Other"); - UIWidgets::CVarCheckbox("Authentic logo", "gEnhancements.Graphics.AuthenticLogo", - { .tooltip = "Hide the game version and build details and display the authentic " - "model and texture on the boot logo start screen" }); - UIWidgets::CVarCheckbox("Bow Reticle", "gEnhancements.Graphics.BowReticle", - { .tooltip = "Gives the bow a reticle when you draw an arrow" }); - UIWidgets::CVarCheckbox("Disable Black Bar Letterboxes", "gEnhancements.Graphics.DisableBlackBars", - { .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" }); + SearchMenuGetItem(MENU_ITEM_AUTHENTIC_LOGO); + SearchMenuGetItem(MENU_ITEM_BOW_RETICLE); + SearchMenuGetItem(MENU_ITEM_DISABLE_BLACK_BARS); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(255, 255, 0, 255)); ImGui::SeparatorText("Unstable"); ImGui::PopStyleColor(); - UIWidgets::CVarCheckbox( - "Disable Scene Geometry Distance Check", "gEnhancements.Graphics.DisableSceneGeometryDistanceCheck", - { .tooltip = "Disables the distance check for scene geometry, allowing it to be drawn no matter how far " - "away it is from the player. This may have unintended side effects." }); + SearchMenuGetItem(MENU_ITEM_GEOMETRY_DISTANCE_CHECK); // BENTODO: Not implemented yet // UIWidgets::CVarCheckbox("Widescreen Actor Culling", // "gEnhancements.Graphics.ActorCullingAccountsForWidescreen", // { .tooltip = "Adjusts the culling planes to account for widescreen resolutions. " // "This may have unintended side effects." }); - if (UIWidgets::CVarSliderInt( - "Increase Actor Draw Distance: %dx", "gEnhancements.Graphics.IncreaseActorDrawDistance", 1, 5, 1, - { .tooltip = "Increase the range in which Actors are drawn. This may have unintended side effects." })) { - CVarSetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance", - MIN(CVarGetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance", 1), - CVarGetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance", 1))); - } - if (UIWidgets::CVarSliderInt( - "Increase Actor Update Distance: %dx", "gEnhancements.Graphics.IncreaseActorUpdateDistance", 1, 5, 1, - { .tooltip = "Increase the range in which Actors are updated. This may have unintended side effects." })) { - CVarSetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance", - MAX(CVarGetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance", 1), - CVarGetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance", 1))); - } -}; + + SearchMenuGetItem(MENU_ITEM_ACTOR_DRAW_DISTANCE); + SearchMenuGetItem(MENU_ITEM_ACTOR_UPDATE_DISTANCE); +} // Items/Songs void DrawItemEnhancements() { ImGui::SeparatorText("Masks"); - UIWidgets::CVarCheckbox("Blast Mask has Powder Keg Force", "gEnhancements.Masks.BlastMaskKeg"); - UIWidgets::CVarCheckbox("Fast Transformation", "gEnhancements.Masks.FastTransformation"); - UIWidgets::CVarCheckbox("Fierce Deity's Mask Anywhere", "gEnhancements.Masks.FierceDeitysAnywhere", - { .tooltip = "Allow using Fierce Deity's mask outside of boss rooms." }); - UIWidgets::CVarCheckbox("No Blast Mask Cooldown", "gEnhancements.Masks.NoBlastMaskCooldown", {}); + SearchMenuGetItem(MENU_ITEM_BLAST_MASK_KEG_FORCE); + SearchMenuGetItem(MENU_ITEM_FAST_TRANSFORMATION); + SearchMenuGetItem(MENU_ITEM_FIERCE_DEITY_ANYWHERE); + SearchMenuGetItem(MENU_ITEM_NO_BLAST_MASK_COOLDOWN); } void DrawSongEnhancements() { - UIWidgets::CVarCheckbox( - "Enable Sun's Song", "gEnhancements.Songs.EnableSunsSong", - { .tooltip = "Enables the partially implemented Sun's Song. RIGHT-DOWN-UP-RIGHT-DOWN-UP to play it. " - "This song will make time move very fast until either Link moves to a different scene, " - "or when the time switches to a new time period." }); - UIWidgets::CVarCheckbox("Dpad Ocarina", "gEnhancements.Playback.DpadOcarina", - { .tooltip = "Enables using the Dpad for Ocarina playback." }); - UIWidgets::CVarCheckbox("Prevent Dropped Ocarina Inputs", "gEnhancements.Playback.NoDropOcarinaInput", - { .tooltip = "Prevent dropping inputs when playing the ocarina quickly" }); + ImGui::SeparatorText("Items/Songs"); + SearchMenuGetItem(MENU_ITEM_ENABLE_SUNS_SONG); + SearchMenuGetItem(MENU_ITEM_DPAD_OCARINA); + SearchMenuGetItem(MENU_ITEM_PREVENT_DROPPED_OCARINA_INPUTS); } void DrawTimeSaverEnhancements1() { ImGui::SeparatorText("Cutscenes"); - UIWidgets::CVarCheckbox("Hide Title Cards", "gEnhancements.Cutscenes.HideTitleCards"); - UIWidgets::CVarCheckbox("Skip Entrance Cutscenes", "gEnhancements.Cutscenes.SkipEntranceCutscenes"); - UIWidgets::CVarCheckbox( - "Skip to File Select", "gEnhancements.Cutscenes.SkipToFileSelect", - { .tooltip = "Skip the opening title sequence and go straight to the file select menu after boot" }); - UIWidgets::CVarCheckbox( - "Skip Intro Sequence", "gEnhancements.Cutscenes.SkipIntroSequence", - { .tooltip = "When starting a game you will be taken straight to South Clock Town as Deku Link." }); - UIWidgets::CVarCheckbox( - "Skip Story Cutscenes", "gEnhancements.Cutscenes.SkipStoryCutscenes", - { .tooltip = "Disclaimer: This doesn't do much yet, we will be progressively adding more skips over time" }); - UIWidgets::CVarCheckbox( - "Skip Misc Interactions", "gEnhancements.Cutscenes.SkipMiscInteractions", - { .tooltip = "Disclaimer: This doesn't do much yet, we will be progressively adding more skips over time" }); + SearchMenuGetItem(MENU_ITEM_HIDE_TITLE_CARDS); + SearchMenuGetItem(MENU_ITEM_SKIP_ENTRANCE_CUTSCENES); + SearchMenuGetItem(MENU_ITEM_SKIP_TO_FILE_SELECT); + SearchMenuGetItem(MENU_ITEM_SKIP_INTRO_SEQUENCE); + SearchMenuGetItem(MENU_ITEM_SKIP_STORY_CUTSCENES); + SearchMenuGetItem(MENU_ITEM_SKIP_MISC_INTERACTIONS); } void DrawTimeSaverEnhancements2() { - UIWidgets::CVarCheckbox( - "Fast Bank Selection", "gEnhancements.Dialogue.FastBankSelection", - { .tooltip = "Pressing the Z or R buttons while the Deposit/Withdrawl Rupees dialogue is open will set " - "the Rupees to Links current Rupees or 0 respectively." }); - UIWidgets::CVarCheckbox( - "Fast Text", "gEnhancements.Dialogue.FastText", - { .tooltip = "Speeds up text rendering, and enables holding of B progress to next message" }); - UIWidgets::CVarCheckbox("Fast Magic Arrow Equip Animation", "gEnhancements.Equipment.MagicArrowEquipSpeed", - { .tooltip = "Removes the animation for equipping Magic Arrows." }); + ImGui::SeparatorText("Dialogue"); + SearchMenuGetItem(MENU_ITEM_FAST_BANK_SELECTION); + SearchMenuGetItem(MENU_ITEM_FAST_TEXT); + SearchMenuGetItem(MENU_ITEM_FAST_MAGIC_ARROW_ANIM); } void DrawFixEnhancements() { - UIWidgets::CVarCheckbox("Fix Ammo Count Color", "gFixes.FixAmmoCountEnvColor", - { .tooltip = "Fixes a missing gDPSetEnvColor, which causes the ammo count to be " - "the wrong color prior to obtaining magic or other conditions." }); - - UIWidgets::CVarCheckbox( - "Fix Hess and Weirdshot Crash", "gEnhancements.Fixes.HessCrash", - { .tooltip = "Fixes a crash that can occur when performing a HESS or Weirdshot.", .defaultValue = true }); - - UIWidgets::CVarCheckbox("Fix Text Control Characters", "gEnhancements.Fixes.ControlCharacters", - { .tooltip = "Fixes certain control characters not functioning properly " - "depending on their position within the text." }); + ImGui::SeparatorText("Fixes"); + SearchMenuGetItem(MENU_ITEM_FIX_AMMO_COUNT_COLOR); + SearchMenuGetItem(MENU_ITEM_FIX_HESS_WEIRDSHOT); + SearchMenuGetItem(MENU_ITEM_FIX_TEXT_CONTROL_CHAR); } void DrawRestorationEnhancements() { - UIWidgets::CVarCheckbox("Constant Distance Backflips and Sidehops", "gEnhancements.Restorations.ConstantFlipsHops", - { .tooltip = "Backflips and Sidehops travel a constant distance as they did in OOT." }); - UIWidgets::CVarCheckbox( - "Power Crouch Stab", "gEnhancements.Restorations.PowerCrouchStab", - { .tooltip = "Crouch stabs will use the power of Link's previous melee attack, as is in MM JP 1.0 and OOT." }); - UIWidgets::CVarCheckbox("Side Rolls", "gEnhancements.Restorations.SideRoll", - { .tooltip = "Restores side rolling from OOT." }); - UIWidgets::CVarCheckbox("Tatl ISG", "gEnhancements.Restorations.TatlISG", - { .tooltip = "Restores Navi ISG from OOT, but now with Tatl." }); + ImGui::SeparatorText("Restorations"); + SearchMenuGetItem(MENU_ITEM_RESTORE_DISTANCE_FLIPS_HOPS); + SearchMenuGetItem(MENU_ITEM_RESTORE_POWER_CROUCH_STAB); + SearchMenuGetItem(MENU_ITEM_RESTORE_SIDEROLLS); + SearchMenuGetItem(MENU_ITEM_RESTORE_TATL_ISG); } void DrawHudEditorContents() { + // SearchMenuGetItem(MENU_ITEM_HUD_EDITOR); UIWidgets::WindowButton("Popout Hud Editor", "gWindows.HudEditor", mHudEditorWindow, { .tooltip = "Enables the Hud Editor window, allowing you to edit your hud" }); if (!CVarGetInteger("gWindows.HudEditor", 0)) { @@ -536,92 +350,41 @@ void DrawHudEditorContents() { void DrawGeneralDevTools() { // PortNote: This should be hidden for ports on systems that are single-screen, and/or smaller than 1280x800. // Popout will assume size of 1280x800, and will break on those systems. - UIWidgets::CVarCheckbox("Popout Menu", "gSettings.Menu.Popout", - { .tooltip = "Changes the menu display from overlay to windowed." }); - if (UIWidgets::Button("Open App Files Folder", - { .tooltip = "Opens the folder that contains the save and mods folders, etc." })) { - std::string filesPath = Ship::Context::GetInstance()->GetAppDirectoryPath(); - SDL_OpenURL(std::string("file:///" + std::filesystem::absolute(filesPath).string()).c_str()); - } - if (UIWidgets::CVarCheckbox("Debug Mode", "gDeveloperTools.DebugEnabled", - { .tooltip = "Enables Debug Mode, allowing you to select maps with L + R + Z." })) { - // If disabling debug mode, disable all debug features - if (!CVarGetInteger("gDeveloperTools.DebugEnabled", 0)) { - CVarClear("gDeveloperTools.DebugSaveFileMode"); - CVarClear("gDeveloperTools.PreventActorUpdate"); - CVarClear("gDeveloperTools.PreventActorDraw"); - CVarClear("gDeveloperTools.PreventActorInit"); - CVarClear("gDeveloperTools.DisableObjectDependency"); - if (gPlayState != NULL) { - gPlayState->frameAdvCtx.enabled = false; - } - RegisterDebugSaveCreate(); - RegisterPreventActorUpdateHooks(); - RegisterPreventActorDrawHooks(); - RegisterPreventActorInitHooks(); - } - }; + SearchMenuGetItem(MENU_ITEM_MODERN_MENU_POPOUT); + SearchMenuGetItem(MENU_ITEM_OPEN_APP_FILES); + SearchMenuGetItem(MENU_ITEM_DEBUG_MODE_ENABLE); if (CVarGetInteger("gDeveloperTools.DebugEnabled", 0)) { - UIWidgets::CVarCheckbox( - "Better Map Select", "gDeveloperTools.BetterMapSelect.Enabled", - { .tooltip = "Overrides the original map select with a translated, more user-friendly version." }); - - if (UIWidgets::CVarCombobox( - "Debug Save File Mode", "gDeveloperTools.DebugSaveFileMode", debugSaveOptions, - { .tooltip = - "Change the behavior of creating saves while debug mode is enabled:\n\n" - "- Empty Save: The default 3 heart save file in first cycle\n" - "- Vanilla Debug Save: Uses the title screen save info (8 hearts, all items and masks)\n" - "- 100\% Save: All items, equipment, mask, quast status and bombers notebook complete" })) { - RegisterDebugSaveCreate(); - } + SearchMenuGetItem(MENU_ITEM_DEBUG_BETTER_MAP_SELECT); + SearchMenuGetItem(MENU_ITEM_DEBUG_SAVE_FILE_MODE); } - if (UIWidgets::CVarCheckbox("Prevent Actor Update", "gDeveloperTools.PreventActorUpdate")) { - RegisterPreventActorUpdateHooks(); - } - if (UIWidgets::CVarCheckbox("Prevent Actor Draw", "gDeveloperTools.PreventActorDraw")) { - RegisterPreventActorDrawHooks(); - } - if (UIWidgets::CVarCheckbox("Prevent Actor Init", "gDeveloperTools.PreventActorInit")) { - RegisterPreventActorInitHooks(); - } - UIWidgets::CVarCheckbox("Disable Object Dependency", "gDeveloperTools.DisableObjectDependency"); - if (UIWidgets::CVarCombobox("Log Level", "gDeveloperTools.LogLevel", logLevels, - { - .tooltip = "The log level determines which messages are printed to the " - "console. This does not affect the log file output", - .defaultIndex = 1, - })) { - Ship::Context::GetInstance()->GetLogger()->set_level( - (spdlog::level::level_enum)CVarGetInteger("gDeveloperTools.LogLevel", 1)); - } + SearchMenuGetItem(MENU_ITEM_PREVENT_ACTOR_UPDATE); + SearchMenuGetItem(MENU_ITEM_PREVENT_ACTOR_DRAW); + SearchMenuGetItem(MENU_ITEM_PREVENT_ACTOR_INIT); + SearchMenuGetItem(MENU_ITEM_DISABLE_OBJECT_DEPENDECY); + SearchMenuGetItem(MENU_ITEM_DEBUG_LOG_LEVEL); if (gPlayState != NULL) { ImGui::Separator(); - UIWidgets::Checkbox( - "Frame Advance", (bool*)&gPlayState->frameAdvCtx.enabled, - { .tooltip = "This allows you to advance through the game one frame at a time on command. " - "To advance a frame, hold Z and tap R on the second controller. Holding Z " - "and R will advance a frame every half second. You can also use the buttons below." }); + SearchMenuGetItem(MENU_ITEM_FRAME_ADVANCE_ENABLE); if (gPlayState->frameAdvCtx.enabled) { - if (UIWidgets::Button("Advance 1", { .size = UIWidgets::Sizes::Inline })) { - CVarSetInteger("gDeveloperTools.FrameAdvanceTick", 1); - } - ImGui::SameLine(); - UIWidgets::Button("Advance (Hold)", { .size = UIWidgets::Sizes::Inline }); + SearchMenuGetItem(MENU_ITEM_FRAME_ADVANCE_SINGLE); + SearchMenuGetItem(MENU_ITEM_FRAME_ADVANCE_HOLD); if (ImGui::IsItemActive()) { CVarSetInteger("gDeveloperTools.FrameAdvanceTick", 1); } } } + ImGui::PushStyleColor(ImGuiCol_Button, menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)]); RenderWarpPointSection(); + ImGui::PopStyleColor(1); } void DrawCollisionViewerContents() { - UIWidgets::WindowButton("Popout Collision Viewer", "gWindows.CollisionViewer", mCollisionViewerWindow, - { .tooltip = "Draws collision to the screen" }); + UIWidgets::WindowButton( + "Popout Collision Viewer", "gWindows.CollisionViewer", mCollisionViewerWindow, + { .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], .tooltip = "Draws collision to the screen" }); if (!CVarGetInteger("gWindows.CollisionViewer", 0)) { mCollisionViewerWindow->DrawElement(); } @@ -630,7 +393,8 @@ void DrawCollisionViewerContents() { void DrawStatsContents() { UIWidgets::WindowButton( "Popout Stats", "gOpenWindows.Stats", mStatsWindow, - { .tooltip = "Shows the stats window, with your FPS and frametimes, and the OS you're playing on" }); + { .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + .tooltip = "Shows the stats window, with your FPS and frametimes, and the OS you're playing on" }); if (!CVarGetInteger("gOpenWindows.Stats", 0)) { mStatsWindow->DrawElement(); } @@ -639,7 +403,8 @@ void DrawStatsContents() { void DrawConsoleContents() { UIWidgets::WindowButton( "Popout Console", "gOpenWindows.Console", mConsoleWindow, - { .tooltip = "Enables the console window, allowing you to input commands, type help for some examples" }); + { .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + .tooltip = "Enables the console window, allowing you to input commands, type help for some examples" }); if (!CVarGetInteger("gOpenWindows.Console", 0)) { mConsoleWindow->DrawElement(); } @@ -648,7 +413,8 @@ void DrawConsoleContents() { void DrawGfxDebuggerContents() { UIWidgets::WindowButton( "Popout Gfx Debugger", "gOpenWindows.GfxDebugger", mGfxDebuggerWindow, - { .tooltip = "Enables the Gfx Debugger window, allowing you to input commands, type help for some examples" }); + { .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + .tooltip = "Enables the Gfx Debugger window, allowing you to input commands, type help for some examples" }); if (!CVarGetInteger("gOpenWindows.GfxDebugger", 0)) { mGfxDebuggerWindow->DrawElement(); } @@ -656,7 +422,8 @@ void DrawGfxDebuggerContents() { void DrawSaveEditorContents() { UIWidgets::WindowButton("Popout Save Editor", "gWindows.SaveEditor", mSaveEditorWindow, - { .tooltip = "Enables the Save Editor window, allowing you to edit your save file" }); + { .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + .tooltip = "Enables the Save Editor window, allowing you to edit your save file" }); if (!CVarGetInteger("gWindows.SaveEditor", 0)) { mSaveEditorWindow->DrawElement(); } @@ -665,14 +432,18 @@ void DrawSaveEditorContents() { void DrawActorViewerContents() { UIWidgets::WindowButton( "Popout Actor Viewer", "gWindows.ActorViewer", mActorViewerWindow, - { .tooltip = "Enables the Actor Viewer window, allowing you to view actors in the world." }); + { .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + .tooltip = "Enables the Actor Viewer window, allowing you to view actors in the world." }); if (!CVarGetInteger("gWindows.ActorViewer", 0)) { mActorViewerWindow->DrawElement(); } } void DrawEventLogContents() { - UIWidgets::WindowButton("Popout Event Log", "gWindows.EventLog", mEventLogWindow); + UIWidgets::WindowButton("Popout Event Log", "gWindows.EventLog", mEventLogWindow, + { + .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + }); if (!CVarGetInteger("gWindows.EventLog", 0)) { mActorViewerWindow->DrawElement(); } @@ -689,7 +460,8 @@ void BenMenu::InitElement() { poppedSize.y = CVarGetInteger("gSettings.Menu.PoppedHeight", 800); poppedPos.x = CVarGetInteger("gSettings.Menu.PoppedPos.x", 0); poppedPos.y = CVarGetInteger("gSettings.Menu.PoppedPos.y", 0); - std::vector settingsSidebar = { { "General", { DrawGeneralSettings, nullptr, nullptr } }, + std::vector settingsSidebar = { { "Search", { DrawSearchSettings, nullptr, nullptr } }, + { "General", { DrawGeneralSettings, nullptr, nullptr } }, { "Audio", { DrawAudioSettings, nullptr, nullptr } }, { "Graphics", { DrawGraphicsSettings, nullptr, nullptr } }, { "Controls", { DrawControllerSettings } } }; @@ -784,6 +556,8 @@ void BenMenu::Draw() { } void BenMenu::DrawElement() { + SearchMenuUpdateDisabled(); + windowHeight = ImGui::GetMainViewport()->WorkSize.y; windowWidth = ImGui::GetMainViewport()->WorkSize.x; auto windowFlags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings; diff --git a/mm/2s2h/search/SearchMenu.h b/mm/2s2h/search/SearchMenu.h new file mode 100644 index 0000000000..2a2dc1c2e0 --- /dev/null +++ b/mm/2s2h/search/SearchMenu.h @@ -0,0 +1,1214 @@ +#include "2s2h/Enhancements/Enhancements.h" + +extern "C" { +#include "functions.h" +extern PlayState* gPlayState; +} + +using WidgetFunc = void (*)(); +std::string disabledTempTooltip; +const char* disabledTooltip; +bool disabledValue = false; + +std::vector menuTheme = { + ImVec4(1.0f, 1.0f, 1.0f, 1.0f), ImVec4(0.4f, 0.4f, 0.4f, 1.0f), ImVec4(0.1f, 0.1f, 0.1f, 1.0f), + ImVec4(0.24f, 0.31f, 0.71f, 1.0f), ImVec4(0.5f, 0.0f, 0.0f, 1.0f), ImVec4(0.3f, 0.0f, 0.0f, 1.0f), + ImVec4(0.0f, 0.7f, 0.0f, 1.0f), ImVec4(0.0f, 0.5f, 0.0f, 1.0f), ImVec4(0.0f, 0.3f, 0.0f, 1.0f), + ImVec4(1.0f, 0.627f, 0.0f, 1.0f), +}; + +typedef enum { + COLOR_WHITE, + COLOR_GRAY, + COLOR_DARK_GRAY, + COLOR_INDIGO, + COLOR_RED, + COLOR_DARK_RED, + COLOR_LIGHT_GREEN, + COLOR_GREEN, + COLOR_DARK_GREEN, + COLOR_YELLOW, +} colorOptions; + +typedef enum { + CHECKBOX, + COMBOBOX, + SLIDER_INT, + SLIDER_FLOAT, + BUTTON, +}; + +typedef enum { + MOTION_BLUR_DYNAMIC, + MOTION_BLUR_ALWAYS_OFF, + MOTION_BLUR_ALWAYS_ON, +}; + +typedef enum { + DEBUG_LOG_TRACE, + DEBUG_LOG_DEBUG, + DEBUG_LOG_INFO, + DEBUG_LOG_WARN, + DEBUG_LOG_ERROR, + DEBUG_LOG_CRITICAL, + DEBUG_LOG_OFF, +}; + +struct widgetOptions { + int32_t min; + int32_t max; + int32_t defaultValue; + std::unordered_map comboBoxOptions; +}; + +struct cvarObject { + uint32_t cVarIndex; + const char* cVarText; + const char* cVarName; + const char* cVarTooltip; + uint32_t widgetType; + widgetOptions cVarOptions; + WidgetFunc cVarFunction; + std::vector disabledName; +}; + +std::unordered_map menuThemeOptions = { + { COLOR_WHITE, "White" }, + { COLOR_GRAY, "Gray" }, + { COLOR_DARK_GRAY, "Dark Gray" }, + { COLOR_INDIGO, "Indigo" }, + { COLOR_RED, "Red" }, + { COLOR_DARK_RED, "Dark Red" }, + { COLOR_LIGHT_GREEN, "Light Green" }, + { COLOR_GREEN, "Green" }, + { COLOR_DARK_GREEN, "Dark Green" }, + { COLOR_YELLOW, "Yellow" }, +}; + +static const std::unordered_map alwaysWinDoggyraceOptions = { + { ALWAYS_WIN_DOGGY_RACE_OFF, "Off" }, + { ALWAYS_WIN_DOGGY_RACE_MASKOFTRUTH, "When owning Mask of Truth" }, + { ALWAYS_WIN_DOGGY_RACE_ALWAYS, "Always" }, +}; + +static const std::unordered_map clockTypeOptions = { + { CLOCK_TYPE_ORIGINAL, "Original" }, + { CLOCK_TYPE_TEXT_BASED, "Text only" }, +}; + +static const std::unordered_map textureFilteringMap = { + { FILTER_THREE_POINT, "Three-Point" }, + { FILTER_LINEAR, "Linear" }, + { FILTER_NONE, "None" }, +}; + + +static const std::unordered_map motionBlurOptions = { + { MOTION_BLUR_DYNAMIC, "Dynamic (default)" }, + { MOTION_BLUR_ALWAYS_OFF, "Always Off" }, + { MOTION_BLUR_ALWAYS_ON, "Always On" }, +}; + +static const std::unordered_map debugSaveOptions = { + { DEBUG_SAVE_INFO_COMPLETE, "100\% save" }, + { DEBUG_SAVE_INFO_VANILLA_DEBUG, "Vanilla debug save" }, + { DEBUG_SAVE_INFO_NONE, "Empty save" }, +}; + + +static const std::unordered_map logLevels = { + { DEBUG_LOG_TRACE, "Trace" }, { DEBUG_LOG_DEBUG, "Debug" }, { DEBUG_LOG_INFO, "Info" }, + { DEBUG_LOG_WARN, "Warn" }, { DEBUG_LOG_ERROR, "Error" }, { DEBUG_LOG_CRITICAL, "Critical" }, + { DEBUG_LOG_OFF, "Off" }, +}; + +std::unordered_map disabledMap = { + { "Debug Camera is Enabled", false }, + { "Free Look is Enabled", false }, + { "AutoSave is Disabled", false }, +}; + +typedef enum { + MENU_ITEM_MENU_THEME, + MENU_ITEM_MENUBAR_CONTROLLER_NAV, + MENU_ITEM_CURSOR_VISIBILITY, + MENU_ITEM_HOTKEY_TEXT, + MENU_ITEM_MASTER_VOLUME, + MENU_ITEM_MAIN_MUSIC_VOLUME, + MENU_ITEM_SUB_MUSIC_VOLUME, + MENU_ITEM_SOUND_EFFECT_VOLUME, + MENU_ITEM_FANFARE_VOLUME, + MENU_ITEM_AMBIENT_VOLUME, + // MENU_ITEM_AUDIO_BACKEND, (Unused placeholder) + MENU_ITEM_TOGGLE_FULLSCREEN, + MENU_ITEM_INTERNAL_RESOLUTION, + MENU_ITEM_MSAA, + MENU_ITEM_FRAME_RATE, + MENU_ITEM_MATCH_REFRESH_RATE, + MENU_ITEM_JITTER_FIX, + // MENU_ITEM_RENDERER_API, (Unused placeholder) + MENU_ITEM_ENABLE_VSYNC, + MENU_ITEM_ENABLE_WINDOWED_FULLSCREEN, + MENU_ITEM_ENABLE_MULTI_VIEWPORT, + MENU_ITEM_TEXTURE_FILTER, + MENU_ITEM_INPUT_EDITOR, + MENU_ITEM_FIX_TARGET_CAMERA_SNAP, + MENU_ITEM_ENABLE_FREE_LOOK, + MENU_ITEM_FREE_LOOK_CAMERA_DISTANCE, + MENU_ITEM_FREE_LOOK_TRANSITION_SPEED, + MENU_ITEM_FREE_LOOK_MAX_PITCH, + MENU_ITEM_FREE_LOOK_MIN_PITCH, + MENU_ITEM_ENABLE_DEBUG_CAMERA, + MENU_ITEM_INVERT_CAMERA_X_AXIS, + MENU_ITEM_INVERT_CAMERA_Y_AXIS, + MENU_ITEM_THIRD_PERSON_CAMERA_X_SENSITIVITY, + MENU_ITEM_THIRD_PERSON_CAMERA_Y_SENSITIVITY, + MENU_ITEM_ENABLE_CAMERA_ROLL, + MENU_ITEM_CAMERA_SPEED, + MENU_ITEM_CHEATS_INFINITE_HEALTH, + MENU_ITEM_CHEATS_INFINITE_MAGIC, + MENU_ITEM_CHEATS_INFINITE_RUPEES, + MENU_ITEM_CHEATS_INFINITE_CONSUMABLES, + MENU_ITEM_CHEATS_LONG_FLOWER_GLIDE, + MENU_ITEM_CHEATS_NO_CLIP, + MENU_ITEM_CHEATS_INFINITE_RAZOR_SWORD, + MENU_ITEM_CHEATS_UNRESTRICTED_ITEMS, + MENU_ITEM_CHEATS_MOON_JUMP_ON_L, + MENU_ITEM_FAST_FLOWER_LAUNCH, + MENU_ITEM_INSTANT_PUTAWAY, + MENU_ITEM_CLIMB_SPEED, + MENU_ITEM_DPAD_EQUIPS, + MENU_ITEM_ALWAYS_WIN_DOGGY_RACE, + MENU_ITEM_PLAY_AS_KAFEI, + MENU_ITEM_TIME_MOVES_WHEN_YOU_MOVE, + MENU_ITEM_PERSIST_OWL_SAVES, + MENU_ITEM_PAUSE_MENU_SAVE, + MENU_ITEM_AUTOSAVE, + MENU_ITEM_AUTOSAVE_INTERVAL, + MENU_ITEM_DISABLE_BOTTLE_RESET, + MENU_ITEM_DISABLE_CONSUMABLE_RESET, + MENU_ITEM_DISABLE_RAZOR_SWORD_RESET, + MENU_ITEM_DISABLE_RUPEE_RESET, + MENU_ITEM_DISABLE_SAVE_DELAY, + MENU_ITEM_CLOCK_OPTIONS, + MENU_ITEM_MILITARY_CLOCK, + MENU_ITEM_MOTION_BLUR_MODE, + MENU_ITEM_MOTION_BLUE_INTERPOLATE, + MENU_ITEM_MOTION_BLUR_ENABLE, + MENU_ITEM_MOTION_BLUR_STRENGTH, + MENU_ITEM_AUTHENTIC_LOGO, + MENU_ITEM_BOW_RETICLE, + MENU_ITEM_DISABLE_BLACK_BARS, + MENU_ITEM_GEOMETRY_DISTANCE_CHECK, + MENU_ITEM_ACTOR_DRAW_DISTANCE, + MENU_ITEM_ACTOR_UPDATE_DISTANCE, + MENU_ITEM_BLAST_MASK_KEG_FORCE, + MENU_ITEM_FAST_TRANSFORMATION, + MENU_ITEM_FIERCE_DEITY_ANYWHERE, + MENU_ITEM_NO_BLAST_MASK_COOLDOWN, + MENU_ITEM_ENABLE_SUNS_SONG, + MENU_ITEM_DPAD_OCARINA, + MENU_ITEM_PREVENT_DROPPED_OCARINA_INPUTS, + MENU_ITEM_HIDE_TITLE_CARDS, + MENU_ITEM_SKIP_ENTRANCE_CUTSCENES, + MENU_ITEM_SKIP_TO_FILE_SELECT, + MENU_ITEM_SKIP_INTRO_SEQUENCE, + MENU_ITEM_SKIP_STORY_CUTSCENES, + MENU_ITEM_SKIP_MISC_INTERACTIONS, + MENU_ITEM_FAST_BANK_SELECTION, + MENU_ITEM_FAST_TEXT, + MENU_ITEM_FAST_MAGIC_ARROW_ANIM, + MENU_ITEM_FIX_AMMO_COUNT_COLOR, + MENU_ITEM_FIX_HESS_WEIRDSHOT, + MENU_ITEM_FIX_TEXT_CONTROL_CHAR, + MENU_ITEM_RESTORE_DISTANCE_FLIPS_HOPS, + MENU_ITEM_RESTORE_POWER_CROUCH_STAB, + MENU_ITEM_RESTORE_SIDEROLLS, + MENU_ITEM_RESTORE_TATL_ISG, + // MENU_ITEM_HUD_EDITOR, Unused placeholder + MENU_ITEM_MODERN_MENU_POPOUT, + MENU_ITEM_OPEN_APP_FILES, + MENU_ITEM_DEBUG_MODE_ENABLE, + MENU_ITEM_DEBUG_BETTER_MAP_SELECT, + MENU_ITEM_DEBUG_SAVE_FILE_MODE, + MENU_ITEM_PREVENT_ACTOR_UPDATE, + MENU_ITEM_PREVENT_ACTOR_DRAW, + MENU_ITEM_PREVENT_ACTOR_INIT, + MENU_ITEM_DISABLE_OBJECT_DEPENDECY, + MENU_ITEM_DEBUG_LOG_LEVEL, + MENU_ITEM_FRAME_ADVANCE_ENABLE, + MENU_ITEM_FRAME_ADVANCE_SINGLE, + MENU_ITEM_FRAME_ADVANCE_HOLD, +}; + +cvarObject enhancementList[] = { + // Menu Theme + { MENU_ITEM_MENU_THEME, + "Menu Theme", + "gSettings.MenuTheme", + "Changes the Theme of the Menu Widgets.", + COMBOBOX, + { 0, 0, 0, menuThemeOptions }, + nullptr }, + // General Settings + { MENU_ITEM_MENUBAR_CONTROLLER_NAV, + "Menubar Controller Navigation", + CVAR_IMGUI_CONTROLLER_NAV, + "Allows controller navigation of the SOH menu bar (Settings, Enhancements,...)\nCAUTION: " + "This will disable game inputs while the menubar is visible.\n\nD-pad to move between " + "items, A to select, and X to grab focus on the menu bar", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_CURSOR_VISIBILITY, + "Cursor Always Visible", + "gSettings.CursorVisibility", + "Makes the cursor always visible, even in full screen.", + CHECKBOX, + {}, + ([]() { + Ship::Context::GetInstance()->GetWindow()->SetForceCursorVisibility( + CVarGetInteger("gSettings.CursorVisibility", 0)); + }) }, + { MENU_ITEM_HOTKEY_TEXT, + "Hide Menu Hotkey Text", + "gSettings.DisableMenuShortcutNotify", + "Prevents showing the text telling you the shortcut to open the menu\n" + "when the menu isn't open.", + CHECKBOX, + {}, + nullptr }, + // Audio Settings + { MENU_ITEM_MASTER_VOLUME, + "Master Volume: %.2f%%", + "gSettings.Audio.MasterVolume", + "Adjust overall sound volume.", + SLIDER_FLOAT, + { 0, 100, 100 }, + nullptr }, + { MENU_ITEM_MAIN_MUSIC_VOLUME, + "Main Music Volume: %.2f%%", + "gSettings.Audio.MainMusicVolume", + "Adjust the Background Music volume.", + SLIDER_FLOAT, + { 0, 100, 100 }, + ([]() { + AudioSeq_SetPortVolumeScale(SEQ_PLAYER_BGM_MAIN, CVarGetFloat("gSettings.Audio.MainMusicVolume", 1.0f)); + }) }, + { MENU_ITEM_SUB_MUSIC_VOLUME, + "Sub Music Volume: %.2f%%", + "gSettings.Audio.SubMusicVolume", + "Adjust the Sub Music volume.", + SLIDER_FLOAT, + { 0, 100, 100 }, + ([]() { + AudioSeq_SetPortVolumeScale(SEQ_PLAYER_BGM_SUB, CVarGetFloat("gSettings.Audio.SubMusicVolume", 1.0f)); + }) }, + { MENU_ITEM_SOUND_EFFECT_VOLUME, + "Sound Effects Volume: %.2f%%", + "gSettings.Audio.SoundEffectsVolume", + "Adjust the Sound Effects volume.", + SLIDER_FLOAT, + { 0, 100, 100 }, + ([]() { + AudioSeq_SetPortVolumeScale(SEQ_PLAYER_SFX, CVarGetFloat("gSettings.Audio.SoundEffectsVolume", 1.0f)); + }) }, + { MENU_ITEM_FANFARE_VOLUME, + "Fanfare Volume: %.2f%%", + "gSettings.Audio.FanfareVolume", + "Adjust the Fanfare volume.", + SLIDER_FLOAT, + { 0, 100, 100 }, + ([]() { + AudioSeq_SetPortVolumeScale(SEQ_PLAYER_FANFARE, CVarGetFloat("gSettings.Audio.FanfareVolume", 1.0f)); + }) }, + { MENU_ITEM_AMBIENT_VOLUME, + "Ambience Volume: %.2f%%", + "gSettings.Audio.AmbienceVolume", + "Adjust the Ambient Sound volume.", + SLIDER_FLOAT, + { 0, 100, 100 }, + ([]() { + AudioSeq_SetPortVolumeScale(SEQ_PLAYER_AMBIENCE, CVarGetFloat("gSettings.Audio.AmbienceVolume", 1.0f)); + }) }, + //{ MENU_ITEM_AUDIO_BACKEND }, Unused placeholder + // Graphics Settings + { MENU_ITEM_TOGGLE_FULLSCREEN, + "Toggle Fullscreen", + "gSettings.Fullscreen", + "Toggles Fullscreen On/Off.", + CHECKBOX, + {}, + ([]() { Ship::Context::GetInstance()->GetWindow()->ToggleFullscreen(); }) }, + { MENU_ITEM_INTERNAL_RESOLUTION, + "Internal Resolution: %f%%", + CVAR_INTERNAL_RESOLUTION, + "Multiplies your output resolution by the value inputted, as a more intensive but effective " + "form of anti-aliasing.", + SLIDER_FLOAT, + { 50, 200, 100 }, + ([]() { + Ship::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(CVarGetFloat(CVAR_INTERNAL_RESOLUTION, 1)); + }) }, + { MENU_ITEM_MSAA, + "Anti-aliasing (MSAA): %d", + CVAR_MSAA_VALUE, + "Activates MSAA (multi-sample anti-aliasing) from 2x up to 8x, to smooth the edges of rendered " + "geometry.\n" + "Higher sample count will result in smoother edges on models, but may reduce performance.", + SLIDER_INT, + { 1, 8, 1 }, + ([]() { Ship::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger(CVAR_MSAA_VALUE, 1)); }) }, + { MENU_ITEM_FRAME_RATE, + "Current FPS: %d", + "gInterpolationFPS", + "Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is " + "purely visual and does not impact game logic, execution of glitches etc.\n\n A higher target " + "FPS than your monitor's refresh rate will waste resources, and might give a worse result.", + SLIDER_INT, + { 20, 360, 20 }, + nullptr }, + { MENU_ITEM_MATCH_REFRESH_RATE, + "Match Refresh Rate", + "", + "Matches interpolation value to the current game's window refresh rate.", + BUTTON, + { }, + ([]() { + int hz = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); + if (hz >= 20 && hz <= 360) { + CVarSetInteger("gInterpolationFPS", hz); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + } + }) }, + { MENU_ITEM_JITTER_FIX, + "Jitter fix : >= % d FPS", + "gExtraLatencyThreshold", + "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.", + SLIDER_INT, + { 0, 360, 80 }, + nullptr }, + //{ MENU_ITEM_RENDERER_API }, Unused placeholder + { MENU_ITEM_ENABLE_VSYNC, "Enable Vsync", CVAR_VSYNC_ENABLED, "Enables Vsync.", CHECKBOX, {}, nullptr }, + { MENU_ITEM_ENABLE_WINDOWED_FULLSCREEN, + "Windowed Fullscreen", + CVAR_SDL_WINDOWED_FULLSCREEN, + "Enables Windowed Fullscreen Mode.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_ENABLE_MULTI_VIEWPORT, + "Allow multi-windows", + CVAR_ENABLE_MULTI_VIEWPORTS, + "Allows multiple windows to be opened at once. Requires a reload to take effect.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_TEXTURE_FILTER, + "Texture Filter (Needs reload)", + CVAR_TEXTURE_FILTER, + "Sets the applied Texture Filtering.", + COMBOBOX, + { 0, 0, 0, textureFilteringMap }, + nullptr }, + // Input Editor + { MENU_ITEM_INPUT_EDITOR, + "Popout Input Editor", + "gWindows.BenInputEditor", + "Enables the separate Input Editor window.", + BUTTON, + {}, + nullptr }, + // Camera Snap Fix + { MENU_ITEM_FIX_TARGET_CAMERA_SNAP, + "Fix Targetting Camera Snap", + "gEnhancements.Camera.FixTargettingCameraSnap", + "Fixes the camera snap that occurs when you are moving and press the targetting button.", + CHECKBOX, + {}, + nullptr }, + // Free Look Settings + { MENU_ITEM_ENABLE_FREE_LOOK, + "Free Look", + "gEnhancements.Camera.FreeLook.Enable", + "Enables free look 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.", + CHECKBOX, + {}, + ([]() { RegisterCameraFreeLook(); }), { "Debug Camera is Enabled" } }, + { MENU_ITEM_FREE_LOOK_CAMERA_DISTANCE, + "Camera Distance: %d", + "gEnhancements.Camera.FreeLook.MaxCameraDistance", + "Maximum Camera Distance for Free Look.", + SLIDER_INT, + { 100, 900, 185 }, + nullptr }, + { MENU_ITEM_FREE_LOOK_TRANSITION_SPEED, + "Camera Transition Speed: %d", + "gEnhancements.Camera.FreeLook.TransitionSpeed", + "Can someone help me?", + SLIDER_INT, + { 1, 900, 25 }, + nullptr }, + { MENU_ITEM_FREE_LOOK_MAX_PITCH, + "Max Camera Height Angle: %.0f\xC2\xB0", + "gEnhancements.Camera.FreeLook.MaxPitch", + "Maximum Height of the Camera.", + SLIDER_FLOAT, + { -8900, 8900, 7200 }, + nullptr }, + { MENU_ITEM_FREE_LOOK_MIN_PITCH, + "Min Camera Height Angle: %.0f\xC2\xB0", + "gEnhancements.Camera.FreeLook.MinPitch", + "Minimum Height of the Camera.", + SLIDER_FLOAT, + { -8900, 8900, -4900 }, + nullptr }, + // Camera Enhancements + { MENU_ITEM_ENABLE_DEBUG_CAMERA, + "Debug Camera", + "gEnhancements.Camera.DebugCam.Enable", + "Enables free camera control.", + CHECKBOX, + {}, + ([]() { RegisterDebugCam(); }), { "Free Look is Enabled" } }, + { MENU_ITEM_INVERT_CAMERA_X_AXIS, + "Invert Camera X Axis", + "gEnhancements.Camera.RightStick.InvertXAxis", + "Inverts the Camera X Axis", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_INVERT_CAMERA_Y_AXIS, + "Invert Camera Y Axis", + "gEnhancements.Camera.RightStick.InvertYAxis", + "Inverts the Camera Y Axis", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_THIRD_PERSON_CAMERA_X_SENSITIVITY, + "Third-Person Horizontal Sensitivity: %.0f", + "gEnhancements.Camera.RightStick.CameraSensitivity.X", + "Adjust the Sensitivity of the x axis when in Third Person.", + SLIDER_FLOAT, + { 1, 500, 100 }, + nullptr }, + { MENU_ITEM_THIRD_PERSON_CAMERA_Y_SENSITIVITY, + "Third-Person Vertical Sensitivity: %.0f", + "gEnhancements.Camera.RightStick.CameraSensitivity.Y", + "Adjust the Sensitivity of the x axis when in Third Person.", + SLIDER_FLOAT, + { 1, 500, 100 }, + nullptr }, + { MENU_ITEM_ENABLE_CAMERA_ROLL, + "Enable Roll (6\xC2\xB0 of Freedom)", + "gEnhancements.Camera.DebugCam.6DOF", + "This allows for all six degrees of movement with the camera, NOTE: Yaw will work " + "differently in this system, instead rotating around the focal point" + ", rather than a polar axis.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_CAMERA_SPEED, + "Camera Speed: %.0f", + "gEnhancements.Camera.DebugCam.CameraSpeed", + "Adjusts the speed of the Camera.", + SLIDER_FLOAT, + { 10, 300, 50 }, + nullptr }, + // Cheats + { MENU_ITEM_CHEATS_INFINITE_HEALTH, + "Infinite Health", + "gCheats.InfiniteHealth", + "Always have full Hearts.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_CHEATS_INFINITE_MAGIC, + "Infinite Magic", + "gCheats.InfiniteMagic", + "Always have full Magic.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_CHEATS_INFINITE_RUPEES, + "Infinite Rupees", + "gCheats.InfiniteRupees", + "Always have a full Wallet.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_CHEATS_INFINITE_CONSUMABLES, + "Infinite Consumables", + "gCheats.InfiniteConsumables", + "Always have max Consumables, you must have collected the consumables first.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_CHEATS_LONG_FLOWER_GLIDE, + "Longer Deku Flower Glide", + "gCheats.LongerFlowerGlide", + "Allows Deku Link to glide longer, no longer dropping after a certain distance.", + CHECKBOX, + {}, + ([]() { RegisterLongerFlowerGlide(); }) }, + { MENU_ITEM_CHEATS_NO_CLIP, + "No Clip", + "gCheats.NoClip", + "Allows Link to phase through collision.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_CHEATS_INFINITE_RAZOR_SWORD, + "Unbreakable Razor Sword", + "gCheats.UnbreakableRazorSword", + "Allows to Razor Sword to be used indefinitely without dulling its blade.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_CHEATS_UNRESTRICTED_ITEMS, + "Unrestricted Items", + "gCheats.UnrestrictedItems", + "Allows all Forms to use all Items.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_CHEATS_MOON_JUMP_ON_L, + "Moon Jump on L", + "gCheats.MoonJumpOnL", + "Holding L makes you float into the air.", + CHECKBOX, + {}, + ([]() { RegisterMoonJumpOnL(); }) }, + // Gameplay Enhancements + { MENU_ITEM_FAST_FLOWER_LAUNCH, + "Fast Deku Flower Launch", + "gEnhancements.Player.FastFlowerLaunch", + "Speeds up the time it takes to be able to get maximum height from launching out of a deku flower", + CHECKBOX, + {}, + ([]() { RegisterFastFlowerLaunch(); }) }, + { MENU_ITEM_INSTANT_PUTAWAY, + "Instant Putaway", + "gEnhancements.Player.InstantPutaway", + "Allows Link to instantly puts away held item without waiting.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_CLIMB_SPEED, + "Climb speed", + "gEnhancements.PlayerMovement.ClimbSpeed", + "Increases the speed at which Link climbs vines and ladders.", + SLIDER_INT, + { 1, 5, 1 }, + nullptr }, + { MENU_ITEM_DPAD_EQUIPS, + "Dpad Equips", + "gEnhancements.Dpad.DpadEquips", + "Allows you to equip items to your d-pad", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_ALWAYS_WIN_DOGGY_RACE, + "Always Win Doggy Race", + "gEnhancements.Minigames.AlwaysWinDoggyRace", + "Makes the Doggy Race easier to win.", + COMBOBOX, + { 0, 0, 0, alwaysWinDoggyraceOptions }, + nullptr }, + // Game Modes + { MENU_ITEM_PLAY_AS_KAFEI, + "Play as Kafei", + "gModes.PlayAsKafei", + "Requires scene reload to take effect.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_TIME_MOVES_WHEN_YOU_MOVE, + "Time Moves when you Move", + "gModes.TimeMovesWhenYouMove", + "Time only moves when Link is not standing still.", + CHECKBOX, + {}, + ([]() { RegisterTimeMovesWhenYouMove(); }) }, + // Saving Enhancements + { MENU_ITEM_PERSIST_OWL_SAVES, + "Persistent Owl Saves", + "gEnhancements.Saving.PersistentOwlSaves", + "Continuing a save will not remove the owl save. Playing Song of " + "Time, allowing the moon to crash or finishing the " + "game will remove the owl save and become the new last save.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_PAUSE_MENU_SAVE, + "Pause Menu Save", + "gEnhancements.Saving.PauseSave", + "Re-introduce the pause menu save system. Pressing B in the pause menu will give you the " + "option to create a persistent Owl Save from your current location.\n\nWhen loading back " + "into the game, you will be placed either at the entrance of the dungeon you saved in, or " + "in South Clock Town.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_AUTOSAVE, + "Autosave", + "gEnhancements.Saving.Autosave", + "Automatically create a persistent Owl Save on the chosen interval.\n\nWhen loading " + "back into the game, you will be placed either at the entrance of the dungeon you " + "saved in, or in South Clock Town.", + CHECKBOX, + {}, + ([]() { RegisterAutosave(); }) }, + { MENU_ITEM_AUTOSAVE_INTERVAL, + "Autosave Interval: %d minutes", + "gEnhancements.Saving.AutosaveInterval", + "Sets the interval between Autosaves.", + SLIDER_INT, + { 1, 60, 5 }, + nullptr, { "AutoSave is Disabled" } }, + { MENU_ITEM_DISABLE_BOTTLE_RESET, + "Do not reset Bottle content", + "gEnhancements.Cycle.DoNotResetBottleContent", + "Playing the Song Of Time will not reset the bottles' content.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_DISABLE_CONSUMABLE_RESET, + "Do not reset Consumables", + "gEnhancements.Cycle.DoNotResetConsumables", + "Playing the Song Of Time will not reset the consumables.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_DISABLE_RAZOR_SWORD_RESET, + "Do not reset Razor Sword", + "gEnhancements.Cycle.DoNotResetRazorSword", + "Playing the Song Of Time will not reset the Sword back to Kokiri Sword.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_DISABLE_RUPEE_RESET, + "Do not reset Rupees", + "gEnhancements.Cycle.DoNotResetRupees", + "Playing the Song Of Time will not reset the your rupees.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_DISABLE_SAVE_DELAY, + "Disable Save Delay", + "gEnhancements.Saving.DisableSaveDelay", + "Removes the arbitrary 2 second timer for saving from the original game. This is known to " + "cause issues when attempting the 0th Day Glitch", + CHECKBOX, + {}, + nullptr }, + // Graphics Enhancements + { MENU_ITEM_CLOCK_OPTIONS, + "Clock Type", + "gEnhancements.Graphics.ClockType", + "Swaps between Graphical and Text only Clock types.", + COMBOBOX, + { 0, 0, 0, clockTypeOptions }, + nullptr }, + { MENU_ITEM_MILITARY_CLOCK, + "24 Hours Clock", + "gEnhancements.Graphics.24HoursClock", + "Changes from a 12 Hour to a 24 Hour Clock", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_MOTION_BLUR_MODE, + "Motion Blur Mode", + "gEnhancements.Graphics.MotionBlur.Mode", + "Selects the Mode for Motion Blur.", + COMBOBOX, + { 0, 0, 0, motionBlurOptions }, + nullptr }, + { MENU_ITEM_MOTION_BLUE_INTERPOLATE, + "Interpolate", + "gEnhancements.Graphics.MotionBlur.Interpolate", + "Change motion blur capture to also happen on interpolated frames instead of only on game frames.\n" + "This notably reduces the overall motion blur strength but smooths out the trails.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_MOTION_BLUR_ENABLE, + "On/Off", + "gEnhancements.Graphics.MotionBlur.Toggle", + "Enables Motion Blur.", + CHECKBOX, + {}, + ([]() { + if (CVarGetInteger("gEnhancements.Graphics.MotionBlur.Toggle", 0) == 0) { + R_MOTION_BLUR_ENABLED; + R_MOTION_BLUR_ALPHA = CVarGetInteger("gEnhancements.Graphics.MotionBlur.Strength", 0); + } else { + !R_MOTION_BLUR_ENABLED; + } + }) }, + { MENU_ITEM_MOTION_BLUR_STRENGTH, + "Strength", + "gEnhancements.Graphics.MotionBlur.Strength", + "Motion Blur strength.", + SLIDER_INT, + { 0, 255, 180 }, + nullptr }, + { MENU_ITEM_AUTHENTIC_LOGO, + "Authentic Logo", + "gEnhancements.Graphics.AuthenticLogo", + "Hide the game version and build details and display the authentic " + "model and texture on the boot logo start screen", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_BOW_RETICLE, + "Bow Reticle", + "gEnhancements.Graphics.BowReticle", + "Gives the bow a reticle when you draw an arrow.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_DISABLE_BLACK_BARS, + "Disable Black Bar Letterboxes", + "gEnhancements.Graphics.DisableBlackBars", + "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.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_GEOMETRY_DISTANCE_CHECK, + "Disable Scene Geometry Distance Check", + "gEnhancements.Graphics.DisableSceneGeometryDistanceCheck", + "Disables the distance check for scene geometry, allowing it to be drawn no matter how far " + "away it is from the player. This may have unintended side effects.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_ACTOR_DRAW_DISTANCE, + "Increase Actor Draw Distance: %dx", + "gEnhancements.Graphics.IncreaseActorDrawDistance", + "Increase the range in which Actors are drawn. This may have unintended side effects.", + SLIDER_INT, + { 1, 5, 1 }, + ([]() { + CVarSetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance", + MIN(CVarGetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance", 1), + CVarGetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance", 1))); + }) }, + { MENU_ITEM_ACTOR_UPDATE_DISTANCE, + "Increase Actor Update Distance: %dx", + "gEnhancements.Graphics.IncreaseActorUpdateDistance", + "Increase the range in which Actors are updated. This may have unintended side effects.", + SLIDER_INT, + { 1, 5, 1 }, + ([]() { + CVarSetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance", + MAX(CVarGetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance", 1), + CVarGetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance", 1))); + }) }, + // Mask Enhancements + { MENU_ITEM_BLAST_MASK_KEG_FORCE, + "Blast Mask has Powder Keg Force", + "gEnhancements.Masks.BlastMaskKeg", + "Blast Mask can also destroy objects only the Powder Keg can.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_FAST_TRANSFORMATION, + "Fast Transformation", + "gEnhancements.Masks.FastTransformation", + "Removes the delay when using transormation masks.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_FIERCE_DEITY_ANYWHERE, + "Fierce Deity's Mask Anywhere", + "gEnhancements.Masks.FierceDeitysAnywhere", + "Allow using Fierce Deity's mask outside of boss rooms.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_NO_BLAST_MASK_COOLDOWN, + "No Blast Mask Cooldown", + "gEnhancements.Masks.NoBlastMaskCooldown", + "Eliminates the Cooldown between Blast Mask usage.", + CHECKBOX, + {}, + nullptr }, + // Song Enhancements + { MENU_ITEM_ENABLE_SUNS_SONG, + "Enable Sun's Song", + "gEnhancements.Songs.EnableSunsSong", + "Enables the partially implemented Sun's Song. RIGHT-DOWN-UP-RIGHT-DOWN-UP to play it. " + "This song will make time move very fast until either Link moves to a different scene, " + "or when the time switches to a new time period.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_DPAD_OCARINA, + "Dpad Ocarina", + "gEnhancements.Playback.DpadOcarina", + "Enables using the Dpad for Ocarina playback.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_PREVENT_DROPPED_OCARINA_INPUTS, + "Prevent Dropped Ocarina Inputs", + "gEnhancements.Playback.NoDropOcarinaInput", + "Prevent dropping inputs when playing the ocarina quickly.", + CHECKBOX, + {}, + nullptr }, + // Cutscene Skips + { MENU_ITEM_HIDE_TITLE_CARDS, + "Hide Title Cards", + "gEnhancements.Cutscenes.HideTitleCards", + "Hides Title Cards when entering areas.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_SKIP_ENTRANCE_CUTSCENES, + "Skip Entrance Cutscenes", + "gEnhancements.Cutscenes.SkipEntranceCutscenes", + "Skip cutscenes that occur when first entering a new area.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_SKIP_TO_FILE_SELECT, + "Skip to File Select", + "gEnhancements.Cutscenes.SkipToFileSelect", + "Skip the opening title sequence and go straight to the file select menu after boot.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_SKIP_INTRO_SEQUENCE, + "Skip Intro Sequence", + "gEnhancements.Cutscenes.SkipIntroSequence", + "When starting a game you will be taken straight to South Clock Town as Deku Link.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_SKIP_STORY_CUTSCENES, + "Skip Story Cutscenes", + "gEnhancements.Cutscenes.SkipStoryCutscenes", + "Disclaimer: This doesn't do much yet, we will be progressively adding more skips over time.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_SKIP_MISC_INTERACTIONS, + "Skip Misc Interactions", + "gEnhancements.Cutscenes.SkipMiscInteractions", + "Disclaimer: This doesn't do much yet, we will be progressively adding more skips over time.", + CHECKBOX, + {}, + nullptr }, + // Dialogue Enhancements + { MENU_ITEM_FAST_BANK_SELECTION, + "Fast Bank Selection", + "gEnhancements.Dialogue.FastBankSelection", + "Pressing the Z or R buttons while the Deposit/Withdrawl Rupees dialogue is open will set " + "the Rupees to Links current Rupees or 0 respectively.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_FAST_TEXT, + "Fast Text", + "gEnhancements.Dialogue.FastText", + "Speeds up text rendering, and enables holding of B progress to next message.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_FAST_MAGIC_ARROW_ANIM, + "Fast Magic Arrow Equip Animation", + "gEnhancements.Equipment.MagicArrowEquipSpeed", + "Removes the animation for equipping Magic Arrows.", + CHECKBOX, + {}, + nullptr }, + // Fixes + { MENU_ITEM_FIX_AMMO_COUNT_COLOR, + "Fix Ammo Count Color", + "gFixes.FixAmmoCountEnvColor", + "Fixes a missing gDPSetEnvColor, which causes the ammo count to be " + "the wrong color prior to obtaining magic or other conditions.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_FIX_HESS_WEIRDSHOT, + "Fix Hess and Weirdshot Crash", + "gEnhancements.Fixes.HessCrash", + "Fixes a crash that can occur when performing a HESS or Weirdshot.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_FIX_TEXT_CONTROL_CHAR, + "Fix Text Control Characters", + "gEnhancements.Fixes.ControlCharacters", + "Fixes certain control characters not functioning properly " + "depending on their position within the text.", + CHECKBOX, + {}, + nullptr }, + // Restorations + { MENU_ITEM_RESTORE_DISTANCE_FLIPS_HOPS, + "Constant Distance Backflips and Sidehops", + "gEnhancements.Restorations.ConstantFlipsHops", + "Backflips and Sidehops travel a constant distance as they did in OoT.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_RESTORE_POWER_CROUCH_STAB, + "Power Crouch Stab", + "gEnhancements.Restorations.PowerCrouchStab", + "Crouch stabs will use the power of Link's previous melee attack, as is in MM JP 1.0 and OoT.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_RESTORE_SIDEROLLS, + "Side Rolls", + "gEnhancements.Restorations.SideRoll", + "Restores side rolling from OoT.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_RESTORE_TATL_ISG, + "Tatl ISG", + "gEnhancements.Restorations.TatlISG", + "Restores Navi ISG from OoT, but now with Tatl.", + CHECKBOX, + {}, + nullptr }, + // HUD Editor + // { MENU_ITEM_HUD_EDITOR }, Unused placeholder + { MENU_ITEM_MODERN_MENU_POPOUT, + "Popout Menu", + "gSettings.Menu.Popout", + "Changes the menu display from overlay to windowed.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_OPEN_APP_FILES, + "Open App Files Folder", + "", + "Opens the folder that contains the save and mods folders, etc,", + BUTTON, + {}, + ([]() { + std::string filesPath = Ship::Context::GetInstance()->GetAppDirectoryPath(); + SDL_OpenURL(std::string("file:///" + std::filesystem::absolute(filesPath).string()).c_str()); + }) }, + { MENU_ITEM_DEBUG_MODE_ENABLE, + "Debug Mode", + "gDeveloperTools.DebugEnabled", + "Enables Debug Mode, allowing you to select maps with L + R + Z.", + CHECKBOX, + {}, + ([]() { + if (!CVarGetInteger("gDeveloperTools.DebugEnabled", 0)) { + CVarClear("gDeveloperTools.DebugSaveFileMode"); + CVarClear("gDeveloperTools.PreventActorUpdate"); + CVarClear("gDeveloperTools.PreventActorDraw"); + CVarClear("gDeveloperTools.PreventActorInit"); + CVarClear("gDeveloperTools.DisableObjectDependency"); + if (gPlayState != NULL) { + gPlayState->frameAdvCtx.enabled = false; + } + RegisterDebugSaveCreate(); + RegisterPreventActorUpdateHooks(); + RegisterPreventActorDrawHooks(); + RegisterPreventActorInitHooks(); + } + }) }, + { MENU_ITEM_DEBUG_BETTER_MAP_SELECT, + "Better Map Select", + "gDeveloperTools.BetterMapSelect.Enabled", + "Overrides the original map select with a translated, more user-friendly version.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_DEBUG_SAVE_FILE_MODE, + "Debug Save File Mode", + "gDeveloperTools.DebugSaveFileMode", + "Change the behavior of creating saves while debug mode is enabled:\n\n" + "- Empty Save: The default 3 heart save file in first cycle\n" + "- Vanilla Debug Save: Uses the title screen save info (8 hearts, all items and masks)\n" + "- 100\% Save: All items, equipment, mask, quast status and bombers notebook complete", + COMBOBOX, + { 0, 0, 0, debugSaveOptions }, + ([]() { RegisterDebugSaveCreate(); }) }, + { MENU_ITEM_PREVENT_ACTOR_UPDATE, + "Prevent Actor Update", + "gDeveloperTools.PreventActorUpdate", + "Prevents Actors from updating.", + CHECKBOX, + {}, + ([]() { RegisterPreventActorUpdateHooks(); }) }, + { MENU_ITEM_PREVENT_ACTOR_DRAW, + "Prevent Actor Draw", + "gDeveloperTools.PreventActorDraw", + "Prevents Actors from drawing.", + CHECKBOX, + {}, + ([]() { RegisterPreventActorDrawHooks(); }) }, + { MENU_ITEM_PREVENT_ACTOR_INIT, + "Prevent Actor Init", + "gDeveloperTools.PreventActorInit", + "Prevents Actors from initializing.", + CHECKBOX, + {}, + ([]() { RegisterPreventActorInitHooks(); }) }, + { MENU_ITEM_DISABLE_OBJECT_DEPENDECY, + "Disable Object Dependency", + "gDeveloperTools.DisableObjectDependency", + "Disables dependencies when loading objects.", + CHECKBOX, + {}, + nullptr }, + { MENU_ITEM_DEBUG_LOG_LEVEL, + "Log Level", + "gDeveloperTools.LogLevel", + "The log level determines which messages are printed to the " + "console. This does not affect the log file output", + COMBOBOX, + { 0, 0, 0, logLevels }, + ([]() { + Ship::Context::GetInstance()->GetLogger()->set_level( + (spdlog::level::level_enum)CVarGetInteger("gDeveloperTools.LogLevel", 1)); + }) }, + { MENU_ITEM_FRAME_ADVANCE_ENABLE, + "Frame Advance", + "gDeveloperTools.FrameAdvance", + "This allows you to advance through the game one frame at a time on command. " + "To advance a frame, hold Z and tap R on the second controller. Holding Z " + "and R will advance a frame every half second. You can also use the buttons below.", + CHECKBOX, + {}, + ([]() { + if (CVarGetInteger("gDeveloperTools.FrameAdvance", 0) == 1) { + gPlayState->frameAdvCtx.enabled = true; + } else { + gPlayState->frameAdvCtx.enabled = false; + }; + }) }, + { MENU_ITEM_FRAME_ADVANCE_SINGLE, "Advance 1", "", "Advance 1 frame.", BUTTON, {}, ([]() { + CVarSetInteger("gDeveloperTools.FrameAdvanceTick", 1); + }) }, + { MENU_ITEM_FRAME_ADVANCE_HOLD, + "Advance (Hold)", + "", + "Advance frames while the button is held.", + BUTTON, + {}, + nullptr }, +}; + +void SearchMenuUpdateDisabled() { + disabledMap.at("Debug Camera is Enabled") = CVarGetInteger("gEnhancements.Camera.DebugCam.Enable", 0); + disabledMap.at("Free Look is Enabled") = CVarGetInteger("gEnhancements.Camera.FreeLook.Enable", 0); + disabledMap.at("AutoSave is Disabled") = !CVarGetInteger("gEnhancements.Saving.Autosave", 0); +} + +void SearchMenuGetItem(uint32_t index) { + disabledTempTooltip = "This setting is disabled because the following is set: \n\n"; + disabledValue = false; + disabledTooltip = " "; + + if (!enhancementList[index].disabledName.empty()) { + for (int i = 0; i < enhancementList[index].disabledName.size(); i++) { + if (disabledMap.at(enhancementList[index].disabledName[i]) == true) { + disabledValue = true; + disabledTempTooltip += std::string("- ") + enhancementList[index].disabledName[i] + std::string("\n"); + } + } + disabledTooltip = disabledTempTooltip.c_str(); + } else { + disabledValue = false; + disabledTooltip= " "; + } + + float floatMin; + float floatMax; + float floatDefault; + + switch (enhancementList[index].widgetType) { + case CHECKBOX: + if (UIWidgets::CVarCheckbox(enhancementList[index].cVarText, enhancementList[index].cVarName, + { + .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + .tooltip = enhancementList[index].cVarTooltip, + .disabled = disabledValue, + .disabledTooltip = disabledTooltip, + })) { + if (enhancementList[index].cVarFunction != nullptr) { + enhancementList[index].cVarFunction(); + } + }; + break; + case COMBOBOX: + if (UIWidgets::CVarCombobox(enhancementList[index].cVarText, enhancementList[index].cVarName, + enhancementList[index].cVarOptions.comboBoxOptions, + { + .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + .tooltip = enhancementList[index].cVarTooltip, + .disabled = disabledValue, + .disabledTooltip = disabledTooltip, + })) { + if (enhancementList[index].cVarFunction != nullptr) { + enhancementList[index].cVarFunction(); + } + } + break; + case SLIDER_INT: + if (UIWidgets::CVarSliderInt(enhancementList[index].cVarText, enhancementList[index].cVarName, + enhancementList[index].cVarOptions.min, enhancementList[index].cVarOptions.max, + enhancementList[index].cVarOptions.defaultValue, + { + .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + .tooltip = enhancementList[index].cVarTooltip, + .disabled = disabledValue, + .disabledTooltip = disabledTooltip, + })) { + if (enhancementList[index].cVarFunction != nullptr) { + enhancementList[index].cVarFunction(); + } + }; + break; + case SLIDER_FLOAT: + floatMin = (static_cast(enhancementList[index].cVarOptions.min) / 100); + floatMax = (static_cast(enhancementList[index].cVarOptions.max) / 100); + floatDefault = (static_cast(enhancementList[index].cVarOptions.defaultValue) / 100); + if (UIWidgets::CVarSliderFloat(enhancementList[index].cVarText, enhancementList[index].cVarName, floatMin, + floatMax, floatDefault, + { + .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + .tooltip = enhancementList[index].cVarTooltip, + .disabled = disabledValue, + .disabledTooltip = disabledTooltip, + })) { + if (enhancementList[index].cVarFunction != nullptr) { + enhancementList[index].cVarFunction(); + } + } + break; + case BUTTON: + if (UIWidgets::Button(enhancementList[index].cVarText, + { + .color = menuTheme[CVarGetInteger("gSettings.MenuTheme", 0)], + .tooltip = enhancementList[index].cVarTooltip, + .disabled = disabledValue, + .disabledTooltip = disabledTooltip, + })) { + if (enhancementList[index].cVarFunction != nullptr) { + enhancementList[index].cVarFunction(); + } + } + break; + default: + break; + } +}