diff options
Diffstat (limited to 'src/input_common/drivers/sdl_driver.cpp')
-rw-r--r-- | src/input_common/drivers/sdl_driver.cpp | 77 |
1 files changed, 53 insertions, 24 deletions
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index 4818bb744..d975eb815 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp @@ -40,25 +40,26 @@ public: } void EnableMotion() { - if (sdl_controller) { - SDL_GameController* controller = sdl_controller.get(); - has_accel = SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL) == SDL_TRUE; - has_gyro = SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO) == SDL_TRUE; - if (has_accel) { - SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_TRUE); - } - if (has_gyro) { - SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); - } + if (!sdl_controller) { + return; + } + SDL_GameController* controller = sdl_controller.get(); + if (HasMotion()) { + SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_FALSE); + SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_FALSE); + } + has_accel = SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL) == SDL_TRUE; + has_gyro = SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO) == SDL_TRUE; + if (has_accel) { + SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_TRUE); + } + if (has_gyro) { + SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); } } - bool HasGyro() const { - return has_gyro; - } - - bool HasAccel() const { - return has_accel; + bool HasMotion() const { + return has_gyro || has_accel; } bool UpdateMotion(SDL_ControllerSensorEvent event) { @@ -85,6 +86,20 @@ public: if (time_difference == 0) { return false; } + + // Motion data is invalid + if (motion.accel_x == 0 && motion.gyro_x == 0 && motion.accel_y == 0 && + motion.gyro_y == 0 && motion.accel_z == 0 && motion.gyro_z == 0) { + if (motion_error_count++ < 200) { + return false; + } + // Try restarting the sensor + motion_error_count = 0; + EnableMotion(); + return false; + } + + motion_error_count = 0; motion.delta_timestamp = time_difference * 1000; return true; } @@ -250,6 +265,7 @@ private: mutable std::mutex mutex; u64 last_motion_update{}; + std::size_t motion_error_count{}; bool has_gyro{false}; bool has_accel{false}; bool has_vibration{false}; @@ -318,6 +334,15 @@ void SDLDriver::InitJoystick(int joystick_index) { const auto guid = GetGUID(sdl_joystick); + if (Settings::values.enable_joycon_driver) { + if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && + (guid.uuid[8] == 0x06 || guid.uuid[8] == 0x07)) { + LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); + SDL_JoystickClose(sdl_joystick); + return; + } + } + std::scoped_lock lock{joystick_map_mutex}; if (joystick_map.find(guid) == joystick_map.end()) { auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_gamecontroller); @@ -440,9 +465,13 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); - // Use hidapi driver for joycons. This will allow joycons to be detected as a GameController and - // not a generic one - SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1"); + // Disable hidapi drivers for switch controllers when the custom joycon driver is enabled + if (Settings::values.enable_joycon_driver) { + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "0"); + } else { + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1"); + } + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "1"); // Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native // driver on Linux. @@ -532,7 +561,7 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const { return devices; } -Common::Input::VibrationError SDLDriver::SetVibration( +Common::Input::DriverResult SDLDriver::SetVibration( const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) { const auto joystick = GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port)); @@ -566,7 +595,7 @@ Common::Input::VibrationError SDLDriver::SetVibration( .vibration = new_vibration, }); - return Common::Input::VibrationError::None; + return Common::Input::DriverResult::Success; } bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) { @@ -942,18 +971,18 @@ MotionMapping SDLDriver::GetMotionMappingForDevice(const Common::ParamPackage& p MotionMapping mapping = {}; joystick->EnableMotion(); - if (joystick->HasGyro() || joystick->HasAccel()) { + if (joystick->HasMotion()) { mapping.insert_or_assign(Settings::NativeMotion::MotionRight, BuildMotionParam(joystick->GetPort(), joystick->GetGUID())); } if (params.Has("guid2")) { joystick2->EnableMotion(); - if (joystick2->HasGyro() || joystick2->HasAccel()) { + if (joystick2->HasMotion()) { mapping.insert_or_assign(Settings::NativeMotion::MotionLeft, BuildMotionParam(joystick2->GetPort(), joystick2->GetGUID())); } } else { - if (joystick->HasGyro() || joystick->HasAccel()) { + if (joystick->HasMotion()) { mapping.insert_or_assign(Settings::NativeMotion::MotionLeft, BuildMotionParam(joystick->GetPort(), joystick->GetGUID())); } |