From eca3a405b69f38b9757cacd87e12ed73f6643d87 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 4 Apr 2021 08:39:49 -0700 Subject: [PATCH] UI: Flip Y analog direction based on config. --- Common/Input/InputState.cpp | 12 +++++++++++ Common/Input/InputState.h | 7 ++++++- Common/UI/Root.cpp | 23 +++++++++++++-------- Core/KeyMap.cpp | 41 ++++++++++++++++++++++++------------- Core/KeyMap.h | 13 ++++++++---- Windows/DinputDevice.cpp | 6 +++--- 6 files changed, 72 insertions(+), 30 deletions(-) diff --git a/Common/Input/InputState.cpp b/Common/Input/InputState.cpp index 90fc9b6a1a..66922ce77f 100644 --- a/Common/Input/InputState.cpp +++ b/Common/Input/InputState.cpp @@ -33,6 +33,7 @@ std::vector confirmKeys; std::vector cancelKeys; std::vector tabLeftKeys; std::vector tabRightKeys; +static std::unordered_map uiFlipAnalogY; static void AppendKeys(std::vector &keys, const std::vector &newKeys) { for (auto iter = newKeys.begin(); iter != newKeys.end(); ++iter) { @@ -61,3 +62,14 @@ void SetTabLeftRightKeys(const std::vector &tabLeft, const std::vector flipYByDeviceId) { + uiFlipAnalogY = flipYByDeviceId; +} + +int GetAnalogYDirection(int deviceId) { + auto configured = uiFlipAnalogY.find(deviceId); + if (configured != uiFlipAnalogY.end()) + return configured->second; + return 0; +} diff --git a/Common/Input/InputState.h b/Common/Input/InputState.h index 59a0a6e057..02377f3b24 100644 --- a/Common/Input/InputState.h +++ b/Common/Input/InputState.h @@ -4,8 +4,9 @@ // own mapping. Might later move the mapping system from PPSSPP to native. #include -#include #include +#include +#include #include "Common/Math/lin/vec3.h" #include "Common/Input/KeyCodes.h" @@ -162,3 +163,7 @@ void SetDPadKeys(const std::vector &leftKey, const std::vector & const std::vector &upKey, const std::vector &downKey); void SetConfirmCancelKeys(const std::vector &confirm, const std::vector &cancel); void SetTabLeftRightKeys(const std::vector &tabLeft, const std::vector &tabRight); + +// 0 means unknown (attempt autodetect), -1 means flip, 1 means original direction. +void SetAnalogFlipY(std::unordered_map flipYByDeviceId); +int GetAnalogYDirection(int deviceId); diff --git a/Common/UI/Root.cpp b/Common/UI/Root.cpp index fadbaeeb6d..ef60f64e12 100644 --- a/Common/UI/Root.cpp +++ b/Common/UI/Root.cpp @@ -4,11 +4,11 @@ #include "ppsspp_config.h" -#include "Common/UI/Root.h" -#include "Common/UI/ViewGroup.h" - +#include "Common/Input/InputState.h" #include "Common/Log.h" #include "Common/TimeUtil.h" +#include "Common/UI/Root.h" +#include "Common/UI/ViewGroup.h" namespace UI { @@ -346,14 +346,21 @@ bool AxisEvent(const AxisInput &axis, ViewGroup *root) { old.x = dir; } if (axis.axisId == JOYSTICK_AXIS_Y || axis.axisId == JOYSTICK_AXIS_HAT_Y) { - // We stupidly interpret the joystick Y axis backwards on Android and Linux instead of reversing - // it early (see keymaps...). Too late to fix without invalidating a lot of config files, so we - // reverse it here too. + int direction = GetAnalogYDirection(axis.deviceId); + if (direction == 0) { + // We stupidly interpret the joystick Y axis backwards on Android and Linux instead of reversing + // it early (see keymaps...). Too late to fix without invalidating a lot of config files, so we + // reverse it here too. #if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(LINUX) - GenerateKeyFromAxis(old.y, dir, NKCODE_DPAD_UP, NKCODE_DPAD_DOWN); + GenerateKeyFromAxis(old.y, dir, NKCODE_DPAD_UP, NKCODE_DPAD_DOWN); #else - GenerateKeyFromAxis(old.y, dir, NKCODE_DPAD_DOWN, NKCODE_DPAD_UP); + GenerateKeyFromAxis(old.y, dir, NKCODE_DPAD_DOWN, NKCODE_DPAD_UP); #endif + } else if (direction == -1) { + GenerateKeyFromAxis(old.y, dir, NKCODE_DPAD_UP, NKCODE_DPAD_DOWN); + } else { + GenerateKeyFromAxis(old.y, dir, NKCODE_DPAD_DOWN, NKCODE_DPAD_UP); + } old.y = dir; } break; diff --git a/Core/KeyMap.cpp b/Core/KeyMap.cpp index 43e268c79a..ad3e95cac9 100644 --- a/Core/KeyMap.cpp +++ b/Core/KeyMap.cpp @@ -15,8 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include #include +#include +#include #if defined(SDL) #include @@ -49,6 +50,7 @@ struct DefMappingStruct { KeyMapping g_controllerMap; int g_controllerMapGeneration = 0; std::set g_seenPads; +static std::set g_seenDeviceIds; bool g_swapped_keys = false; @@ -352,6 +354,13 @@ void UpdateNativeMenuKeys() { SetDPadKeys(upKeys, downKeys, leftKeys, rightKeys); SetConfirmCancelKeys(confirmKeys, cancelKeys); SetTabLeftRightKeys(tabLeft, tabRight); + + std::unordered_map flipYByDeviceId; + for (int deviceId : g_seenDeviceIds) { + auto analogs = MappedAxesForDevice(deviceId); + flipYByDeviceId[deviceId] = analogs.leftY.direction; + } + SetAnalogFlipY(flipYByDeviceId); } static void SetDefaultKeyMap(int deviceId, const DefMappingStruct *array, size_t count, bool replace) { @@ -361,6 +370,7 @@ static void SetDefaultKeyMap(int deviceId, const DefMappingStruct *array, size_t else SetAxisMapping(array[i].pspKey, deviceId, array[i].key, array[i].direction, replace); } + g_seenDeviceIds.insert(deviceId); } void SetDefaultKeyMap(DefaultMaps dmap, bool replace) { @@ -853,30 +863,31 @@ MappedAnalogAxes MappedAxesForDevice(int deviceId) { MappedAnalogAxes result{}; // Find the axisId mapped for a specific virtual button. - auto findAxisId = [&](int btn) -> int { + auto findAxisId = [&](int btn) -> MappedAnalogAxis { + MappedAnalogAxis info{ -1 }; for (const auto &key : g_controllerMap[btn]) { if (key.deviceId == deviceId) { - int direction = 0; - return TranslateKeyCodeToAxis(key.keyCode, direction); + info.axisId = TranslateKeyCodeToAxis(key.keyCode, info.direction); + return info; } } - return -1; + return info; }; // Find the axisId of a pair of opposing buttons. - auto findAxisIdPair = [&](int minBtn, int maxBtn) -> int { - int foundMin = findAxisId(minBtn); - int foundMax = findAxisId(maxBtn); - if (foundMin == foundMax) { + auto findAxisIdPair = [&](int minBtn, int maxBtn) -> MappedAnalogAxis { + MappedAnalogAxis foundMin = findAxisId(minBtn); + MappedAnalogAxis foundMax = findAxisId(maxBtn); + if (foundMin.axisId == foundMax.axisId) { return foundMax; } - return -1; + return MappedAnalogAxis{ -1 }; }; - result.leftXAxisId = findAxisIdPair(VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX); - result.leftYAxisId = findAxisIdPair(VIRTKEY_AXIS_Y_MIN, VIRTKEY_AXIS_Y_MAX); - result.rightXAxisId = findAxisIdPair(VIRTKEY_AXIS_RIGHT_X_MIN, VIRTKEY_AXIS_RIGHT_X_MAX); - result.rightYAxisId = findAxisIdPair(VIRTKEY_AXIS_RIGHT_Y_MIN, VIRTKEY_AXIS_RIGHT_Y_MAX); + result.leftX = findAxisIdPair(VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX); + result.leftY = findAxisIdPair(VIRTKEY_AXIS_Y_MIN, VIRTKEY_AXIS_Y_MAX); + result.rightX = findAxisIdPair(VIRTKEY_AXIS_RIGHT_X_MIN, VIRTKEY_AXIS_RIGHT_X_MAX); + result.rightY = findAxisIdPair(VIRTKEY_AXIS_RIGHT_Y_MIN, VIRTKEY_AXIS_RIGHT_Y_MAX); return result; } @@ -905,6 +916,7 @@ void SetKeyMapping(int btn, KeyDef key, bool replace) { } g_controllerMapGeneration++; + g_seenDeviceIds.insert(key.deviceId); UpdateNativeMenuKeys(); } @@ -969,6 +981,7 @@ void LoadFromIni(IniFile &file) { int keyCode = atoi(parts[1].c_str()); SetKeyMapping(psp_button_names[i].key, KeyDef(deviceId, keyCode), false); + g_seenDeviceIds.insert(deviceId); } } diff --git a/Core/KeyMap.h b/Core/KeyMap.h index 9953b0f87c..f6918ec71b 100644 --- a/Core/KeyMap.h +++ b/Core/KeyMap.h @@ -80,11 +80,16 @@ const float AXIS_BIND_THRESHOLD_MOUSE = 0.01f; typedef std::map> KeyMapping; +struct MappedAnalogAxis { + int axisId; + int direction; +}; + struct MappedAnalogAxes { - int leftXAxisId; - int leftYAxisId; - int rightXAxisId; - int rightYAxisId; + MappedAnalogAxis leftX; + MappedAnalogAxis leftY; + MappedAnalogAxis rightX; + MappedAnalogAxis rightY; }; // KeyMap diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index 4e605907ff..cb80e23be9 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -306,10 +306,10 @@ int DinputDevice::UpdateState() { axis.deviceId = DEVICE_ID_PAD_0 + pDevNum; auto axesToSquare = KeyMap::MappedAxesForDevice(axis.deviceId); - ApplyNormalization(js, axesToSquare.leftXAxisId, axesToSquare.leftYAxisId); + ApplyNormalization(js, axesToSquare.leftX.axisId, axesToSquare.leftY.axisId); // Prevent double normalization. - if (axesToSquare.leftXAxisId != axesToSquare.rightXAxisId && axesToSquare.leftXAxisId != axesToSquare.rightYAxisId) - ApplyNormalization(js, axesToSquare.rightXAxisId, axesToSquare.rightYAxisId); + if (axesToSquare.leftX.axisId != axesToSquare.rightX.axisId && axesToSquare.leftX.axisId != axesToSquare.rightY.axisId) + ApplyNormalization(js, axesToSquare.rightX.axisId, axesToSquare.rightY.axisId); SendNativeAxis(DEVICE_ID_PAD_0 + pDevNum, js.lX, last_lX_, JOYSTICK_AXIS_X); SendNativeAxis(DEVICE_ID_PAD_0 + pDevNum, js.lY, last_lY_, JOYSTICK_AXIS_Y);