This commit is contained in:
nclok1405 2025-08-18 06:47:55 +00:00 committed by GitHub
commit aab251509e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 104 additions and 11 deletions

View file

@ -0,0 +1,58 @@
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "soh/OTRGlobals.h"
#include <spdlog/spdlog.h>
extern "C" {
#include "functions.h"
#include "macros.h"
#include "variables.h"
extern PlayState* gPlayState;
}
#define CVAR_FRAMEADVANCEALTSCHEME_NAME CVAR_DEVELOPER_TOOLS("FrameAdvanceAltScheme")
#define CVAR_FRAMEADVANCEALTSCHEME_DEFAULT 0
#define CVAR_FRAMEADVANCEALTSCHEME_VALUE \
CVarGetInteger(CVAR_FRAMEADVANCEALTSCHEME_NAME, CVAR_FRAMEADVANCEALTSCHEME_DEFAULT)
void RegisterFrameAdvanceAltScheme() {
COND_VB_SHOULD(VB_FRAME_ADVANCE_BE_VANILLA, CVAR_FRAMEADVANCEALTSCHEME_VALUE, {
// Do not run vanilla Frame Advance codes.
*should = false;
});
COND_VB_SHOULD(VB_FRAME_ADVANCE_FREEZE_FRAME, CVAR_FRAMEADVANCEALTSCHEME_VALUE, {
FrameAdvanceContext* frameAdvCtx = va_arg(args, FrameAdvanceContext*);
Input* input = gPlayState->state.input;
bool runFrame = false;
// Push START to toggle the frame advance mode.
if (CHECK_BTN_ALL(input[3].press.button, BTN_START)) {
frameAdvCtx->enabled = !frameAdvCtx->enabled;
if (frameAdvCtx->enabled) {
SPDLOG_DEBUG("Frame Advance is now enabled");
} else {
SPDLOG_DEBUG("Frame Advance is now disabled");
}
}
// Push A to advance one frame.
// Hold L to run normally until L is released.
// Hold R to advance a frame every half second.
if (!frameAdvCtx->enabled || CVarGetInteger(CVAR_DEVELOPER_TOOLS("FrameAdvanceTick"), 0) ||
CHECK_BTN_ALL(input[3].press.button, BTN_A) || CHECK_BTN_ALL(input[3].cur.button, BTN_L) ||
CHECK_BTN_ALL(input[3].press.button, BTN_R) ||
(CHECK_BTN_ALL(input[3].cur.button, BTN_R) && (++frameAdvCtx->timer >= 9))) {
CVarClear(CVAR_DEVELOPER_TOOLS("FrameAdvanceTick"));
frameAdvCtx->timer = 0;
runFrame = true;
}
*should = !runFrame;
});
}
static RegisterShipInitFunc initFunc_FrameAdvanceAltScheme(RegisterFrameAdvanceAltScheme,
{ CVAR_FRAMEADVANCEALTSCHEME_NAME });

View file

@ -535,6 +535,22 @@ typedef enum {
// - None // - None
VB_FIX_SAW_SOFTLOCK, VB_FIX_SAW_SOFTLOCK,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - `*FrameAdvanceContext`
VB_FRAME_ADVANCE_BE_VANILLA,
// #### `result`
// ```c
// false
// ```
// #### `args`
// - `*FrameAdvanceContext`
VB_FRAME_ADVANCE_FREEZE_FRAME,
// #### `result` // #### `result`
// ```c // ```c
// true // true

View file

@ -105,6 +105,13 @@ void SohMenu::AddMenuDevTools() {
} }
}) })
.SameLine(true); .SameLine(true);
AddWidget(path, "Frame Advance Alternative Control Scheme", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_DEVELOPER_TOOLS("FrameAdvanceAltScheme"))
.Options(CheckboxOptions().Tooltip("Remaps Frame Advance controls. Uses Controller Port 4.\n"
"Push START button to toggle Frame Advance.\n"
"Push A button to advance a frame.\n"
"Hold L button to run the game normally until L button is released.\n"
"Hold R button to advance a frame every half second."));
AddWidget(path, "Log Level", WIDGET_CVAR_COMBOBOX) AddWidget(path, "Log Level", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_DEVELOPER_TOOLS("LogLevel")) .CVar(CVAR_DEVELOPER_TOOLS("LogLevel"))
.Options(ComboboxOptions() .Options(ComboboxOptions()

View file

@ -1,4 +1,6 @@
#include "global.h" #include "global.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx) { void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx) {
frameAdvCtx->timer = 0; frameAdvCtx->timer = 0;
@ -14,6 +16,8 @@ void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx) {
* This function returns true when frame advance is not active (game will run normally) * This function returns true when frame advance is not active (game will run normally)
*/ */
s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input) { s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input) {
if (GameInteractor_Should(VB_FRAME_ADVANCE_BE_VANILLA, true, frameAdvCtx)) {
// Vanilla Frame Advance
if (CHECK_BTN_ALL(input->cur.button, BTN_R) && CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) { if (CHECK_BTN_ALL(input->cur.button, BTN_R) && CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) {
frameAdvCtx->enabled = !frameAdvCtx->enabled; frameAdvCtx->enabled = !frameAdvCtx->enabled;
} }
@ -29,3 +33,11 @@ s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input) {
return false; return false;
} }
// Call hooks and ask if we should freeze the frame
if (GameInteractor_Should(VB_FRAME_ADVANCE_FREEZE_FRAME, false, frameAdvCtx)) {
return false;
}
// No hooks said we should freeze the frame, so run the game normally
return true;
}