From 936c493b9ebd690b917833c3f21b2982e29fb4c5 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 20 Sep 2022 22:24:06 -0500 Subject: [PATCH] Add cheat for easy pause buffering (#1439) * Add cheat for easy pause buffering * Add pause input buffering * Fix pause input buffering * Changes from feedback * Convert frame to bool * Handle when pad is nullptr * Add newline * Split input buffering into it's own CVAR * Split SetShouldBlockGameInput up into to methods --- libultraship/libultraship/ControlDeck.cpp | 19 ++++++++++++++----- libultraship/libultraship/ControlDeck.h | 4 ++++ libultraship/libultraship/Controller.cpp | 10 +++++----- soh/soh/GameMenuBar.cpp | 2 ++ soh/soh/OTRGlobals.cpp | 12 ++++++++++++ soh/soh/OTRGlobals.h | 2 ++ soh/src/code/padmgr.c | 5 +++++ soh/src/code/z_kaleido_setup.c | 6 +++++- soh/src/code/z_play.c | 7 +++++++ .../ovl_kaleido_scope/z_kaleido_scope_PAL.c | 4 ++++ 10 files changed, 60 insertions(+), 11 deletions(-) diff --git a/libultraship/libultraship/ControlDeck.cpp b/libultraship/libultraship/ControlDeck.cpp index 071d62956..499d34d72 100644 --- a/libultraship/libultraship/ControlDeck.cpp +++ b/libultraship/libultraship/ControlDeck.cpp @@ -73,13 +73,11 @@ namespace Ship { } void ControlDeck::WriteToPad(OSContPad* pad) const { - bool shouldBlockGameInput = CVar_GetS32("gOpenMenuBar", 0) && CVar_GetS32("gControlNav", 0); - for (size_t i = 0; i < virtualDevices.size(); i++) { const std::shared_ptr backend = physicalDevices[virtualDevices[i]]; if (backend->GetGuid() == "Auto") { for (const auto& device : physicalDevices) { - if(shouldBlockGameInput && device->GetGuid() != "Keyboard") { + if(ShouldBlockGameInput() && device->GetGuid() != "Keyboard") { device->Read(nullptr, i); continue; } @@ -87,7 +85,7 @@ namespace Ship { } continue; } - if(shouldBlockGameInput && backend->GetGuid() != "Keyboard") { + if(ShouldBlockGameInput() && backend->GetGuid() != "Keyboard") { backend->Read(nullptr, i); continue; } @@ -258,4 +256,15 @@ namespace Ship { return controllerBits; } -} \ No newline at end of file + void ControlDeck::BlockGameInput() { + shouldBlockGameInput = true; + } + + void ControlDeck::UnblockGameInput() { + shouldBlockGameInput = false; + } + + bool ControlDeck::ShouldBlockGameInput() const { + return shouldBlockGameInput || (CVar_GetS32("gOpenMenuBar", 0) && CVar_GetS32("gControlNav", 0)); + } +} diff --git a/libultraship/libultraship/ControlDeck.h b/libultraship/libultraship/ControlDeck.h index e0e85f27a..b72f8c3ce 100644 --- a/libultraship/libultraship/ControlDeck.h +++ b/libultraship/libultraship/ControlDeck.h @@ -20,9 +20,13 @@ namespace Ship { int32_t GetVirtualDevice(int32_t slot); size_t GetNumVirtualDevices(); uint8_t* GetControllerBits(); + void BlockGameInput(); + void UnblockGameInput(); + bool ShouldBlockGameInput() const; private: std::vector virtualDevices = {}; std::vector> physicalDevices = {}; uint8_t* controllerBits = nullptr; + bool shouldBlockGameInput = false; }; } diff --git a/libultraship/libultraship/Controller.cpp b/libultraship/libultraship/Controller.cpp index 05ed01e25..3af444090 100644 --- a/libultraship/libultraship/Controller.cpp +++ b/libultraship/libultraship/Controller.cpp @@ -78,11 +78,11 @@ namespace Ship { padToBuffer.gyro_y = getGyroY(virtualSlot); padBuffer.push_front(padToBuffer); - if (pad != nullptr) { - *pad = padBuffer[std::min(padBuffer.size(), (size_t)CVar_GetS32("gSimulatedInputLag", 0))]; - } - - while (padBuffer.size() > 6) { + if (pad != nullptr) { + *pad = padBuffer[std::min(padBuffer.size(), (size_t)CVar_GetS32("gSimulatedInputLag", 0))]; + } + + while (padBuffer.size() > 6) { padBuffer.pop_back(); } } diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp index 834cc57e4..979573b93 100644 --- a/soh/soh/GameMenuBar.cpp +++ b/soh/soh/GameMenuBar.cpp @@ -1244,6 +1244,8 @@ namespace GameMenuBar { 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("Easy Frame Advancing", "gCheatEasyPauseBufferEnabled", true, false); + UIWidgets::Tooltip("Continue holding START button when unpausing to only advance a single frame and then re-pause"); 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); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index b2aa6dd91..60dc1e9e4 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1549,6 +1549,18 @@ extern "C" int Controller_ShouldRumble(size_t i) { return 0; } +extern "C" void Controller_BlockGameInput() { + auto controlDeck = Ship::Window::GetInstance()->GetControlDeck(); + + controlDeck->BlockGameInput(); +} + +extern "C" void Controller_UnblockGameInput() { + auto controlDeck = Ship::Window::GetInstance()->GetControlDeck(); + + controlDeck->UnblockGameInput(); +} + extern "C" void Hooks_ExecuteAudioInit() { Ship::ExecuteHooks(); } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index c9f2b0e9b..c79ba92f3 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -91,6 +91,8 @@ int AudioPlayer_GetDesiredBuffered(void); void AudioPlayer_Play(const uint8_t* buf, uint32_t len); void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples); int Controller_ShouldRumble(size_t i); +void Controller_BlockGameInput(); +void Controller_UnblockGameInput(); void Hooks_ExecuteAudioInit(); void* getN64WeirdFrame(s32 i); Sprite* GetSeedTexture(uint8_t index); diff --git a/soh/src/code/padmgr.c b/soh/src/code/padmgr.c index e2283c1e9..98b97dc71 100644 --- a/soh/src/code/padmgr.c +++ b/soh/src/code/padmgr.c @@ -288,6 +288,11 @@ void PadMgr_ProcessInputs(PadMgr* padMgr) { } OTRControllerCallback(&controllerCallback); + if (CVar_GetS32("gPauseBufferBlockInputFrame", 0)) { + Controller_BlockGameInput(); + } else { + Controller_UnblockGameInput(); + } PadMgr_UnlockPadData(padMgr); } diff --git a/soh/src/code/z_kaleido_setup.c b/soh/src/code/z_kaleido_setup.c index f578f98b4..644cbb010 100644 --- a/soh/src/code/z_kaleido_setup.c +++ b/soh/src/code/z_kaleido_setup.c @@ -18,11 +18,15 @@ void KaleidoSetup_Update(GlobalContext* globalCtx) { globalCtx->shootingGalleryStatus <= 1 && gSaveContext.unk_13F0 != 8 && gSaveContext.unk_13F0 != 9 && (globalCtx->sceneNum != SCENE_BOWLING || !Flags_GetSwitch(globalCtx, 0x38))) { + if (CVar_GetS32("gCheatEasyPauseBufferFrameAdvance", 0) == 2 && !CHECK_BTN_ALL(input->press.button, BTN_START)) { + CVar_SetS32("gCheatEasyPauseBufferFrameAdvance", 0); + } + if (CHECK_BTN_ALL(input->cur.button, BTN_L) && CHECK_BTN_ALL(input->press.button, BTN_CUP)) { if (BREG(0)) { pauseCtx->debugState = 3; } - } else if (CHECK_BTN_ALL(input->press.button, BTN_START)) { + } else if ((CHECK_BTN_ALL(input->press.button, BTN_START) && !CVar_GetS32("gCheatEasyPauseBufferFrameAdvance", 0)) || CVar_GetS32("gCheatEasyPauseBufferFrameAdvance", 0) == 1) { gSaveContext.unk_13EE = gSaveContext.unk_13EA; if (CHECK_BTN_ALL(input->cur.button, BTN_L)) diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index c22ab6d57..ff5e879ce 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -1481,6 +1481,13 @@ time_t Gameplay_GetRealTime() { void Gameplay_Main(GameState* thisx) { GlobalContext* globalCtx = (GlobalContext*)thisx; + if (CVar_GetS32("gCheatEasyPauseBufferFrameAdvance", 0)) { + CVar_SetS32("gCheatEasyPauseBufferFrameAdvance", CVar_GetS32("gCheatEasyPauseBufferFrameAdvance", 0) - 1); + } + if (CVar_GetS32("gPauseBufferBlockInputFrame", 0)) { + CVar_SetS32("gPauseBufferBlockInputFrame", CVar_GetS32("gPauseBufferBlockInputFrame", 0) - 1); + } + D_8012D1F8 = &globalCtx->state.input[0]; DebugDisplay_Init(); diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index a4a5c725f..ee0b5c179 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -3704,6 +3704,10 @@ void KaleidoScope_Update(GlobalContext* globalCtx) switch (pauseCtx->unk_1E4) { case 0: if (CHECK_BTN_ALL(input->press.button, BTN_START)) { + CVar_SetS32("gPauseBufferBlockInputFrame", 9); + if (CVar_GetS32("gCheatEasyPauseBufferEnabled", 0)) { + CVar_SetS32("gCheatEasyPauseBufferFrameAdvance", 13); + } Interface_SetDoAction(globalCtx, DO_ACTION_NONE); pauseCtx->state = 0x12; WREG(2) = -6240;