UI: Flip Y analog direction based on config.

This commit is contained in:
Unknown W. Brackets 2021-04-04 08:39:49 -07:00
parent c9428975fe
commit eca3a405b6
6 changed files with 72 additions and 30 deletions

View File

@ -33,6 +33,7 @@ std::vector<KeyDef> confirmKeys;
std::vector<KeyDef> cancelKeys;
std::vector<KeyDef> tabLeftKeys;
std::vector<KeyDef> tabRightKeys;
static std::unordered_map<int, int> uiFlipAnalogY;
static void AppendKeys(std::vector<KeyDef> &keys, const std::vector<KeyDef> &newKeys) {
for (auto iter = newKeys.begin(); iter != newKeys.end(); ++iter) {
@ -61,3 +62,14 @@ void SetTabLeftRightKeys(const std::vector<KeyDef> &tabLeft, const std::vector<K
tabLeftKeys = tabLeft;
tabRightKeys = tabRight;
}
void SetAnalogFlipY(std::unordered_map<int, int> flipYByDeviceId) {
uiFlipAnalogY = flipYByDeviceId;
}
int GetAnalogYDirection(int deviceId) {
auto configured = uiFlipAnalogY.find(deviceId);
if (configured != uiFlipAnalogY.end())
return configured->second;
return 0;
}

View File

@ -4,8 +4,9 @@
// own mapping. Might later move the mapping system from PPSSPP to native.
#include <map>
#include <vector>
#include <mutex>
#include <unordered_map>
#include <vector>
#include "Common/Math/lin/vec3.h"
#include "Common/Input/KeyCodes.h"
@ -162,3 +163,7 @@ void SetDPadKeys(const std::vector<KeyDef> &leftKey, const std::vector<KeyDef> &
const std::vector<KeyDef> &upKey, const std::vector<KeyDef> &downKey);
void SetConfirmCancelKeys(const std::vector<KeyDef> &confirm, const std::vector<KeyDef> &cancel);
void SetTabLeftRightKeys(const std::vector<KeyDef> &tabLeft, const std::vector<KeyDef> &tabRight);
// 0 means unknown (attempt autodetect), -1 means flip, 1 means original direction.
void SetAnalogFlipY(std::unordered_map<int, int> flipYByDeviceId);
int GetAnalogYDirection(int deviceId);

View File

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

View File

@ -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 <set>
#include <algorithm>
#include <set>
#include <unordered_map>
#if defined(SDL)
#include <SDL_keyboard.h>
@ -49,6 +50,7 @@ struct DefMappingStruct {
KeyMapping g_controllerMap;
int g_controllerMapGeneration = 0;
std::set<std::string> g_seenPads;
static std::set<int> 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<int, int> 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);
}
}

View File

@ -80,11 +80,16 @@ const float AXIS_BIND_THRESHOLD_MOUSE = 0.01f;
typedef std::map<int, std::vector<KeyDef>> 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

View File

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