summaryrefslogtreecommitdiff
path: root/src/input_common/sdl/sdl_impl.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2020-12-30 22:24:30 -0800
committerGravatar GitHub2020-12-30 22:24:30 -0800
commitfb41c82aaa6f633fcf09108bc9e104c54313f191 (patch)
tree5d1d536f4760d1a70dc2a2e371135078a3fd18f0 /src/input_common/sdl/sdl_impl.cpp
parentMerge pull request #5208 from bunnei/service-threads (diff)
parentPort citra-emu/citra#5509 (diff)
downloadyuzu-fb41c82aaa6f633fcf09108bc9e104c54313f191.tar.gz
yuzu-fb41c82aaa6f633fcf09108bc9e104c54313f191.tar.xz
yuzu-fb41c82aaa6f633fcf09108bc9e104c54313f191.zip
Merge pull request #5265 from german77/port5509
Port citra-emu/citra#5509 "Look at direction of analog axis travel instead of instantaneous sample"
Diffstat (limited to 'src/input_common/sdl/sdl_impl.cpp')
-rw-r--r--src/input_common/sdl/sdl_impl.cpp47
1 files changed, 45 insertions, 2 deletions
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp
index 0b531f698..d32eb732a 100644
--- a/src/input_common/sdl/sdl_impl.cpp
+++ b/src/input_common/sdl/sdl_impl.cpp
@@ -1030,11 +1030,44 @@ public:
1030 } 1030 }
1031 return {}; 1031 return {};
1032 } 1032 }
1033 [[nodiscard]] std::optional<Common::ParamPackage> FromEvent(const SDL_Event& event) const { 1033 [[nodiscard]] std::optional<Common::ParamPackage> FromEvent(SDL_Event& event) {
1034 switch (event.type) { 1034 switch (event.type) {
1035 case SDL_JOYAXISMOTION: 1035 case SDL_JOYAXISMOTION:
1036 if (std::abs(event.jaxis.value / 32767.0) < 0.5) { 1036 if (!axis_memory.count(event.jaxis.which) ||
1037 !axis_memory[event.jaxis.which].count(event.jaxis.axis)) {
1038 axis_memory[event.jaxis.which][event.jaxis.axis] = event.jaxis.value;
1039 axis_event_count[event.jaxis.which][event.jaxis.axis] = 1;
1037 break; 1040 break;
1041 } else {
1042 axis_event_count[event.jaxis.which][event.jaxis.axis]++;
1043 // The joystick and axis exist in our map if we take this branch, so no checks
1044 // needed
1045 if (std::abs(
1046 (event.jaxis.value - axis_memory[event.jaxis.which][event.jaxis.axis]) /
1047 32767.0) < 0.5) {
1048 break;
1049 } else {
1050 if (axis_event_count[event.jaxis.which][event.jaxis.axis] == 2 &&
1051 IsAxisAtPole(event.jaxis.value) &&
1052 IsAxisAtPole(axis_memory[event.jaxis.which][event.jaxis.axis])) {
1053 // If we have exactly two events and both are near a pole, this is
1054 // likely a digital input masquerading as an analog axis; Instead of
1055 // trying to look at the direction the axis travelled, assume the first
1056 // event was press and the second was release; This should handle most
1057 // digital axes while deferring to the direction of travel for analog
1058 // axes
1059 event.jaxis.value = static_cast<Sint16>(
1060 std::copysign(32767, axis_memory[event.jaxis.which][event.jaxis.axis]));
1061 } else {
1062 // There are more than two events, so this is likely a true analog axis,
1063 // check the direction it travelled
1064 event.jaxis.value = static_cast<Sint16>(std::copysign(
1065 32767,
1066 event.jaxis.value - axis_memory[event.jaxis.which][event.jaxis.axis]));
1067 }
1068 axis_memory.clear();
1069 axis_event_count.clear();
1070 }
1038 } 1071 }
1039 [[fallthrough]]; 1072 [[fallthrough]];
1040 case SDL_JOYBUTTONUP: 1073 case SDL_JOYBUTTONUP:
@@ -1043,6 +1076,16 @@ public:
1043 } 1076 }
1044 return std::nullopt; 1077 return std::nullopt;
1045 } 1078 }
1079
1080private:
1081 // Determine whether an axis value is close to an extreme or center
1082 // Some controllers have a digital D-Pad as a pair of analog sticks, with 3 possible values per
1083 // axis, which is why the center must be considered a pole
1084 bool IsAxisAtPole(int16_t value) const {
1085 return std::abs(value) >= 32767 || std::abs(value) < 327;
1086 }
1087 std::unordered_map<SDL_JoystickID, std::unordered_map<uint8_t, int16_t>> axis_memory;
1088 std::unordered_map<SDL_JoystickID, std::unordered_map<uint8_t, uint32_t>> axis_event_count;
1046}; 1089};
1047 1090
1048class SDLMotionPoller final : public SDLPoller { 1091class SDLMotionPoller final : public SDLPoller {