From 76e325feb8f144471d4b4c93369ee167cbaa9ed8 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 11 Jan 2024 05:02:34 +0000 Subject: [PATCH] Add frame advance toggle (#23) --- mm/2s2h/SohMenuBar.cpp | 23 +++++++++++++++++++++++ mm/src/code/z_pause.c | 11 ++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/mm/2s2h/SohMenuBar.cpp b/mm/2s2h/SohMenuBar.cpp index cf503c7cf..9b509de5b 100644 --- a/mm/2s2h/SohMenuBar.cpp +++ b/mm/2s2h/SohMenuBar.cpp @@ -484,6 +484,29 @@ void DrawDeveloperToolsMenu() { UIWidgets::PaddedEnhancementCheckbox("Debug Warp Screen Translation", "gDebugWarpScreenTranslation", true, false, false, "", UIWidgets::CheckboxGraphics::Cross, true); UIWidgets::Tooltip("Translate the Debug Warp Screen based on the game language"); + if (gPlayState != NULL) { + UIWidgets::PaddedSeparator(); + ImGui::Checkbox("Frame Advance##frameAdvance", (bool*)&gPlayState->frameAdvCtx.enabled); + UIWidgets::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."); + if (gPlayState->frameAdvCtx.enabled) { + 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("Advance 1", ImVec2(90.0f, 0.0f))) { + CVarSetInteger("gDeveloperTools.FrameAdvanceTick", 1); + } + ImGui::SameLine(); + ImGui::Button("Advance (Hold)"); + if (ImGui::IsItemActive()) { + CVarSetInteger("gDeveloperTools.FrameAdvanceTick", 1); + } + ImGui::PopStyleVar(3); + ImGui::PopStyleColor(1); + } + } UIWidgets::PaddedSeparator(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f)); ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0)); diff --git a/mm/src/code/z_pause.c b/mm/src/code/z_pause.c index b16cc62c1..88f367477 100644 --- a/mm/src/code/z_pause.c +++ b/mm/src/code/z_pause.c @@ -23,6 +23,7 @@ #include "libc/stdbool.h" #include "padutils.h" #include "macros.h" +#include "libultraship/libultraship.h" void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx) { frameAdvCtx->timer = 0; @@ -33,9 +34,17 @@ void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx) { * Returns true when frame advance is not active (game will run normally) */ s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input) { - if (!frameAdvCtx->enabled || (CHECK_BTN_ALL(input->cur.button, BTN_Z) && + if (CVarGetInteger("gDebugEnabled", 0)) { + if (CHECK_BTN_ALL(input->cur.button, BTN_R) && CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) { + frameAdvCtx->enabled = !frameAdvCtx->enabled; + } + } + + if (!frameAdvCtx->enabled || CVarGetInteger("gDeveloperTools.FrameAdvanceTick", 0) || + (CHECK_BTN_ALL(input->cur.button, BTN_Z) && (CHECK_BTN_ALL(input->press.button, BTN_R) || (CHECK_BTN_ALL(input->cur.button, BTN_R) && (++frameAdvCtx->timer >= 9))))) { + CVarClear("gDeveloperTools.FrameAdvanceTick"); frameAdvCtx->timer = 0; return true; }