summaryrefslogtreecommitdiff
path: root/src/input_common/drivers/sdl_driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/drivers/sdl_driver.cpp')
-rw-r--r--src/input_common/drivers/sdl_driver.cpp95
1 files changed, 69 insertions, 26 deletions
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp
index 4818bb744..5c20b3426 100644
--- a/src/input_common/drivers/sdl_driver.cpp
+++ b/src/input_common/drivers/sdl_driver.cpp
@@ -40,25 +40,26 @@ public:
40 } 40 }
41 41
42 void EnableMotion() { 42 void EnableMotion() {
43 if (sdl_controller) { 43 if (!sdl_controller) {
44 SDL_GameController* controller = sdl_controller.get(); 44 return;
45 has_accel = SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL) == SDL_TRUE; 45 }
46 has_gyro = SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO) == SDL_TRUE; 46 SDL_GameController* controller = sdl_controller.get();
47 if (has_accel) { 47 if (HasMotion()) {
48 SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_TRUE); 48 SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_FALSE);
49 } 49 SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_FALSE);
50 if (has_gyro) { 50 }
51 SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); 51 has_accel = SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL) == SDL_TRUE;
52 } 52 has_gyro = SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO) == SDL_TRUE;
53 if (has_accel) {
54 SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_TRUE);
55 }
56 if (has_gyro) {
57 SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE);
53 } 58 }
54 } 59 }
55 60
56 bool HasGyro() const { 61 bool HasMotion() const {
57 return has_gyro; 62 return has_gyro || has_accel;
58 }
59
60 bool HasAccel() const {
61 return has_accel;
62 } 63 }
63 64
64 bool UpdateMotion(SDL_ControllerSensorEvent event) { 65 bool UpdateMotion(SDL_ControllerSensorEvent event) {
@@ -85,6 +86,20 @@ public:
85 if (time_difference == 0) { 86 if (time_difference == 0) {
86 return false; 87 return false;
87 } 88 }
89
90 // Motion data is invalid
91 if (motion.accel_x == 0 && motion.gyro_x == 0 && motion.accel_y == 0 &&
92 motion.gyro_y == 0 && motion.accel_z == 0 && motion.gyro_z == 0) {
93 if (motion_error_count++ < 200) {
94 return false;
95 }
96 // Try restarting the sensor
97 motion_error_count = 0;
98 EnableMotion();
99 return false;
100 }
101
102 motion_error_count = 0;
88 motion.delta_timestamp = time_difference * 1000; 103 motion.delta_timestamp = time_difference * 1000;
89 return true; 104 return true;
90 } 105 }
@@ -250,6 +265,7 @@ private:
250 mutable std::mutex mutex; 265 mutable std::mutex mutex;
251 266
252 u64 last_motion_update{}; 267 u64 last_motion_update{};
268 std::size_t motion_error_count{};
253 bool has_gyro{false}; 269 bool has_gyro{false};
254 bool has_accel{false}; 270 bool has_accel{false};
255 bool has_vibration{false}; 271 bool has_vibration{false};
@@ -318,6 +334,23 @@ void SDLDriver::InitJoystick(int joystick_index) {
318 334
319 const auto guid = GetGUID(sdl_joystick); 335 const auto guid = GetGUID(sdl_joystick);
320 336
337 if (Settings::values.enable_joycon_driver) {
338 if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e &&
339 (guid.uuid[8] == 0x06 || guid.uuid[8] == 0x07)) {
340 LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index);
341 SDL_JoystickClose(sdl_joystick);
342 return;
343 }
344 }
345
346 if (Settings::values.enable_procon_driver) {
347 if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && guid.uuid[8] == 0x09) {
348 LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index);
349 SDL_JoystickClose(sdl_joystick);
350 return;
351 }
352 }
353
321 std::scoped_lock lock{joystick_map_mutex}; 354 std::scoped_lock lock{joystick_map_mutex};
322 if (joystick_map.find(guid) == joystick_map.end()) { 355 if (joystick_map.find(guid) == joystick_map.end()) {
323 auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_gamecontroller); 356 auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_gamecontroller);
@@ -440,9 +473,19 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
440 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); 473 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
441 SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); 474 SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
442 475
443 // Use hidapi driver for joycons. This will allow joycons to be detected as a GameController and 476 // Disable hidapi drivers for joycon controllers when the custom joycon driver is enabled
444 // not a generic one 477 if (Settings::values.enable_joycon_driver) {
445 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1"); 478 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "0");
479 } else {
480 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1");
481 }
482
483 // Disable hidapi drivers for pro controllers when the custom joycon driver is enabled
484 if (Settings::values.enable_procon_driver) {
485 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "0");
486 } else {
487 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "1");
488 }
446 489
447 // Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native 490 // Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native
448 // driver on Linux. 491 // driver on Linux.
@@ -532,7 +575,7 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const {
532 return devices; 575 return devices;
533} 576}
534 577
535Common::Input::VibrationError SDLDriver::SetVibration( 578Common::Input::DriverResult SDLDriver::SetVibration(
536 const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) { 579 const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
537 const auto joystick = 580 const auto joystick =
538 GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port)); 581 GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port));
@@ -566,14 +609,14 @@ Common::Input::VibrationError SDLDriver::SetVibration(
566 .vibration = new_vibration, 609 .vibration = new_vibration,
567 }); 610 });
568 611
569 return Common::Input::VibrationError::None; 612 return Common::Input::DriverResult::Success;
570} 613}
571 614
572bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) { 615bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) {
573 const auto joystick = 616 const auto joystick =
574 GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port)); 617 GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port));
575 618
576 constexpr Common::Input::VibrationStatus test_vibration{ 619 static constexpr Common::Input::VibrationStatus test_vibration{
577 .low_amplitude = 1, 620 .low_amplitude = 1,
578 .low_frequency = 160.0f, 621 .low_frequency = 160.0f,
579 .high_amplitude = 1, 622 .high_amplitude = 1,
@@ -581,7 +624,7 @@ bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) {
581 .type = Common::Input::VibrationAmplificationType::Exponential, 624 .type = Common::Input::VibrationAmplificationType::Exponential,
582 }; 625 };
583 626
584 constexpr Common::Input::VibrationStatus zero_vibration{ 627 static constexpr Common::Input::VibrationStatus zero_vibration{
585 .low_amplitude = 0, 628 .low_amplitude = 0,
586 .low_frequency = 160.0f, 629 .low_frequency = 160.0f,
587 .high_amplitude = 0, 630 .high_amplitude = 0,
@@ -942,18 +985,18 @@ MotionMapping SDLDriver::GetMotionMappingForDevice(const Common::ParamPackage& p
942 MotionMapping mapping = {}; 985 MotionMapping mapping = {};
943 joystick->EnableMotion(); 986 joystick->EnableMotion();
944 987
945 if (joystick->HasGyro() || joystick->HasAccel()) { 988 if (joystick->HasMotion()) {
946 mapping.insert_or_assign(Settings::NativeMotion::MotionRight, 989 mapping.insert_or_assign(Settings::NativeMotion::MotionRight,
947 BuildMotionParam(joystick->GetPort(), joystick->GetGUID())); 990 BuildMotionParam(joystick->GetPort(), joystick->GetGUID()));
948 } 991 }
949 if (params.Has("guid2")) { 992 if (params.Has("guid2")) {
950 joystick2->EnableMotion(); 993 joystick2->EnableMotion();
951 if (joystick2->HasGyro() || joystick2->HasAccel()) { 994 if (joystick2->HasMotion()) {
952 mapping.insert_or_assign(Settings::NativeMotion::MotionLeft, 995 mapping.insert_or_assign(Settings::NativeMotion::MotionLeft,
953 BuildMotionParam(joystick2->GetPort(), joystick2->GetGUID())); 996 BuildMotionParam(joystick2->GetPort(), joystick2->GetGUID()));
954 } 997 }
955 } else { 998 } else {
956 if (joystick->HasGyro() || joystick->HasAccel()) { 999 if (joystick->HasMotion()) {
957 mapping.insert_or_assign(Settings::NativeMotion::MotionLeft, 1000 mapping.insert_or_assign(Settings::NativeMotion::MotionLeft,
958 BuildMotionParam(joystick->GetPort(), joystick->GetGUID())); 1001 BuildMotionParam(joystick->GetPort(), joystick->GetGUID()));
959 } 1002 }