From e1e5a8b49b21ccdc3f942a7021e3d5842910a80b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 May 2021 13:21:45 -0700 Subject: [PATCH 1/2] UI: Ignore duplicate axis events. We already ignore these on Windows, so this makes other platforms follow the same logic. --- UI/EmuScreen.cpp | 10 +++++++++ UI/EmuScreen.h | 5 ++++- Windows/DinputDevice.cpp | 3 --- Windows/XinputDevice.cpp | 48 ++++++++++++---------------------------- 4 files changed, 28 insertions(+), 38 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 799cc20da239..ed60aacf7cc5 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -864,6 +864,16 @@ void EmuScreen::pspKey(int pspKeyCode, int flags) { bool EmuScreen::axis(const AxisInput &axis) { Core_NotifyActivity(); + // Ignore duplicate values to prevent axis values overwriting each other. + uint64_t key = ((uint64_t)axis.axisId << 32) | axis.deviceId; + // Center value far from zero just to ensure we send the first zero. + // PSP games can't see higher resolution than this. + int value = 128 + ceilf(axis.value * 127.5f + 127.5f); + if (lastAxis_[key] == value) { + return false; + } + lastAxis_[key] = value; + if (axis.value > 0) { processAxis(axis, 1); return true; diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 5cbedbf07ddf..7f53be825788 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -17,9 +17,11 @@ #pragma once +#include +#include #include +#include #include -#include #include "Common/File/Path.h" #include "Common/Input/KeyCodes.h" @@ -113,4 +115,5 @@ class EmuScreen : public UIScreen { bool autoRotatingAnalogCW_ = false; bool autoRotatingAnalogCCW_ = false; + std::unordered_map lastAxis_; }; diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index cb80e23be9fc..bc5ab3e6a7bc 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -200,9 +200,6 @@ DinputDevice::~DinputDevice() { } void SendNativeAxis(int deviceId, int value, int &lastValue, int axisId) { - if (value == lastValue) - return; - AxisInput axis; axis.deviceId = deviceId; axis.axisId = axisId; diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index 5a4a636bf6e6..446b0589d3bf 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -282,54 +282,34 @@ void XinputDevice::UpdatePad(int pad, const XINPUT_STATE &state, XINPUT_VIBRATIO const float STICK_INV_DEADZONE = g_Config.fXInputAnalogInverseDeadzone; const float STICK_SENSITIVITY = g_Config.fXInputAnalogSensitivity; + AxisInput axis; + axis.deviceId = DEVICE_ID_X360_0 + pad; + auto sendAxis = [&](AndroidJoystickAxis axisId, float value) { + axis.axisId = axisId; + axis.value = value; + NativeAxis(axis); + }; + if (NormalizedDeadzoneDiffers(prevState[pad].Gamepad.sThumbLX, prevState[pad].Gamepad.sThumbLY, state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, STICK_DEADZONE)) { Stick left = NormalizedDeadzoneFilter(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, STICK_DEADZONE, STICK_INV_MODE, STICK_INV_DEADZONE, STICK_SENSITIVITY); - AxisInput axis; - axis.deviceId = DEVICE_ID_X360_0 + pad; - axis.axisId = JOYSTICK_AXIS_X; - axis.value = left.x; - if (prevState[pad].Gamepad.sThumbLX != state.Gamepad.sThumbLX) { - NativeAxis(axis); - } - axis.axisId = JOYSTICK_AXIS_Y; - axis.value = left.y; - if (prevState[pad].Gamepad.sThumbLY != state.Gamepad.sThumbLY) { - NativeAxis(axis); - } + sendAxis(JOYSTICK_AXIS_X, left.x); + sendAxis(JOYSTICK_AXIS_Y, left.y); } if (NormalizedDeadzoneDiffers(prevState[pad].Gamepad.sThumbRX, prevState[pad].Gamepad.sThumbRY, state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, STICK_DEADZONE)) { Stick right = NormalizedDeadzoneFilter(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, STICK_DEADZONE, STICK_INV_MODE, STICK_INV_DEADZONE, STICK_SENSITIVITY); - AxisInput axis; - axis.deviceId = DEVICE_ID_X360_0 + pad; - axis.axisId = JOYSTICK_AXIS_Z; - axis.value = right.x; - if (prevState[pad].Gamepad.sThumbRX != state.Gamepad.sThumbRX) { - NativeAxis(axis); - } - axis.axisId = JOYSTICK_AXIS_RZ; - axis.value = right.y; - if (prevState[pad].Gamepad.sThumbRY != state.Gamepad.sThumbRY) { - NativeAxis(axis); - } + sendAxis(JOYSTICK_AXIS_Z, right.x); + sendAxis(JOYSTICK_AXIS_RZ, right.y); } if (NormalizedDeadzoneDiffers(prevState[pad].Gamepad.bLeftTrigger, state.Gamepad.bLeftTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD)) { - AxisInput axis; - axis.deviceId = DEVICE_ID_X360_0 + pad; - axis.axisId = JOYSTICK_AXIS_LTRIGGER; - axis.value = (float)state.Gamepad.bLeftTrigger / 255.0f; - NativeAxis(axis); + sendAxis(JOYSTICK_AXIS_LTRIGGER, (float)state.Gamepad.bLeftTrigger / 255.0f); } if (NormalizedDeadzoneDiffers(prevState[pad].Gamepad.bRightTrigger, state.Gamepad.bRightTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD)) { - AxisInput axis; - axis.deviceId = DEVICE_ID_X360_0 + pad; - axis.axisId = JOYSTICK_AXIS_RTRIGGER; - axis.value = (float)state.Gamepad.bRightTrigger / 255.0f; - NativeAxis(axis); + sendAxis(JOYSTICK_AXIS_RTRIGGER, (float)state.Gamepad.bRightTrigger / 255.0f); } prevState[pad] = state; From b0de7ee0e1bcbd46b8bb97a957dfb77644556dab Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 May 2021 15:18:21 -0700 Subject: [PATCH 2/2] UI: Move to ScreenManager for mapping. Otherwise we'll detect repeated axis for some devices and you won't be able to map what you want. --- Common/UI/Screen.cpp | 11 +++++++++++ Common/UI/Screen.h | 6 +++++- UI/EmuScreen.cpp | 10 ---------- UI/EmuScreen.h | 3 --- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Common/UI/Screen.cpp b/Common/UI/Screen.cpp index f8f4cd10dcd6..1945b5be4fee 100644 --- a/Common/UI/Screen.cpp +++ b/Common/UI/Screen.cpp @@ -106,6 +106,17 @@ bool ScreenManager::key(const KeyInput &key) { bool ScreenManager::axis(const AxisInput &axis) { std::lock_guard guard(inputLock_); + + // Ignore duplicate values to prevent axis values overwriting each other. + uint64_t key = ((uint64_t)axis.axisId << 32) | axis.deviceId; + // Center value far from zero just to ensure we send the first zero. + // PSP games can't see higher resolution than this. + int value = 128 + ceilf(axis.value * 127.5f + 127.5f); + if (lastAxis_[key] == value) { + return false; + } + lastAxis_[key] = value; + bool result = false; // Send center axis to every screen layer. if (axis.value == 0) { diff --git a/Common/UI/Screen.h b/Common/UI/Screen.h index 46f7261ddbfc..59429d75e7c2 100644 --- a/Common/UI/Screen.h +++ b/Common/UI/Screen.h @@ -13,9 +13,11 @@ #pragma once -#include +#include #include #include +#include +#include #include "Common/Common.h" #include "Common/Input/InputState.h" @@ -165,4 +167,6 @@ class ScreenManager { // Used for options, in-game menus and other things you expect to be able to back out from onto something. std::vector stack_; std::vector nextStack_; + + std::unordered_map lastAxis_; }; diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index ed60aacf7cc5..799cc20da239 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -864,16 +864,6 @@ void EmuScreen::pspKey(int pspKeyCode, int flags) { bool EmuScreen::axis(const AxisInput &axis) { Core_NotifyActivity(); - // Ignore duplicate values to prevent axis values overwriting each other. - uint64_t key = ((uint64_t)axis.axisId << 32) | axis.deviceId; - // Center value far from zero just to ensure we send the first zero. - // PSP games can't see higher resolution than this. - int value = 128 + ceilf(axis.value * 127.5f + 127.5f); - if (lastAxis_[key] == value) { - return false; - } - lastAxis_[key] = value; - if (axis.value > 0) { processAxis(axis, 1); return true; diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 7f53be825788..df2adf9d4831 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -17,10 +17,8 @@ #pragma once -#include #include #include -#include #include #include "Common/File/Path.h" @@ -115,5 +113,4 @@ class EmuScreen : public UIScreen { bool autoRotatingAnalogCW_ = false; bool autoRotatingAnalogCCW_ = false; - std::unordered_map lastAxis_; };