diff options
Diffstat (limited to 'src/input_common/sdl/sdl_impl.cpp')
| -rw-r--r-- | src/input_common/sdl/sdl_impl.cpp | 281 |
1 files changed, 223 insertions, 58 deletions
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index b9b584b2a..68672a92b 100644 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp | |||
| @@ -18,16 +18,6 @@ | |||
| 18 | #include <utility> | 18 | #include <utility> |
| 19 | #include <vector> | 19 | #include <vector> |
| 20 | 20 | ||
| 21 | // Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307 | ||
| 22 | #ifdef __clang__ | ||
| 23 | #pragma clang diagnostic push | ||
| 24 | #pragma clang diagnostic ignored "-Wimplicit-fallthrough" | ||
| 25 | #endif | ||
| 26 | #include <SDL.h> | ||
| 27 | #ifdef __clang__ | ||
| 28 | #pragma clang diagnostic pop | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #include "common/logging/log.h" | 21 | #include "common/logging/log.h" |
| 32 | #include "common/math_util.h" | 22 | #include "common/math_util.h" |
| 33 | #include "common/param_package.h" | 23 | #include "common/param_package.h" |
| @@ -214,6 +204,40 @@ public: | |||
| 214 | sdl_controller.reset(controller); | 204 | sdl_controller.reset(controller); |
| 215 | } | 205 | } |
| 216 | 206 | ||
| 207 | bool IsJoyconLeft() const { | ||
| 208 | return std::strstr(GetControllerName().c_str(), "Joy-Con Left") != nullptr; | ||
| 209 | } | ||
| 210 | |||
| 211 | bool IsJoyconRight() const { | ||
| 212 | return std::strstr(GetControllerName().c_str(), "Joy-Con Right") != nullptr; | ||
| 213 | } | ||
| 214 | |||
| 215 | std::string GetControllerName() const { | ||
| 216 | if (sdl_controller) { | ||
| 217 | switch (SDL_GameControllerGetType(sdl_controller.get())) { | ||
| 218 | case SDL_CONTROLLER_TYPE_XBOX360: | ||
| 219 | return "XBox 360 Controller"; | ||
| 220 | case SDL_CONTROLLER_TYPE_XBOXONE: | ||
| 221 | return "XBox One Controller"; | ||
| 222 | default: | ||
| 223 | break; | ||
| 224 | } | ||
| 225 | const auto name = SDL_GameControllerName(sdl_controller.get()); | ||
| 226 | if (name) { | ||
| 227 | return name; | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | if (sdl_joystick) { | ||
| 232 | const auto name = SDL_JoystickName(sdl_joystick.get()); | ||
| 233 | if (name) { | ||
| 234 | return name; | ||
| 235 | } | ||
| 236 | } | ||
| 237 | |||
| 238 | return "Unknown"; | ||
| 239 | } | ||
| 240 | |||
| 217 | private: | 241 | private: |
| 218 | struct State { | 242 | struct State { |
| 219 | std::unordered_map<int, bool> buttons; | 243 | std::unordered_map<int, bool> buttons; |
| @@ -858,23 +882,42 @@ SDLState::~SDLState() { | |||
| 858 | std::vector<Common::ParamPackage> SDLState::GetInputDevices() { | 882 | std::vector<Common::ParamPackage> SDLState::GetInputDevices() { |
| 859 | std::scoped_lock lock(joystick_map_mutex); | 883 | std::scoped_lock lock(joystick_map_mutex); |
| 860 | std::vector<Common::ParamPackage> devices; | 884 | std::vector<Common::ParamPackage> devices; |
| 885 | std::unordered_map<int, std::shared_ptr<SDLJoystick>> joycon_pairs; | ||
| 886 | for (const auto& [key, value] : joystick_map) { | ||
| 887 | for (const auto& joystick : value) { | ||
| 888 | if (!joystick->GetSDLJoystick()) { | ||
| 889 | continue; | ||
| 890 | } | ||
| 891 | std::string name = | ||
| 892 | fmt::format("{} {}", joystick->GetControllerName(), joystick->GetPort()); | ||
| 893 | devices.emplace_back(Common::ParamPackage{ | ||
| 894 | {"class", "sdl"}, | ||
| 895 | {"display", std::move(name)}, | ||
| 896 | {"guid", joystick->GetGUID()}, | ||
| 897 | {"port", std::to_string(joystick->GetPort())}, | ||
| 898 | }); | ||
| 899 | if (joystick->IsJoyconLeft()) { | ||
| 900 | joycon_pairs.insert_or_assign(joystick->GetPort(), joystick); | ||
| 901 | } | ||
| 902 | } | ||
| 903 | } | ||
| 904 | |||
| 905 | // Add dual controllers | ||
| 861 | for (const auto& [key, value] : joystick_map) { | 906 | for (const auto& [key, value] : joystick_map) { |
| 862 | for (const auto& joystick : value) { | 907 | for (const auto& joystick : value) { |
| 863 | if (auto* const controller = joystick->GetSDLGameController()) { | 908 | if (joystick->IsJoyconRight()) { |
| 909 | if (!joycon_pairs.contains(joystick->GetPort())) { | ||
| 910 | continue; | ||
| 911 | } | ||
| 912 | const auto joystick2 = joycon_pairs.at(joystick->GetPort()); | ||
| 913 | |||
| 864 | std::string name = | 914 | std::string name = |
| 865 | fmt::format("{} {}", GetControllerName(controller), joystick->GetPort()); | 915 | fmt::format("{} {}", "Nintendo Dual Joy-Con", joystick->GetPort()); |
| 866 | devices.emplace_back(Common::ParamPackage{ | ||
| 867 | {"class", "sdl"}, | ||
| 868 | {"display", std::move(name)}, | ||
| 869 | {"guid", joystick->GetGUID()}, | ||
| 870 | {"port", std::to_string(joystick->GetPort())}, | ||
| 871 | }); | ||
| 872 | } else if (auto* const joy = joystick->GetSDLJoystick()) { | ||
| 873 | std::string name = fmt::format("{} {}", SDL_JoystickName(joy), joystick->GetPort()); | ||
| 874 | devices.emplace_back(Common::ParamPackage{ | 916 | devices.emplace_back(Common::ParamPackage{ |
| 875 | {"class", "sdl"}, | 917 | {"class", "sdl"}, |
| 876 | {"display", std::move(name)}, | 918 | {"display", std::move(name)}, |
| 877 | {"guid", joystick->GetGUID()}, | 919 | {"guid", joystick->GetGUID()}, |
| 920 | {"guid2", joystick2->GetGUID()}, | ||
| 878 | {"port", std::to_string(joystick->GetPort())}, | 921 | {"port", std::to_string(joystick->GetPort())}, |
| 879 | }); | 922 | }); |
| 880 | } | 923 | } |
| @@ -883,17 +926,6 @@ std::vector<Common::ParamPackage> SDLState::GetInputDevices() { | |||
| 883 | return devices; | 926 | return devices; |
| 884 | } | 927 | } |
| 885 | 928 | ||
| 886 | std::string SDLState::GetControllerName(SDL_GameController* controller) const { | ||
| 887 | switch (SDL_GameControllerGetType(controller)) { | ||
| 888 | case SDL_CONTROLLER_TYPE_XBOX360: | ||
| 889 | return "XBox 360 Controller"; | ||
| 890 | case SDL_CONTROLLER_TYPE_XBOXONE: | ||
| 891 | return "XBox One Controller"; | ||
| 892 | default: | ||
| 893 | return SDL_GameControllerName(controller); | ||
| 894 | } | ||
| 895 | } | ||
| 896 | |||
| 897 | namespace { | 929 | namespace { |
| 898 | Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis, | 930 | Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis, |
| 899 | float value = 0.1f) { | 931 | float value = 0.1f) { |
| @@ -1073,24 +1105,48 @@ ButtonMapping SDLState::GetButtonMappingForDevice(const Common::ParamPackage& pa | |||
| 1073 | return {}; | 1105 | return {}; |
| 1074 | } | 1106 | } |
| 1075 | const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); | 1107 | const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); |
| 1108 | |||
| 1076 | auto* controller = joystick->GetSDLGameController(); | 1109 | auto* controller = joystick->GetSDLGameController(); |
| 1077 | if (controller == nullptr) { | 1110 | if (controller == nullptr) { |
| 1078 | return {}; | 1111 | return {}; |
| 1079 | } | 1112 | } |
| 1080 | 1113 | ||
| 1081 | const bool invert = | ||
| 1082 | SDL_GameControllerGetType(controller) != SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO; | ||
| 1083 | |||
| 1084 | // This list is missing ZL/ZR since those are not considered buttons in SDL GameController. | 1114 | // This list is missing ZL/ZR since those are not considered buttons in SDL GameController. |
| 1085 | // We will add those afterwards | 1115 | // We will add those afterwards |
| 1086 | // This list also excludes Screenshot since theres not really a mapping for that | 1116 | // This list also excludes Screenshot since theres not really a mapping for that |
| 1087 | using ButtonBindings = | 1117 | ButtonBindings switch_to_sdl_button; |
| 1088 | std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerButton>, 17>; | 1118 | |
| 1089 | const ButtonBindings switch_to_sdl_button{{ | 1119 | if (SDL_GameControllerGetType(controller) == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) { |
| 1090 | {Settings::NativeButton::A, invert ? SDL_CONTROLLER_BUTTON_B : SDL_CONTROLLER_BUTTON_A}, | 1120 | switch_to_sdl_button = GetNintendoButtonBinding(joystick); |
| 1091 | {Settings::NativeButton::B, invert ? SDL_CONTROLLER_BUTTON_A : SDL_CONTROLLER_BUTTON_B}, | 1121 | } else { |
| 1092 | {Settings::NativeButton::X, invert ? SDL_CONTROLLER_BUTTON_Y : SDL_CONTROLLER_BUTTON_X}, | 1122 | switch_to_sdl_button = GetDefaultButtonBinding(); |
| 1093 | {Settings::NativeButton::Y, invert ? SDL_CONTROLLER_BUTTON_X : SDL_CONTROLLER_BUTTON_Y}, | 1123 | } |
| 1124 | |||
| 1125 | // Add the missing bindings for ZL/ZR | ||
| 1126 | static constexpr ZButtonBindings switch_to_sdl_axis{{ | ||
| 1127 | {Settings::NativeButton::ZL, SDL_CONTROLLER_AXIS_TRIGGERLEFT}, | ||
| 1128 | {Settings::NativeButton::ZR, SDL_CONTROLLER_AXIS_TRIGGERRIGHT}, | ||
| 1129 | }}; | ||
| 1130 | |||
| 1131 | // Parameters contain two joysticks return dual | ||
| 1132 | if (params.Has("guid2")) { | ||
| 1133 | const auto joystick2 = GetSDLJoystickByGUID(params.Get("guid2", ""), params.Get("port", 0)); | ||
| 1134 | |||
| 1135 | if (joystick2->GetSDLGameController() != nullptr) { | ||
| 1136 | return GetDualControllerMapping(joystick, joystick2, switch_to_sdl_button, | ||
| 1137 | switch_to_sdl_axis); | ||
| 1138 | } | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | return GetSingleControllerMapping(joystick, switch_to_sdl_button, switch_to_sdl_axis); | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | ButtonBindings SDLState::GetDefaultButtonBinding() const { | ||
| 1145 | return { | ||
| 1146 | std::pair{Settings::NativeButton::A, SDL_CONTROLLER_BUTTON_B}, | ||
| 1147 | {Settings::NativeButton::B, SDL_CONTROLLER_BUTTON_A}, | ||
| 1148 | {Settings::NativeButton::X, SDL_CONTROLLER_BUTTON_Y}, | ||
| 1149 | {Settings::NativeButton::Y, SDL_CONTROLLER_BUTTON_X}, | ||
| 1094 | {Settings::NativeButton::LStick, SDL_CONTROLLER_BUTTON_LEFTSTICK}, | 1150 | {Settings::NativeButton::LStick, SDL_CONTROLLER_BUTTON_LEFTSTICK}, |
| 1095 | {Settings::NativeButton::RStick, SDL_CONTROLLER_BUTTON_RIGHTSTICK}, | 1151 | {Settings::NativeButton::RStick, SDL_CONTROLLER_BUTTON_RIGHTSTICK}, |
| 1096 | {Settings::NativeButton::L, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, | 1152 | {Settings::NativeButton::L, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, |
| @@ -1104,18 +1160,51 @@ ButtonMapping SDLState::GetButtonMappingForDevice(const Common::ParamPackage& pa | |||
| 1104 | {Settings::NativeButton::SL, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, | 1160 | {Settings::NativeButton::SL, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, |
| 1105 | {Settings::NativeButton::SR, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, | 1161 | {Settings::NativeButton::SR, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, |
| 1106 | {Settings::NativeButton::Home, SDL_CONTROLLER_BUTTON_GUIDE}, | 1162 | {Settings::NativeButton::Home, SDL_CONTROLLER_BUTTON_GUIDE}, |
| 1107 | }}; | 1163 | }; |
| 1164 | } | ||
| 1108 | 1165 | ||
| 1109 | // Add the missing bindings for ZL/ZR | 1166 | ButtonBindings SDLState::GetNintendoButtonBinding( |
| 1110 | using ZBindings = | 1167 | const std::shared_ptr<SDLJoystick>& joystick) const { |
| 1111 | std::array<std::pair<Settings::NativeButton::Values, SDL_GameControllerAxis>, 2>; | 1168 | // Default SL/SR mapping for pro controllers |
| 1112 | static constexpr ZBindings switch_to_sdl_axis{{ | 1169 | auto sl_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; |
| 1113 | {Settings::NativeButton::ZL, SDL_CONTROLLER_AXIS_TRIGGERLEFT}, | 1170 | auto sr_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; |
| 1114 | {Settings::NativeButton::ZR, SDL_CONTROLLER_AXIS_TRIGGERRIGHT}, | 1171 | |
| 1115 | }}; | 1172 | if (joystick->IsJoyconLeft()) { |
| 1173 | sl_button = SDL_CONTROLLER_BUTTON_PADDLE2; | ||
| 1174 | sr_button = SDL_CONTROLLER_BUTTON_PADDLE4; | ||
| 1175 | } | ||
| 1176 | if (joystick->IsJoyconRight()) { | ||
| 1177 | sl_button = SDL_CONTROLLER_BUTTON_PADDLE3; | ||
| 1178 | sr_button = SDL_CONTROLLER_BUTTON_PADDLE1; | ||
| 1179 | } | ||
| 1116 | 1180 | ||
| 1181 | return { | ||
| 1182 | std::pair{Settings::NativeButton::A, SDL_CONTROLLER_BUTTON_A}, | ||
| 1183 | {Settings::NativeButton::B, SDL_CONTROLLER_BUTTON_B}, | ||
| 1184 | {Settings::NativeButton::X, SDL_CONTROLLER_BUTTON_X}, | ||
| 1185 | {Settings::NativeButton::Y, SDL_CONTROLLER_BUTTON_Y}, | ||
| 1186 | {Settings::NativeButton::LStick, SDL_CONTROLLER_BUTTON_LEFTSTICK}, | ||
| 1187 | {Settings::NativeButton::RStick, SDL_CONTROLLER_BUTTON_RIGHTSTICK}, | ||
| 1188 | {Settings::NativeButton::L, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, | ||
| 1189 | {Settings::NativeButton::R, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, | ||
| 1190 | {Settings::NativeButton::Plus, SDL_CONTROLLER_BUTTON_START}, | ||
| 1191 | {Settings::NativeButton::Minus, SDL_CONTROLLER_BUTTON_BACK}, | ||
| 1192 | {Settings::NativeButton::DLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT}, | ||
| 1193 | {Settings::NativeButton::DUp, SDL_CONTROLLER_BUTTON_DPAD_UP}, | ||
| 1194 | {Settings::NativeButton::DRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT}, | ||
| 1195 | {Settings::NativeButton::DDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN}, | ||
| 1196 | {Settings::NativeButton::SL, sl_button}, | ||
| 1197 | {Settings::NativeButton::SR, sr_button}, | ||
| 1198 | {Settings::NativeButton::Home, SDL_CONTROLLER_BUTTON_GUIDE}, | ||
| 1199 | }; | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | ButtonMapping SDLState::GetSingleControllerMapping( | ||
| 1203 | const std::shared_ptr<SDLJoystick>& joystick, const ButtonBindings& switch_to_sdl_button, | ||
| 1204 | const ZButtonBindings& switch_to_sdl_axis) const { | ||
| 1117 | ButtonMapping mapping; | 1205 | ButtonMapping mapping; |
| 1118 | mapping.reserve(switch_to_sdl_button.size() + switch_to_sdl_axis.size()); | 1206 | mapping.reserve(switch_to_sdl_button.size() + switch_to_sdl_axis.size()); |
| 1207 | auto* controller = joystick->GetSDLGameController(); | ||
| 1119 | 1208 | ||
| 1120 | for (const auto& [switch_button, sdl_button] : switch_to_sdl_button) { | 1209 | for (const auto& [switch_button, sdl_button] : switch_to_sdl_button) { |
| 1121 | const auto& binding = SDL_GameControllerGetBindForButton(controller, sdl_button); | 1210 | const auto& binding = SDL_GameControllerGetBindForButton(controller, sdl_button); |
| @@ -1133,11 +1222,68 @@ ButtonMapping SDLState::GetButtonMappingForDevice(const Common::ParamPackage& pa | |||
| 1133 | return mapping; | 1222 | return mapping; |
| 1134 | } | 1223 | } |
| 1135 | 1224 | ||
| 1225 | ButtonMapping SDLState::GetDualControllerMapping(const std::shared_ptr<SDLJoystick>& joystick, | ||
| 1226 | const std::shared_ptr<SDLJoystick>& joystick2, | ||
| 1227 | const ButtonBindings& switch_to_sdl_button, | ||
| 1228 | const ZButtonBindings& switch_to_sdl_axis) const { | ||
| 1229 | ButtonMapping mapping; | ||
| 1230 | mapping.reserve(switch_to_sdl_button.size() + switch_to_sdl_axis.size()); | ||
| 1231 | auto* controller = joystick->GetSDLGameController(); | ||
| 1232 | auto* controller2 = joystick2->GetSDLGameController(); | ||
| 1233 | |||
| 1234 | for (const auto& [switch_button, sdl_button] : switch_to_sdl_button) { | ||
| 1235 | if (IsButtonOnLeftSide(switch_button)) { | ||
| 1236 | const auto& binding = SDL_GameControllerGetBindForButton(controller2, sdl_button); | ||
| 1237 | mapping.insert_or_assign( | ||
| 1238 | switch_button, | ||
| 1239 | BuildParamPackageForBinding(joystick2->GetPort(), joystick2->GetGUID(), binding)); | ||
| 1240 | continue; | ||
| 1241 | } | ||
| 1242 | const auto& binding = SDL_GameControllerGetBindForButton(controller, sdl_button); | ||
| 1243 | mapping.insert_or_assign( | ||
| 1244 | switch_button, | ||
| 1245 | BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding)); | ||
| 1246 | } | ||
| 1247 | for (const auto& [switch_button, sdl_axis] : switch_to_sdl_axis) { | ||
| 1248 | if (IsButtonOnLeftSide(switch_button)) { | ||
| 1249 | const auto& binding = SDL_GameControllerGetBindForAxis(controller2, sdl_axis); | ||
| 1250 | mapping.insert_or_assign( | ||
| 1251 | switch_button, | ||
| 1252 | BuildParamPackageForBinding(joystick2->GetPort(), joystick2->GetGUID(), binding)); | ||
| 1253 | continue; | ||
| 1254 | } | ||
| 1255 | const auto& binding = SDL_GameControllerGetBindForAxis(controller, sdl_axis); | ||
| 1256 | mapping.insert_or_assign( | ||
| 1257 | switch_button, | ||
| 1258 | BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding)); | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | return mapping; | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | bool SDLState::IsButtonOnLeftSide(Settings::NativeButton::Values button) const { | ||
| 1265 | switch (button) { | ||
| 1266 | case Settings::NativeButton::DDown: | ||
| 1267 | case Settings::NativeButton::DLeft: | ||
| 1268 | case Settings::NativeButton::DRight: | ||
| 1269 | case Settings::NativeButton::DUp: | ||
| 1270 | case Settings::NativeButton::L: | ||
| 1271 | case Settings::NativeButton::LStick: | ||
| 1272 | case Settings::NativeButton::Minus: | ||
| 1273 | case Settings::NativeButton::Screenshot: | ||
| 1274 | case Settings::NativeButton::ZL: | ||
| 1275 | return true; | ||
| 1276 | default: | ||
| 1277 | return false; | ||
| 1278 | } | ||
| 1279 | } | ||
| 1280 | |||
| 1136 | AnalogMapping SDLState::GetAnalogMappingForDevice(const Common::ParamPackage& params) { | 1281 | AnalogMapping SDLState::GetAnalogMappingForDevice(const Common::ParamPackage& params) { |
| 1137 | if (!params.Has("guid") || !params.Has("port")) { | 1282 | if (!params.Has("guid") || !params.Has("port")) { |
| 1138 | return {}; | 1283 | return {}; |
| 1139 | } | 1284 | } |
| 1140 | const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); | 1285 | const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); |
| 1286 | const auto joystick2 = GetSDLJoystickByGUID(params.Get("guid2", ""), params.Get("port", 0)); | ||
| 1141 | auto* controller = joystick->GetSDLGameController(); | 1287 | auto* controller = joystick->GetSDLGameController(); |
| 1142 | if (controller == nullptr) { | 1288 | if (controller == nullptr) { |
| 1143 | return {}; | 1289 | return {}; |
| @@ -1148,10 +1294,17 @@ AnalogMapping SDLState::GetAnalogMappingForDevice(const Common::ParamPackage& pa | |||
| 1148 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); | 1294 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); |
| 1149 | const auto& binding_left_y = | 1295 | const auto& binding_left_y = |
| 1150 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); | 1296 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); |
| 1151 | mapping.insert_or_assign(Settings::NativeAnalog::LStick, | 1297 | if (params.Has("guid2")) { |
| 1152 | BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), | 1298 | mapping.insert_or_assign( |
| 1153 | binding_left_x.value.axis, | 1299 | Settings::NativeAnalog::LStick, |
| 1154 | binding_left_y.value.axis)); | 1300 | BuildParamPackageForAnalog(joystick2->GetPort(), joystick2->GetGUID(), |
| 1301 | binding_left_x.value.axis, binding_left_y.value.axis)); | ||
| 1302 | } else { | ||
| 1303 | mapping.insert_or_assign( | ||
| 1304 | Settings::NativeAnalog::LStick, | ||
| 1305 | BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), | ||
| 1306 | binding_left_x.value.axis, binding_left_y.value.axis)); | ||
| 1307 | } | ||
| 1155 | const auto& binding_right_x = | 1308 | const auto& binding_right_x = |
| 1156 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); | 1309 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); |
| 1157 | const auto& binding_right_y = | 1310 | const auto& binding_right_y = |
| @@ -1168,20 +1321,32 @@ MotionMapping SDLState::GetMotionMappingForDevice(const Common::ParamPackage& pa | |||
| 1168 | return {}; | 1321 | return {}; |
| 1169 | } | 1322 | } |
| 1170 | const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); | 1323 | const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); |
| 1324 | const auto joystick2 = GetSDLJoystickByGUID(params.Get("guid2", ""), params.Get("port", 0)); | ||
| 1171 | auto* controller = joystick->GetSDLGameController(); | 1325 | auto* controller = joystick->GetSDLGameController(); |
| 1172 | if (controller == nullptr) { | 1326 | if (controller == nullptr) { |
| 1173 | return {}; | 1327 | return {}; |
| 1174 | } | 1328 | } |
| 1175 | 1329 | ||
| 1330 | MotionMapping mapping = {}; | ||
| 1176 | joystick->EnableMotion(); | 1331 | joystick->EnableMotion(); |
| 1177 | 1332 | ||
| 1178 | if (!joystick->HasGyro() && !joystick->HasAccel()) { | 1333 | if (joystick->HasGyro() || joystick->HasAccel()) { |
| 1179 | return {}; | 1334 | mapping.insert_or_assign(Settings::NativeMotion::MotionRight, |
| 1335 | BuildMotionParam(joystick->GetPort(), joystick->GetGUID())); | ||
| 1336 | } | ||
| 1337 | if (params.Has("guid2")) { | ||
| 1338 | joystick2->EnableMotion(); | ||
| 1339 | if (joystick2->HasGyro() || joystick2->HasAccel()) { | ||
| 1340 | mapping.insert_or_assign(Settings::NativeMotion::MotionLeft, | ||
| 1341 | BuildMotionParam(joystick2->GetPort(), joystick2->GetGUID())); | ||
| 1342 | } | ||
| 1343 | } else { | ||
| 1344 | if (joystick->HasGyro() || joystick->HasAccel()) { | ||
| 1345 | mapping.insert_or_assign(Settings::NativeMotion::MotionLeft, | ||
| 1346 | BuildMotionParam(joystick->GetPort(), joystick->GetGUID())); | ||
| 1347 | } | ||
| 1180 | } | 1348 | } |
| 1181 | 1349 | ||
| 1182 | MotionMapping mapping = {}; | ||
| 1183 | mapping.insert_or_assign(Settings::NativeMotion::MotionLeft, | ||
| 1184 | BuildMotionParam(joystick->GetPort(), joystick->GetGUID())); | ||
| 1185 | return mapping; | 1350 | return mapping; |
| 1186 | } | 1351 | } |
| 1187 | namespace Polling { | 1352 | namespace Polling { |