diff --git a/UnleashedRecomp/hid/hid.cpp b/UnleashedRecomp/hid/hid.cpp index 8db2ebe..0a56224 100644 --- a/UnleashedRecomp/hid/hid.cpp +++ b/UnleashedRecomp/hid/hid.cpp @@ -7,10 +7,14 @@ hid::EInputDevice hid::g_inputDeviceController; hid::EInputDeviceExplicit hid::g_inputDeviceExplicit; uint16_t hid::g_prohibitedButtons; +bool hid::g_isLeftStickProhibited; +bool hid::g_isRightStickProhibited; -void hid::SetProhibitedButtons(uint16_t wButtons) +void hid::SetProhibitedInputs(uint16_t wButtons, bool leftStick, bool rightStick) { hid::g_prohibitedButtons = wButtons; + hid::g_isLeftStickProhibited = leftStick; + hid::g_isRightStickProhibited = rightStick; } bool hid::IsInputAllowed() diff --git a/UnleashedRecomp/hid/hid.h b/UnleashedRecomp/hid/hid.h index caf09b2..730694a 100644 --- a/UnleashedRecomp/hid/hid.h +++ b/UnleashedRecomp/hid/hid.h @@ -33,6 +33,8 @@ namespace hid extern EInputDeviceExplicit g_inputDeviceExplicit; extern uint16_t g_prohibitedButtons; + extern bool g_isLeftStickProhibited; + extern bool g_isRightStickProhibited; void Init(); @@ -40,7 +42,7 @@ namespace hid uint32_t SetState(uint32_t dwUserIndex, XAMINPUT_VIBRATION* pVibration); uint32_t GetCapabilities(uint32_t dwUserIndex, XAMINPUT_CAPABILITIES* pCaps); - void SetProhibitedButtons(uint16_t wButtons); + void SetProhibitedInputs(uint16_t wButtons = 0, bool leftStick = false, bool rightStick = false); bool IsInputAllowed(); bool IsInputDeviceController(); std::string GetInputDeviceName(); diff --git a/UnleashedRecomp/kernel/xam.cpp b/UnleashedRecomp/kernel/xam.cpp index 0271650..3d7ca77 100644 --- a/UnleashedRecomp/kernel/xam.cpp +++ b/UnleashedRecomp/kernel/xam.cpp @@ -466,6 +466,18 @@ uint32_t XamInputGetState(uint32_t userIndex, uint32_t flags, XAMINPUT_STATE* st state->Gamepad.wButtons &= ~hid::g_prohibitedButtons; + if (hid::g_isLeftStickProhibited) + { + state->Gamepad.sThumbLX = 0; + state->Gamepad.sThumbLY = 0; + } + + if (hid::g_isRightStickProhibited) + { + state->Gamepad.sThumbRX = 0; + state->Gamepad.sThumbRY = 0; + } + ByteSwapInplace(state->Gamepad.wButtons); ByteSwapInplace(state->Gamepad.sThumbLX); ByteSwapInplace(state->Gamepad.sThumbLY); diff --git a/UnleashedRecomp/ui/achievement_menu.cpp b/UnleashedRecomp/ui/achievement_menu.cpp index 91c3201..c0d65a2 100644 --- a/UnleashedRecomp/ui/achievement_menu.cpp +++ b/UnleashedRecomp/ui/achievement_menu.cpp @@ -48,13 +48,11 @@ static std::unique_ptr g_upTrophyIcon; static int g_firstVisibleRowIndex; static int g_selectedRowIndex; static double g_rowSelectionTime; +static double g_lastTappedTime; +static double g_lastIncrementTime; static bool g_upWasHeld; static bool g_downWasHeld; -static bool g_leftWasHeld; -static bool g_rightWasHeld; -static bool g_upRSWasHeld; -static bool g_downRSWasHeld; static void ResetSelection() { @@ -601,26 +599,41 @@ static void DrawContentContainer() bool downIsHeld = inputState->GetPadState().IsDown(SWA::eKeyState_DpadDown) || inputState->GetPadState().LeftStickVertical < -0.5f; - bool leftIsHeld = inputState->GetPadState().IsDown(SWA::eKeyState_DpadLeft) || - inputState->GetPadState().LeftStickHorizontal < -0.5f; - - bool rightIsHeld = inputState->GetPadState().IsDown(SWA::eKeyState_DpadRight) || - inputState->GetPadState().LeftStickHorizontal > 0.5f; - - bool upRSIsHeld = inputState->GetPadState().RightStickVertical > 0.5f; - bool downRSIsHeld = inputState->GetPadState().RightStickVertical < -0.5f; - bool isReachedTop = g_selectedRowIndex == 0; bool isReachedBottom = g_selectedRowIndex == rowCount - 1; bool scrollUp = !g_upWasHeld && upIsHeld; bool scrollDown = !g_downWasHeld && downIsHeld; - bool scrollPageUp = !g_leftWasHeld && leftIsHeld && !isReachedTop; - bool scrollPageDown = !g_rightWasHeld && rightIsHeld && !isReachedBottom; - bool jumpToTop = !g_upRSWasHeld && upRSIsHeld && !isReachedTop; - bool jumpToBottom = !g_downRSWasHeld && downRSIsHeld && !isReachedBottom; - int prevSelectedRowIndex = g_selectedRowIndex; + auto time = ImGui::GetTime(); + auto fastScroll = (time - g_lastTappedTime) > 0.6; + auto fastScrollSpeed = 1.0 / 3.5; + static auto fastScrollSpeedUp = false; + + if (scrollUp || scrollDown) + g_lastTappedTime = time; + + if (!upIsHeld && !downIsHeld) + fastScrollSpeedUp = false; + + if (fastScrollSpeedUp) + fastScrollSpeed /= 2; + + if (fastScroll) + { + if ((time - g_lastIncrementTime) < fastScrollSpeed) + { + fastScroll = false; + } + else + { + g_lastIncrementTime = time; + + scrollUp = upIsHeld; + scrollDown = downIsHeld; + fastScrollSpeedUp = true; + } + } if (scrollUp) { @@ -634,40 +647,15 @@ static void DrawContentContainer() if (g_selectedRowIndex >= rowCount) g_selectedRowIndex = 0; } - else if (scrollPageUp) - { - g_selectedRowIndex -= 3; - if (g_selectedRowIndex < 0) - g_selectedRowIndex = 0; - } - else if (scrollPageDown) - { - g_selectedRowIndex += 3; - if (g_selectedRowIndex >= rowCount) - g_selectedRowIndex = rowCount - 1; - } - else if (jumpToTop) - { - g_selectedRowIndex = 0; - } - else if (jumpToBottom) - { - g_selectedRowIndex = rowCount - 1; - } - // lol - if (scrollUp || scrollDown || scrollPageUp || scrollPageDown || jumpToTop || jumpToBottom) + if (scrollUp || scrollDown) { - g_rowSelectionTime = ImGui::GetTime(); + g_rowSelectionTime = time; Game_PlaySound("sys_actstg_pausecursor"); } g_upWasHeld = upIsHeld; g_downWasHeld = downIsHeld; - g_leftWasHeld = leftIsHeld; - g_rightWasHeld = rightIsHeld; - g_upRSWasHeld = upRSIsHeld; - g_downRSWasHeld = downRSIsHeld; int visibleRowCount = int(floor((clipRectMax.y - clipRectMin.y) / itemHeight)); @@ -783,7 +771,7 @@ void AchievementMenu::Open() ResetSelection(); Game_PlaySound("sys_actstg_pausewinopen"); - hid::SetProhibitedButtons(XAMINPUT_GAMEPAD_START); + hid::SetProhibitedInputs(XAMINPUT_GAMEPAD_START); } void AchievementMenu::Close() @@ -793,7 +781,7 @@ void AchievementMenu::Close() g_appearTime = ImGui::GetTime(); g_isClosing = true; - hid::SetProhibitedButtons(0); + hid::SetProhibitedInputs(); } ButtonGuide::Close(); diff --git a/UnleashedRecomp/ui/options_menu.cpp b/UnleashedRecomp/ui/options_menu.cpp index 1bf5753..5979d3b 100644 --- a/UnleashedRecomp/ui/options_menu.cpp +++ b/UnleashedRecomp/ui/options_menu.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -101,6 +102,24 @@ static double g_appearTime = 0.0; static std::unique_ptr g_upMilesElectric; +static float g_rightStickY; + +class SDLEventListenerForOptionsMenu : public SDLEventListener +{ +public: + bool OnSDLEvent(SDL_Event* event) override + { + if (!OptionsMenu::s_isVisible || !hid::IsInputAllowed()) + return false; + + if (event->type == SDL_CONTROLLERAXISMOTION && event->caxis.axis == SDL_CONTROLLER_AXIS_RIGHTY) + g_rightStickY = event->caxis.value / 32767.0f; + + return false; + } +} +g_sdlEventListenerForOptionsMenu; + static void DrawTitle() { static constexpr double fadeOffset = 3.0; @@ -1476,23 +1495,19 @@ static void DrawInfoPanel(ImVec2 infoMin, ImVec2 infoMax) if (scrollMax > 0.0f) { - if (auto pInputState = SWA::CInputState::GetInstance()) - { - auto& rPadState = pInputState->GetPadState(); - auto& vert = rPadState.RightStickVertical; + auto vert = -g_rightStickY; - if (fabs(vert) > 0.25f) - { - isManualScrolling = true; - scrollOffset += vert * scrollSpeed * App::s_deltaTime; - } - else if (isManualScrolling && fabs(vert) <= 0.25f) - { - isScrolling = false; - isManualScrolling = false; - scrollTimer = 0.0f; - scrollDirection = vert > 0.0f ? 1.0f : -1.0f; - } + if (fabs(vert) > 0.25f) + { + isManualScrolling = true; + scrollOffset += vert * scrollSpeed * App::s_deltaTime; + } + else if (isManualScrolling && fabs(vert) <= 0.25f) + { + isScrolling = false; + isManualScrolling = false; + scrollTimer = 0.0f; + scrollDirection = vert > 0.0f ? 1.0f : -1.0f; } if (!isManualScrolling) @@ -1750,7 +1765,7 @@ void OptionsMenu::Open(bool isPause, SWA::EMenuType pauseMenuType) ButtonGuide::Open(buttons); ButtonGuide::SetSideMargins(250); - hid::SetProhibitedButtons(XAMINPUT_GAMEPAD_START); + hid::SetProhibitedInputs(XAMINPUT_GAMEPAD_START, false, true); } void OptionsMenu::Close() @@ -1764,7 +1779,7 @@ void OptionsMenu::Close() ButtonGuide::Close(); Config::Save(); - hid::SetProhibitedButtons(0); + hid::SetProhibitedInputs(); } // Skip Miles Electric animation at main menu.