From 71ccd415c52c5b01eb013d769d187ad46772d2ed Mon Sep 17 00:00:00 2001 From: staphen Date: Sat, 15 Apr 2023 21:18:02 -0400 Subject: [PATCH] Update gamepad motion state regardless of the active event handler --- Source/DiabloUI/settingsmenu.cpp | 2 +- Source/controls/controller_motion.cpp | 124 ++++++++++++++--------- Source/controls/controller_motion.h | 8 +- Source/controls/devices/kbcontroller.cpp | 6 -- Source/controls/devices/kbcontroller.h | 2 - Source/controls/game_controls.cpp | 5 +- Source/controls/input.h | 2 + Source/controls/menu_controls.cpp | 2 +- 8 files changed, 91 insertions(+), 60 deletions(-) diff --git a/Source/DiabloUI/settingsmenu.cpp b/Source/DiabloUI/settingsmenu.cpp index f42b8d54d..4cec3f552 100644 --- a/Source/DiabloUI/settingsmenu.cpp +++ b/Source/DiabloUI/settingsmenu.cpp @@ -479,7 +479,7 @@ void UiSettingsMenu() StaticVector ctrlEvents = ToControllerButtonEvents(event); for (ControllerButtonEvent ctrlEvent : ctrlEvents) { - bool isGamepadMotion = ProcessControllerMotion(event, ctrlEvent); + bool isGamepadMotion = IsControllerMotion(event); DetectInputMethod(event, ctrlEvent); if (event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE) { StopPadEntryTimer(); diff --git a/Source/controls/controller_motion.cpp b/Source/controls/controller_motion.cpp index 1490fdb02..5bae3914c 100644 --- a/Source/controls/controller_motion.cpp +++ b/Source/controls/controller_motion.cpp @@ -7,7 +7,6 @@ #include "controls/devices/game_controller.h" #endif #include "controls/devices/joystick.h" -#include "controls/devices/kbcontroller.h" #include "controls/game_controls.h" #include "controls/plrctrls.h" #include "controls/touch/gamepad.h" @@ -78,42 +77,6 @@ void SetSimulatingMouseWithPadmapper(bool value) } } -void SimulateRightStickWithPadmapper(ControllerButtonEvent ctrlEvent) -{ - if (ctrlEvent.button == ControllerButton_NONE) - return; - if (!ctrlEvent.up && ctrlEvent.button == SuppressedButton) - return; - - string_view actionName = sgOptions.Padmapper.ActionNameTriggeredByButtonEvent(ctrlEvent); - bool upTriggered = actionName == "MouseUp"; - bool downTriggered = actionName == "MouseDown"; - bool leftTriggered = actionName == "MouseLeft"; - bool rightTriggered = actionName == "MouseRight"; - if (!upTriggered && !downTriggered && !leftTriggered && !rightTriggered) { - if (rightStickX == 0 && rightStickY == 0) - SetSimulatingMouseWithPadmapper(false); - return; - } - - bool upActive = (upTriggered && !ctrlEvent.up) || (!upTriggered && sgOptions.Padmapper.IsActive("MouseUp")); - bool downActive = (downTriggered && !ctrlEvent.up) || (!downTriggered && sgOptions.Padmapper.IsActive("MouseDown")); - bool leftActive = (leftTriggered && !ctrlEvent.up) || (!leftTriggered && sgOptions.Padmapper.IsActive("MouseLeft")); - bool rightActive = (rightTriggered && !ctrlEvent.up) || (!rightTriggered && sgOptions.Padmapper.IsActive("MouseRight")); - - rightStickX = 0; - rightStickY = 0; - if (upActive) - rightStickY += 1.F; - if (downActive) - rightStickY -= 1.F; - if (leftActive) - rightStickX -= 1.F; - if (rightActive) - rightStickX += 1.F; - SetSimulatingMouseWithPadmapper(true); -} - } // namespace float leftStickX, leftStickY, rightStickX, rightStickY; @@ -144,31 +107,60 @@ void ScaleJoysticks() } // namespace +bool IsControllerMotion(const SDL_Event &event) +{ +#ifndef USE_SDL1 + if (event.type == SDL_CONTROLLERAXISMOTION) { + return IsAnyOf(event.caxis.axis, + SDL_CONTROLLER_AXIS_LEFTX, + SDL_CONTROLLER_AXIS_LEFTY, + SDL_CONTROLLER_AXIS_RIGHTX, + SDL_CONTROLLER_AXIS_RIGHTY); + } +#endif + + if (event.type == SDL_JOYAXISMOTION) { + switch (event.jaxis.axis) { +#ifdef JOY_AXIS_LEFTX + case JOY_AXIS_LEFTX: + return true; +#endif +#ifdef JOY_AXIS_LEFTX + case JOY_AXIS_LEFTY: + return true; +#endif +#ifdef JOY_AXIS_LEFTX + case JOY_AXIS_RIGHTX: + return true; +#endif +#ifdef JOY_AXIS_LEFTX + case JOY_AXIS_RIGHTY: + return true; +#endif + default: + return false; + } + } + + return false; +} + // Updates motion state for mouse and joystick sticks. -bool ProcessControllerMotion(const SDL_Event &event, ControllerButtonEvent ctrlEvent) +void ProcessControllerMotion(const SDL_Event &event) { #ifndef USE_SDL1 GameController *const controller = GameController::Get(event); if (controller != nullptr && devilution::GameController::ProcessAxisMotion(event)) { ScaleJoysticks(); SetSimulatingMouseWithPadmapper(false); - return true; + return; } #endif Joystick *const joystick = Joystick::Get(event); if (joystick != nullptr && devilution::Joystick::ProcessAxisMotion(event)) { ScaleJoysticks(); SetSimulatingMouseWithPadmapper(false); - return true; } -#if HAS_KBCTRL == 1 - if (ProcessKbCtrlAxisMotion(event)) { - SetSimulatingMouseWithPadmapper(false); - return true; - } -#endif - SimulateRightStickWithPadmapper(ctrlEvent); - return false; } AxisDirection GetLeftStickOrDpadDirection(bool usePadmapper) @@ -219,4 +211,40 @@ AxisDirection GetLeftStickOrDpadDirection(bool usePadmapper) return result; } +void SimulateRightStickWithPadmapper(ControllerButtonEvent ctrlEvent) +{ + if (ctrlEvent.button == ControllerButton_NONE) + return; + if (!ctrlEvent.up && ctrlEvent.button == SuppressedButton) + return; + + string_view actionName = sgOptions.Padmapper.ActionNameTriggeredByButtonEvent(ctrlEvent); + bool upTriggered = actionName == "MouseUp"; + bool downTriggered = actionName == "MouseDown"; + bool leftTriggered = actionName == "MouseLeft"; + bool rightTriggered = actionName == "MouseRight"; + if (!upTriggered && !downTriggered && !leftTriggered && !rightTriggered) { + if (rightStickX == 0 && rightStickY == 0) + SetSimulatingMouseWithPadmapper(false); + return; + } + + bool upActive = (upTriggered && !ctrlEvent.up) || (!upTriggered && sgOptions.Padmapper.IsActive("MouseUp")); + bool downActive = (downTriggered && !ctrlEvent.up) || (!downTriggered && sgOptions.Padmapper.IsActive("MouseDown")); + bool leftActive = (leftTriggered && !ctrlEvent.up) || (!leftTriggered && sgOptions.Padmapper.IsActive("MouseLeft")); + bool rightActive = (rightTriggered && !ctrlEvent.up) || (!rightTriggered && sgOptions.Padmapper.IsActive("MouseRight")); + + rightStickX = 0; + rightStickY = 0; + if (upActive) + rightStickY += 1.F; + if (downActive) + rightStickY -= 1.F; + if (leftActive) + rightStickX -= 1.F; + if (rightActive) + rightStickX += 1.F; + SetSimulatingMouseWithPadmapper(true); +} + } // namespace devilution diff --git a/Source/controls/controller_motion.h b/Source/controls/controller_motion.h index 3e38c8e62..f7c372fbc 100644 --- a/Source/controls/controller_motion.h +++ b/Source/controls/controller_motion.h @@ -22,9 +22,15 @@ extern float leftStickX, leftStickY, rightStickX, rightStickY; extern bool leftStickNeedsScaling, rightStickNeedsScaling; // Updates motion state for mouse and joystick sticks. -bool ProcessControllerMotion(const SDL_Event &event, ControllerButtonEvent ctrlEvent); +void ProcessControllerMotion(const SDL_Event &event); + +// Indicates whether the event represents movement of an analog thumbstick. +bool IsControllerMotion(const SDL_Event &event); // Returns direction of the left thumb stick or DPad (if allow_dpad = true). AxisDirection GetLeftStickOrDpadDirection(bool usePadmapper); +// Simulates right-stick movement based on input from padmapper mouse movement actions. +void SimulateRightStickWithPadmapper(ControllerButtonEvent ctrlEvent); + } // namespace devilution diff --git a/Source/controls/devices/kbcontroller.cpp b/Source/controls/devices/kbcontroller.cpp index 40d6726de..f0cc69833 100644 --- a/Source/controls/devices/kbcontroller.cpp +++ b/Source/controls/devices/kbcontroller.cpp @@ -174,11 +174,5 @@ bool IsKbCtrlButtonPressed(ControllerButton button) #endif } -bool ProcessKbCtrlAxisMotion(const SDL_Event &event) -{ - // Mapping keyboard to right stick axis not implemented. - return false; -} - } // namespace devilution #endif diff --git a/Source/controls/devices/kbcontroller.h b/Source/controls/devices/kbcontroller.h index f675f4337..3f90a92d7 100644 --- a/Source/controls/devices/kbcontroller.h +++ b/Source/controls/devices/kbcontroller.h @@ -21,7 +21,5 @@ SDL_Keycode ControllerButtonToKbCtrlKeyCode(ControllerButton button); bool IsKbCtrlButtonPressed(ControllerButton button); -bool ProcessKbCtrlAxisMotion(const SDL_Event &event); - } // namespace devilution #endif diff --git a/Source/controls/game_controls.cpp b/Source/controls/game_controls.cpp index b94a286e2..4ef74a99b 100644 --- a/Source/controls/game_controls.cpp +++ b/Source/controls/game_controls.cpp @@ -360,7 +360,10 @@ bool HandleControllerButtonEvent(const SDL_Event &event, const ControllerButtonE }; const ButtonReleaser buttonReleaser { ctrlEvent }; - bool isGamepadMotion = ProcessControllerMotion(event, ctrlEvent); + bool isGamepadMotion = IsControllerMotion(event); + if (!isGamepadMotion) { + SimulateRightStickWithPadmapper(ctrlEvent); + } DetectInputMethod(event, ctrlEvent); if (isGamepadMotion) { return true; diff --git a/Source/controls/input.h b/Source/controls/input.h index a283a7e73..1780cdfc2 100644 --- a/Source/controls/input.h +++ b/Source/controls/input.h @@ -3,6 +3,7 @@ #include #include "controls/controller.h" +#include "controls/controller_motion.h" namespace devilution { @@ -11,6 +12,7 @@ inline int PollEvent(SDL_Event *event) int result = SDL_PollEvent(event); if (result != 0) { UnlockControllerState(*event); + ProcessControllerMotion(*event); } return result; diff --git a/Source/controls/menu_controls.cpp b/Source/controls/menu_controls.cpp index ece5b26f7..619886cca 100644 --- a/Source/controls/menu_controls.cpp +++ b/Source/controls/menu_controls.cpp @@ -32,7 +32,7 @@ std::vector GetMenuActions(const SDL_Event &event) continue; } - bool isGamepadMotion = ProcessControllerMotion(event, ctrlEvent); + bool isGamepadMotion = IsControllerMotion(event); DetectInputMethod(event, ctrlEvent); if (isGamepadMotion) { menuActions.push_back(GetMenuHeldUpDownAction());