diff options
Diffstat (limited to 'src/input_common/drivers/sdl_driver.cpp')
| -rw-r--r-- | src/input_common/drivers/sdl_driver.cpp | 167 |
1 files changed, 118 insertions, 49 deletions
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index 5cf1987ad..b72e4b397 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | // Copyright 2018 Citra Emulator Project | 1 | // SPDX-FileCopyrightText: 2018 Citra Emulator Project |
| 2 | // Licensed under GPLv2 or any later version | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | // Refer to the license.txt file included. | ||
| 4 | 3 | ||
| 5 | #include "common/logging/log.h" | 4 | #include "common/logging/log.h" |
| 6 | #include "common/math_util.h" | 5 | #include "common/math_util.h" |
| @@ -13,11 +12,11 @@ | |||
| 13 | namespace InputCommon { | 12 | namespace InputCommon { |
| 14 | 13 | ||
| 15 | namespace { | 14 | namespace { |
| 16 | std::string GetGUID(SDL_Joystick* joystick) { | 15 | Common::UUID GetGUID(SDL_Joystick* joystick) { |
| 17 | const SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); | 16 | const SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); |
| 18 | char guid_str[33]; | 17 | std::array<u8, 16> data{}; |
| 19 | SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str)); | 18 | std::memcpy(data.data(), guid.data, sizeof(data)); |
| 20 | return guid_str; | 19 | return Common::UUID{data}; |
| 21 | } | 20 | } |
| 22 | } // Anonymous namespace | 21 | } // Anonymous namespace |
| 23 | 22 | ||
| @@ -31,9 +30,9 @@ static int SDLEventWatcher(void* user_data, SDL_Event* event) { | |||
| 31 | 30 | ||
| 32 | class SDLJoystick { | 31 | class SDLJoystick { |
| 33 | public: | 32 | public: |
| 34 | SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick, | 33 | SDLJoystick(Common::UUID guid_, int port_, SDL_Joystick* joystick, |
| 35 | SDL_GameController* game_controller) | 34 | SDL_GameController* game_controller) |
| 36 | : guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose}, | 35 | : guid{guid_}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose}, |
| 37 | sdl_controller{game_controller, &SDL_GameControllerClose} { | 36 | sdl_controller{game_controller, &SDL_GameControllerClose} { |
| 38 | EnableMotion(); | 37 | EnableMotion(); |
| 39 | } | 38 | } |
| @@ -41,13 +40,13 @@ public: | |||
| 41 | void EnableMotion() { | 40 | void EnableMotion() { |
| 42 | if (sdl_controller) { | 41 | if (sdl_controller) { |
| 43 | SDL_GameController* controller = sdl_controller.get(); | 42 | SDL_GameController* controller = sdl_controller.get(); |
| 44 | if (SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL) && !has_accel) { | 43 | has_accel = SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL); |
| 44 | has_gyro = SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO); | ||
| 45 | if (has_accel) { | ||
| 45 | SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_TRUE); | 46 | SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_TRUE); |
| 46 | has_accel = true; | ||
| 47 | } | 47 | } |
| 48 | if (SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO) && !has_gyro) { | 48 | if (has_gyro) { |
| 49 | SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); | 49 | SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); |
| 50 | has_gyro = true; | ||
| 51 | } | 50 | } |
| 52 | } | 51 | } |
| 53 | } | 52 | } |
| @@ -62,7 +61,7 @@ public: | |||
| 62 | 61 | ||
| 63 | bool UpdateMotion(SDL_ControllerSensorEvent event) { | 62 | bool UpdateMotion(SDL_ControllerSensorEvent event) { |
| 64 | constexpr float gravity_constant = 9.80665f; | 63 | constexpr float gravity_constant = 9.80665f; |
| 65 | std::lock_guard lock{mutex}; | 64 | std::scoped_lock lock{mutex}; |
| 66 | const u64 time_difference = event.timestamp - last_motion_update; | 65 | const u64 time_difference = event.timestamp - last_motion_update; |
| 67 | last_motion_update = event.timestamp; | 66 | last_motion_update = event.timestamp; |
| 68 | switch (event.sensor) { | 67 | switch (event.sensor) { |
| @@ -120,7 +119,7 @@ public: | |||
| 120 | */ | 119 | */ |
| 121 | const PadIdentifier GetPadIdentifier() const { | 120 | const PadIdentifier GetPadIdentifier() const { |
| 122 | return { | 121 | return { |
| 123 | .guid = Common::UUID{guid}, | 122 | .guid = guid, |
| 124 | .port = static_cast<std::size_t>(port), | 123 | .port = static_cast<std::size_t>(port), |
| 125 | .pad = 0, | 124 | .pad = 0, |
| 126 | }; | 125 | }; |
| @@ -129,7 +128,7 @@ public: | |||
| 129 | /** | 128 | /** |
| 130 | * The guid of the joystick | 129 | * The guid of the joystick |
| 131 | */ | 130 | */ |
| 132 | const std::string& GetGUID() const { | 131 | const Common::UUID& GetGUID() const { |
| 133 | return guid; | 132 | return guid; |
| 134 | } | 133 | } |
| 135 | 134 | ||
| @@ -175,22 +174,23 @@ public: | |||
| 175 | return false; | 174 | return false; |
| 176 | } | 175 | } |
| 177 | 176 | ||
| 178 | BatteryLevel GetBatteryLevel() { | 177 | Common::Input::BatteryLevel GetBatteryLevel() { |
| 179 | const auto level = SDL_JoystickCurrentPowerLevel(sdl_joystick.get()); | 178 | const auto level = SDL_JoystickCurrentPowerLevel(sdl_joystick.get()); |
| 180 | switch (level) { | 179 | switch (level) { |
| 181 | case SDL_JOYSTICK_POWER_EMPTY: | 180 | case SDL_JOYSTICK_POWER_EMPTY: |
| 182 | return BatteryLevel::Empty; | 181 | return Common::Input::BatteryLevel::Empty; |
| 183 | case SDL_JOYSTICK_POWER_LOW: | 182 | case SDL_JOYSTICK_POWER_LOW: |
| 184 | return BatteryLevel::Low; | 183 | return Common::Input::BatteryLevel::Low; |
| 185 | case SDL_JOYSTICK_POWER_MEDIUM: | 184 | case SDL_JOYSTICK_POWER_MEDIUM: |
| 186 | return BatteryLevel::Medium; | 185 | return Common::Input::BatteryLevel::Medium; |
| 187 | case SDL_JOYSTICK_POWER_FULL: | 186 | case SDL_JOYSTICK_POWER_FULL: |
| 188 | case SDL_JOYSTICK_POWER_MAX: | 187 | case SDL_JOYSTICK_POWER_MAX: |
| 189 | return BatteryLevel::Full; | 188 | return Common::Input::BatteryLevel::Full; |
| 190 | case SDL_JOYSTICK_POWER_UNKNOWN: | ||
| 191 | case SDL_JOYSTICK_POWER_WIRED: | 189 | case SDL_JOYSTICK_POWER_WIRED: |
| 190 | return Common::Input::BatteryLevel::Charging; | ||
| 191 | case SDL_JOYSTICK_POWER_UNKNOWN: | ||
| 192 | default: | 192 | default: |
| 193 | return BatteryLevel::Charging; | 193 | return Common::Input::BatteryLevel::None; |
| 194 | } | 194 | } |
| 195 | } | 195 | } |
| 196 | 196 | ||
| @@ -227,7 +227,7 @@ public: | |||
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | private: | 229 | private: |
| 230 | std::string guid; | 230 | Common::UUID guid; |
| 231 | int port; | 231 | int port; |
| 232 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; | 232 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; |
| 233 | std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; | 233 | std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; |
| @@ -239,8 +239,8 @@ private: | |||
| 239 | BasicMotion motion; | 239 | BasicMotion motion; |
| 240 | }; | 240 | }; |
| 241 | 241 | ||
| 242 | std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickByGUID(const std::string& guid, int port) { | 242 | std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickByGUID(const Common::UUID& guid, int port) { |
| 243 | std::lock_guard lock{joystick_map_mutex}; | 243 | std::scoped_lock lock{joystick_map_mutex}; |
| 244 | const auto it = joystick_map.find(guid); | 244 | const auto it = joystick_map.find(guid); |
| 245 | 245 | ||
| 246 | if (it != joystick_map.end()) { | 246 | if (it != joystick_map.end()) { |
| @@ -258,11 +258,15 @@ std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickByGUID(const std::string& | |||
| 258 | return joystick_map[guid].emplace_back(std::move(joystick)); | 258 | return joystick_map[guid].emplace_back(std::move(joystick)); |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickByGUID(const std::string& guid, int port) { | ||
| 262 | return GetSDLJoystickByGUID(Common::UUID{guid}, port); | ||
| 263 | } | ||
| 264 | |||
| 261 | std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) { | 265 | std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) { |
| 262 | auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id); | 266 | auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id); |
| 263 | const std::string guid = GetGUID(sdl_joystick); | 267 | const auto guid = GetGUID(sdl_joystick); |
| 264 | 268 | ||
| 265 | std::lock_guard lock{joystick_map_mutex}; | 269 | std::scoped_lock lock{joystick_map_mutex}; |
| 266 | const auto map_it = joystick_map.find(guid); | 270 | const auto map_it = joystick_map.find(guid); |
| 267 | 271 | ||
| 268 | if (map_it == joystick_map.end()) { | 272 | if (map_it == joystick_map.end()) { |
| @@ -294,13 +298,14 @@ void SDLDriver::InitJoystick(int joystick_index) { | |||
| 294 | return; | 298 | return; |
| 295 | } | 299 | } |
| 296 | 300 | ||
| 297 | const std::string guid = GetGUID(sdl_joystick); | 301 | const auto guid = GetGUID(sdl_joystick); |
| 298 | 302 | ||
| 299 | std::lock_guard lock{joystick_map_mutex}; | 303 | std::scoped_lock lock{joystick_map_mutex}; |
| 300 | if (joystick_map.find(guid) == joystick_map.end()) { | 304 | if (joystick_map.find(guid) == joystick_map.end()) { |
| 301 | auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_gamecontroller); | 305 | auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_gamecontroller); |
| 302 | PreSetController(joystick->GetPadIdentifier()); | 306 | PreSetController(joystick->GetPadIdentifier()); |
| 303 | SetBattery(joystick->GetPadIdentifier(), joystick->GetBatteryLevel()); | 307 | SetBattery(joystick->GetPadIdentifier(), joystick->GetBatteryLevel()); |
| 308 | joystick->EnableMotion(); | ||
| 304 | joystick_map[guid].emplace_back(std::move(joystick)); | 309 | joystick_map[guid].emplace_back(std::move(joystick)); |
| 305 | return; | 310 | return; |
| 306 | } | 311 | } |
| @@ -312,6 +317,7 @@ void SDLDriver::InitJoystick(int joystick_index) { | |||
| 312 | 317 | ||
| 313 | if (joystick_it != joystick_guid_list.end()) { | 318 | if (joystick_it != joystick_guid_list.end()) { |
| 314 | (*joystick_it)->SetSDLJoystick(sdl_joystick, sdl_gamecontroller); | 319 | (*joystick_it)->SetSDLJoystick(sdl_joystick, sdl_gamecontroller); |
| 320 | (*joystick_it)->EnableMotion(); | ||
| 315 | return; | 321 | return; |
| 316 | } | 322 | } |
| 317 | 323 | ||
| @@ -319,13 +325,14 @@ void SDLDriver::InitJoystick(int joystick_index) { | |||
| 319 | auto joystick = std::make_shared<SDLJoystick>(guid, port, sdl_joystick, sdl_gamecontroller); | 325 | auto joystick = std::make_shared<SDLJoystick>(guid, port, sdl_joystick, sdl_gamecontroller); |
| 320 | PreSetController(joystick->GetPadIdentifier()); | 326 | PreSetController(joystick->GetPadIdentifier()); |
| 321 | SetBattery(joystick->GetPadIdentifier(), joystick->GetBatteryLevel()); | 327 | SetBattery(joystick->GetPadIdentifier(), joystick->GetBatteryLevel()); |
| 328 | joystick->EnableMotion(); | ||
| 322 | joystick_guid_list.emplace_back(std::move(joystick)); | 329 | joystick_guid_list.emplace_back(std::move(joystick)); |
| 323 | } | 330 | } |
| 324 | 331 | ||
| 325 | void SDLDriver::CloseJoystick(SDL_Joystick* sdl_joystick) { | 332 | void SDLDriver::CloseJoystick(SDL_Joystick* sdl_joystick) { |
| 326 | const std::string guid = GetGUID(sdl_joystick); | 333 | const auto guid = GetGUID(sdl_joystick); |
| 327 | 334 | ||
| 328 | std::lock_guard lock{joystick_map_mutex}; | 335 | std::scoped_lock lock{joystick_map_mutex}; |
| 329 | // This call to guid is safe since the joystick is guaranteed to be in the map | 336 | // This call to guid is safe since the joystick is guaranteed to be in the map |
| 330 | const auto& joystick_guid_list = joystick_map[guid]; | 337 | const auto& joystick_guid_list = joystick_map[guid]; |
| 331 | const auto joystick_it = std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(), | 338 | const auto joystick_it = std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(), |
| @@ -351,6 +358,8 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { | |||
| 351 | if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { | 358 | if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { |
| 352 | const PadIdentifier identifier = joystick->GetPadIdentifier(); | 359 | const PadIdentifier identifier = joystick->GetPadIdentifier(); |
| 353 | SetButton(identifier, event.jbutton.button, true); | 360 | SetButton(identifier, event.jbutton.button, true); |
| 361 | // Battery doesn't trigger an event so just update every button press | ||
| 362 | SetBattery(identifier, joystick->GetBatteryLevel()); | ||
| 354 | } | 363 | } |
| 355 | break; | 364 | break; |
| 356 | } | 365 | } |
| @@ -389,7 +398,7 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { | |||
| 389 | } | 398 | } |
| 390 | 399 | ||
| 391 | void SDLDriver::CloseJoysticks() { | 400 | void SDLDriver::CloseJoysticks() { |
| 392 | std::lock_guard lock{joystick_map_mutex}; | 401 | std::scoped_lock lock{joystick_map_mutex}; |
| 393 | joystick_map.clear(); | 402 | joystick_map.clear(); |
| 394 | } | 403 | } |
| 395 | 404 | ||
| @@ -427,13 +436,21 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en | |||
| 427 | initialized = true; | 436 | initialized = true; |
| 428 | if (start_thread) { | 437 | if (start_thread) { |
| 429 | poll_thread = std::thread([this] { | 438 | poll_thread = std::thread([this] { |
| 430 | Common::SetCurrentThreadName("yuzu:input:SDL"); | 439 | Common::SetCurrentThreadName("SDL_MainLoop"); |
| 431 | using namespace std::chrono_literals; | 440 | using namespace std::chrono_literals; |
| 432 | while (initialized) { | 441 | while (initialized) { |
| 433 | SDL_PumpEvents(); | 442 | SDL_PumpEvents(); |
| 434 | std::this_thread::sleep_for(1ms); | 443 | std::this_thread::sleep_for(1ms); |
| 435 | } | 444 | } |
| 436 | }); | 445 | }); |
| 446 | vibration_thread = std::thread([this] { | ||
| 447 | Common::SetCurrentThreadName("SDL_Vibration"); | ||
| 448 | using namespace std::chrono_literals; | ||
| 449 | while (initialized) { | ||
| 450 | SendVibrations(); | ||
| 451 | std::this_thread::sleep_for(10ms); | ||
| 452 | } | ||
| 453 | }); | ||
| 437 | } | 454 | } |
| 438 | // Because the events for joystick connection happens before we have our event watcher added, we | 455 | // Because the events for joystick connection happens before we have our event watcher added, we |
| 439 | // can just open all the joysticks right here | 456 | // can just open all the joysticks right here |
| @@ -449,6 +466,7 @@ SDLDriver::~SDLDriver() { | |||
| 449 | initialized = false; | 466 | initialized = false; |
| 450 | if (start_thread) { | 467 | if (start_thread) { |
| 451 | poll_thread.join(); | 468 | poll_thread.join(); |
| 469 | vibration_thread.join(); | ||
| 452 | SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); | 470 | SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); |
| 453 | } | 471 | } |
| 454 | } | 472 | } |
| @@ -466,7 +484,7 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const { | |||
| 466 | devices.emplace_back(Common::ParamPackage{ | 484 | devices.emplace_back(Common::ParamPackage{ |
| 467 | {"engine", GetEngineName()}, | 485 | {"engine", GetEngineName()}, |
| 468 | {"display", std::move(name)}, | 486 | {"display", std::move(name)}, |
| 469 | {"guid", joystick->GetGUID()}, | 487 | {"guid", joystick->GetGUID().RawString()}, |
| 470 | {"port", std::to_string(joystick->GetPort())}, | 488 | {"port", std::to_string(joystick->GetPort())}, |
| 471 | }); | 489 | }); |
| 472 | if (joystick->IsJoyconLeft()) { | 490 | if (joystick->IsJoyconLeft()) { |
| @@ -489,8 +507,8 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const { | |||
| 489 | devices.emplace_back(Common::ParamPackage{ | 507 | devices.emplace_back(Common::ParamPackage{ |
| 490 | {"engine", GetEngineName()}, | 508 | {"engine", GetEngineName()}, |
| 491 | {"display", std::move(name)}, | 509 | {"display", std::move(name)}, |
| 492 | {"guid", joystick->GetGUID()}, | 510 | {"guid", joystick->GetGUID().RawString()}, |
| 493 | {"guid2", joystick2->GetGUID()}, | 511 | {"guid2", joystick2->GetGUID().RawString()}, |
| 494 | {"port", std::to_string(joystick->GetPort())}, | 512 | {"port", std::to_string(joystick->GetPort())}, |
| 495 | }); | 513 | }); |
| 496 | } | 514 | } |
| @@ -528,57 +546,75 @@ Common::Input::VibrationError SDLDriver::SetRumble( | |||
| 528 | .type = Common::Input::VibrationAmplificationType::Exponential, | 546 | .type = Common::Input::VibrationAmplificationType::Exponential, |
| 529 | }; | 547 | }; |
| 530 | 548 | ||
| 531 | if (!joystick->RumblePlay(new_vibration)) { | 549 | if (vibration.type == Common::Input::VibrationAmplificationType::Test) { |
| 532 | return Common::Input::VibrationError::Unknown; | 550 | if (!joystick->RumblePlay(new_vibration)) { |
| 551 | return Common::Input::VibrationError::Unknown; | ||
| 552 | } | ||
| 553 | return Common::Input::VibrationError::None; | ||
| 533 | } | 554 | } |
| 534 | 555 | ||
| 556 | vibration_queue.Push(VibrationRequest{ | ||
| 557 | .identifier = identifier, | ||
| 558 | .vibration = new_vibration, | ||
| 559 | }); | ||
| 560 | |||
| 535 | return Common::Input::VibrationError::None; | 561 | return Common::Input::VibrationError::None; |
| 536 | } | 562 | } |
| 537 | 563 | ||
| 538 | Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid, | 564 | void SDLDriver::SendVibrations() { |
| 565 | while (!vibration_queue.Empty()) { | ||
| 566 | VibrationRequest request; | ||
| 567 | vibration_queue.Pop(request); | ||
| 568 | const auto joystick = GetSDLJoystickByGUID(request.identifier.guid.RawString(), | ||
| 569 | static_cast<int>(request.identifier.port)); | ||
| 570 | joystick->RumblePlay(request.vibration); | ||
| 571 | } | ||
| 572 | } | ||
| 573 | |||
| 574 | Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, const Common::UUID& guid, | ||
| 539 | s32 axis, float value) const { | 575 | s32 axis, float value) const { |
| 540 | Common::ParamPackage params{}; | 576 | Common::ParamPackage params{}; |
| 541 | params.Set("engine", GetEngineName()); | 577 | params.Set("engine", GetEngineName()); |
| 542 | params.Set("port", port); | 578 | params.Set("port", port); |
| 543 | params.Set("guid", std::move(guid)); | 579 | params.Set("guid", guid.RawString()); |
| 544 | params.Set("axis", axis); | 580 | params.Set("axis", axis); |
| 545 | params.Set("threshold", "0.5"); | 581 | params.Set("threshold", "0.5"); |
| 546 | params.Set("invert", value < 0 ? "-" : "+"); | 582 | params.Set("invert", value < 0 ? "-" : "+"); |
| 547 | return params; | 583 | return params; |
| 548 | } | 584 | } |
| 549 | 585 | ||
| 550 | Common::ParamPackage SDLDriver::BuildButtonParamPackageForButton(int port, std::string guid, | 586 | Common::ParamPackage SDLDriver::BuildButtonParamPackageForButton(int port, const Common::UUID& guid, |
| 551 | s32 button) const { | 587 | s32 button) const { |
| 552 | Common::ParamPackage params{}; | 588 | Common::ParamPackage params{}; |
| 553 | params.Set("engine", GetEngineName()); | 589 | params.Set("engine", GetEngineName()); |
| 554 | params.Set("port", port); | 590 | params.Set("port", port); |
| 555 | params.Set("guid", std::move(guid)); | 591 | params.Set("guid", guid.RawString()); |
| 556 | params.Set("button", button); | 592 | params.Set("button", button); |
| 557 | return params; | 593 | return params; |
| 558 | } | 594 | } |
| 559 | 595 | ||
| 560 | Common::ParamPackage SDLDriver::BuildHatParamPackageForButton(int port, std::string guid, s32 hat, | 596 | Common::ParamPackage SDLDriver::BuildHatParamPackageForButton(int port, const Common::UUID& guid, |
| 561 | u8 value) const { | 597 | s32 hat, u8 value) const { |
| 562 | Common::ParamPackage params{}; | 598 | Common::ParamPackage params{}; |
| 563 | params.Set("engine", GetEngineName()); | 599 | params.Set("engine", GetEngineName()); |
| 564 | params.Set("port", port); | 600 | params.Set("port", port); |
| 565 | params.Set("guid", std::move(guid)); | 601 | params.Set("guid", guid.RawString()); |
| 566 | params.Set("hat", hat); | 602 | params.Set("hat", hat); |
| 567 | params.Set("direction", GetHatButtonName(value)); | 603 | params.Set("direction", GetHatButtonName(value)); |
| 568 | return params; | 604 | return params; |
| 569 | } | 605 | } |
| 570 | 606 | ||
| 571 | Common::ParamPackage SDLDriver::BuildMotionParam(int port, std::string guid) const { | 607 | Common::ParamPackage SDLDriver::BuildMotionParam(int port, const Common::UUID& guid) const { |
| 572 | Common::ParamPackage params{}; | 608 | Common::ParamPackage params{}; |
| 573 | params.Set("engine", GetEngineName()); | 609 | params.Set("engine", GetEngineName()); |
| 574 | params.Set("motion", 0); | 610 | params.Set("motion", 0); |
| 575 | params.Set("port", port); | 611 | params.Set("port", port); |
| 576 | params.Set("guid", std::move(guid)); | 612 | params.Set("guid", guid.RawString()); |
| 577 | return params; | 613 | return params; |
| 578 | } | 614 | } |
| 579 | 615 | ||
| 580 | Common::ParamPackage SDLDriver::BuildParamPackageForBinding( | 616 | Common::ParamPackage SDLDriver::BuildParamPackageForBinding( |
| 581 | int port, const std::string& guid, const SDL_GameControllerButtonBind& binding) const { | 617 | int port, const Common::UUID& guid, const SDL_GameControllerButtonBind& binding) const { |
| 582 | switch (binding.bindType) { | 618 | switch (binding.bindType) { |
| 583 | case SDL_CONTROLLER_BINDTYPE_NONE: | 619 | case SDL_CONTROLLER_BINDTYPE_NONE: |
| 584 | break; | 620 | break; |
| @@ -931,4 +967,37 @@ u8 SDLDriver::GetHatButtonId(const std::string& direction_name) const { | |||
| 931 | return direction; | 967 | return direction; |
| 932 | } | 968 | } |
| 933 | 969 | ||
| 970 | bool SDLDriver::IsStickInverted(const Common::ParamPackage& params) { | ||
| 971 | if (!params.Has("guid") || !params.Has("port")) { | ||
| 972 | return false; | ||
| 973 | } | ||
| 974 | const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); | ||
| 975 | if (joystick == nullptr) { | ||
| 976 | return false; | ||
| 977 | } | ||
| 978 | auto* controller = joystick->GetSDLGameController(); | ||
| 979 | if (controller == nullptr) { | ||
| 980 | return false; | ||
| 981 | } | ||
| 982 | |||
| 983 | const auto& axis_x = params.Get("axis_x", 0); | ||
| 984 | const auto& axis_y = params.Get("axis_y", 0); | ||
| 985 | const auto& binding_left_x = | ||
| 986 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); | ||
| 987 | const auto& binding_right_x = | ||
| 988 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); | ||
| 989 | const auto& binding_left_y = | ||
| 990 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); | ||
| 991 | const auto& binding_right_y = | ||
| 992 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); | ||
| 993 | |||
| 994 | if (axis_x != binding_left_y.value.axis && axis_x != binding_right_y.value.axis) { | ||
| 995 | return false; | ||
| 996 | } | ||
| 997 | if (axis_y != binding_left_x.value.axis && axis_y != binding_right_x.value.axis) { | ||
| 998 | return false; | ||
| 999 | } | ||
| 1000 | return true; | ||
| 1001 | } | ||
| 1002 | |||
| 934 | } // namespace InputCommon | 1003 | } // namespace InputCommon |