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
This commit is contained in:
Garrett Cox 2022-09-20 22:24:06 -05:00 committed by GitHub
parent d628bafe29
commit 936c493b9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 60 additions and 11 deletions

View File

@ -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<Controller> 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;
}
void ControlDeck::BlockGameInput() {
shouldBlockGameInput = true;
}
void ControlDeck::UnblockGameInput() {
shouldBlockGameInput = false;
}
bool ControlDeck::ShouldBlockGameInput() const {
return shouldBlockGameInput || (CVar_GetS32("gOpenMenuBar", 0) && CVar_GetS32("gControlNav", 0));
}
}

View File

@ -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<int32_t> virtualDevices = {};
std::vector<std::shared_ptr<Controller>> physicalDevices = {};
uint8_t* controllerBits = nullptr;
bool shouldBlockGameInput = false;
};
}

View File

@ -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))];
}
if (pad != nullptr) {
*pad = padBuffer[std::min(padBuffer.size(), (size_t)CVar_GetS32("gSimulatedInputLag", 0))];
}
while (padBuffer.size() > 6) {
while (padBuffer.size() > 6) {
padBuffer.pop_back();
}
}

View File

@ -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);

View File

@ -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<Ship::AudioInit>();
}

View File

@ -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);

View File

@ -288,6 +288,11 @@ void PadMgr_ProcessInputs(PadMgr* padMgr) {
}
OTRControllerCallback(&controllerCallback);
if (CVar_GetS32("gPauseBufferBlockInputFrame", 0)) {
Controller_BlockGameInput();
} else {
Controller_UnblockGameInput();
}
PadMgr_UnlockPadData(padMgr);
}

View File

@ -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))

View File

@ -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();

View File

@ -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;