diff options
Diffstat (limited to 'src/input_common')
| -rw-r--r-- | src/input_common/drivers/sdl_driver.cpp | 28 | ||||
| -rw-r--r-- | src/input_common/helpers/joycon_driver.cpp | 42 | ||||
| -rw-r--r-- | src/input_common/helpers/joycon_driver.h | 1 | ||||
| -rw-r--r-- | src/input_common/helpers/joycon_protocol/common_protocol.cpp | 8 |
4 files changed, 57 insertions, 22 deletions
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index ab64a64a2..9f26392b1 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp | |||
| @@ -150,6 +150,8 @@ public: | |||
| 150 | if (sdl_controller) { | 150 | if (sdl_controller) { |
| 151 | const auto type = SDL_GameControllerGetType(sdl_controller.get()); | 151 | const auto type = SDL_GameControllerGetType(sdl_controller.get()); |
| 152 | return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) || | 152 | return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) || |
| 153 | (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT) || | ||
| 154 | (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT) || | ||
| 153 | (type == SDL_CONTROLLER_TYPE_PS5); | 155 | (type == SDL_CONTROLLER_TYPE_PS5); |
| 154 | } | 156 | } |
| 155 | return false; | 157 | return false; |
| @@ -228,9 +230,8 @@ public: | |||
| 228 | return false; | 230 | return false; |
| 229 | } | 231 | } |
| 230 | 232 | ||
| 231 | Common::Input::BatteryLevel GetBatteryLevel() { | 233 | Common::Input::BatteryLevel GetBatteryLevel(SDL_JoystickPowerLevel battery_level) { |
| 232 | const auto level = SDL_JoystickCurrentPowerLevel(sdl_joystick.get()); | 234 | switch (battery_level) { |
| 233 | switch (level) { | ||
| 234 | case SDL_JOYSTICK_POWER_EMPTY: | 235 | case SDL_JOYSTICK_POWER_EMPTY: |
| 235 | return Common::Input::BatteryLevel::Empty; | 236 | return Common::Input::BatteryLevel::Empty; |
| 236 | case SDL_JOYSTICK_POWER_LOW: | 237 | case SDL_JOYSTICK_POWER_LOW: |
| @@ -378,7 +379,6 @@ void SDLDriver::InitJoystick(int joystick_index) { | |||
| 378 | if (joystick_map.find(guid) == joystick_map.end()) { | 379 | if (joystick_map.find(guid) == joystick_map.end()) { |
| 379 | auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_gamecontroller); | 380 | auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_gamecontroller); |
| 380 | PreSetController(joystick->GetPadIdentifier()); | 381 | PreSetController(joystick->GetPadIdentifier()); |
| 381 | SetBattery(joystick->GetPadIdentifier(), joystick->GetBatteryLevel()); | ||
| 382 | joystick->EnableMotion(); | 382 | joystick->EnableMotion(); |
| 383 | joystick_map[guid].emplace_back(std::move(joystick)); | 383 | joystick_map[guid].emplace_back(std::move(joystick)); |
| 384 | return; | 384 | return; |
| @@ -398,7 +398,6 @@ void SDLDriver::InitJoystick(int joystick_index) { | |||
| 398 | const int port = static_cast<int>(joystick_guid_list.size()); | 398 | const int port = static_cast<int>(joystick_guid_list.size()); |
| 399 | auto joystick = std::make_shared<SDLJoystick>(guid, port, sdl_joystick, sdl_gamecontroller); | 399 | auto joystick = std::make_shared<SDLJoystick>(guid, port, sdl_joystick, sdl_gamecontroller); |
| 400 | PreSetController(joystick->GetPadIdentifier()); | 400 | PreSetController(joystick->GetPadIdentifier()); |
| 401 | SetBattery(joystick->GetPadIdentifier(), joystick->GetBatteryLevel()); | ||
| 402 | joystick->EnableMotion(); | 401 | joystick->EnableMotion(); |
| 403 | joystick_guid_list.emplace_back(std::move(joystick)); | 402 | joystick_guid_list.emplace_back(std::move(joystick)); |
| 404 | } | 403 | } |
| @@ -438,8 +437,6 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { | |||
| 438 | if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { | 437 | if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { |
| 439 | const PadIdentifier identifier = joystick->GetPadIdentifier(); | 438 | const PadIdentifier identifier = joystick->GetPadIdentifier(); |
| 440 | SetButton(identifier, event.jbutton.button, true); | 439 | SetButton(identifier, event.jbutton.button, true); |
| 441 | // Battery doesn't trigger an event so just update every button press | ||
| 442 | SetBattery(identifier, joystick->GetBatteryLevel()); | ||
| 443 | } | 440 | } |
| 444 | break; | 441 | break; |
| 445 | } | 442 | } |
| @@ -466,6 +463,13 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { | |||
| 466 | } | 463 | } |
| 467 | break; | 464 | break; |
| 468 | } | 465 | } |
| 466 | case SDL_JOYBATTERYUPDATED: { | ||
| 467 | if (auto joystick = GetSDLJoystickBySDLID(event.jbattery.which)) { | ||
| 468 | const PadIdentifier identifier = joystick->GetPadIdentifier(); | ||
| 469 | SetBattery(identifier, joystick->GetBatteryLevel(event.jbattery.level)); | ||
| 470 | } | ||
| 471 | break; | ||
| 472 | } | ||
| 469 | case SDL_JOYDEVICEREMOVED: | 473 | case SDL_JOYDEVICEREMOVED: |
| 470 | LOG_DEBUG(Input, "Controller removed with Instance_ID {}", event.jdevice.which); | 474 | LOG_DEBUG(Input, "Controller removed with Instance_ID {}", event.jdevice.which); |
| 471 | CloseJoystick(SDL_JoystickFromInstanceID(event.jdevice.which)); | 475 | CloseJoystick(SDL_JoystickFromInstanceID(event.jdevice.which)); |
| @@ -505,6 +509,9 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en | |||
| 505 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "0"); | 509 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "0"); |
| 506 | } else { | 510 | } else { |
| 507 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1"); | 511 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1"); |
| 512 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED, "0"); | ||
| 513 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS, "0"); | ||
| 514 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, "1"); | ||
| 508 | } | 515 | } |
| 509 | 516 | ||
| 510 | // Disable hidapi drivers for pro controllers when the custom joycon driver is enabled | 517 | // Disable hidapi drivers for pro controllers when the custom joycon driver is enabled |
| @@ -512,8 +519,11 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en | |||
| 512 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "0"); | 519 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "0"); |
| 513 | } else { | 520 | } else { |
| 514 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "1"); | 521 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "1"); |
| 522 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED, "0"); | ||
| 515 | } | 523 | } |
| 516 | 524 | ||
| 525 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED, "1"); | ||
| 526 | |||
| 517 | // Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native | 527 | // Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native |
| 518 | // driver on Linux. | 528 | // driver on Linux. |
| 519 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_XBOX, "0"); | 529 | SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_XBOX, "0"); |
| @@ -793,7 +803,9 @@ ButtonMapping SDLDriver::GetButtonMappingForDevice(const Common::ParamPackage& p | |||
| 793 | // This list also excludes Screenshot since there's not really a mapping for that | 803 | // This list also excludes Screenshot since there's not really a mapping for that |
| 794 | ButtonBindings switch_to_sdl_button; | 804 | ButtonBindings switch_to_sdl_button; |
| 795 | 805 | ||
| 796 | if (SDL_GameControllerGetType(controller) == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) { | 806 | if (SDL_GameControllerGetType(controller) == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO || |
| 807 | SDL_GameControllerGetType(controller) == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT || | ||
| 808 | SDL_GameControllerGetType(controller) == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT) { | ||
| 797 | switch_to_sdl_button = GetNintendoButtonBinding(joystick); | 809 | switch_to_sdl_button = GetNintendoButtonBinding(joystick); |
| 798 | } else { | 810 | } else { |
| 799 | switch_to_sdl_button = GetDefaultButtonBinding(); | 811 | switch_to_sdl_button = GetDefaultButtonBinding(); |
diff --git a/src/input_common/helpers/joycon_driver.cpp b/src/input_common/helpers/joycon_driver.cpp index 2c8c66951..ec984a647 100644 --- a/src/input_common/helpers/joycon_driver.cpp +++ b/src/input_common/helpers/joycon_driver.cpp | |||
| @@ -72,6 +72,7 @@ DriverResult JoyconDriver::InitializeDevice() { | |||
| 72 | nfc_enabled = false; | 72 | nfc_enabled = false; |
| 73 | passive_enabled = false; | 73 | passive_enabled = false; |
| 74 | irs_enabled = false; | 74 | irs_enabled = false; |
| 75 | input_only_device = false; | ||
| 75 | gyro_sensitivity = Joycon::GyroSensitivity::DPS2000; | 76 | gyro_sensitivity = Joycon::GyroSensitivity::DPS2000; |
| 76 | gyro_performance = Joycon::GyroPerformance::HZ833; | 77 | gyro_performance = Joycon::GyroPerformance::HZ833; |
| 77 | accelerometer_sensitivity = Joycon::AccelerometerSensitivity::G8; | 78 | accelerometer_sensitivity = Joycon::AccelerometerSensitivity::G8; |
| @@ -86,16 +87,23 @@ DriverResult JoyconDriver::InitializeDevice() { | |||
| 86 | rumble_protocol = std::make_unique<RumbleProtocol>(hidapi_handle); | 87 | rumble_protocol = std::make_unique<RumbleProtocol>(hidapi_handle); |
| 87 | 88 | ||
| 88 | // Get fixed joycon info | 89 | // Get fixed joycon info |
| 89 | generic_protocol->GetVersionNumber(version); | 90 | if (generic_protocol->GetVersionNumber(version) != DriverResult::Success) { |
| 90 | generic_protocol->SetLowPowerMode(false); | 91 | // If this command fails the device doesn't accept configuration commands |
| 91 | generic_protocol->GetColor(color); | 92 | input_only_device = true; |
| 92 | if (handle_device_type == ControllerType::Pro) { | ||
| 93 | // Some 3rd party controllers aren't pro controllers | ||
| 94 | generic_protocol->GetControllerType(device_type); | ||
| 95 | } else { | ||
| 96 | device_type = handle_device_type; | ||
| 97 | } | 93 | } |
| 98 | generic_protocol->GetSerialNumber(serial_number); | 94 | |
| 95 | if (!input_only_device) { | ||
| 96 | generic_protocol->SetLowPowerMode(false); | ||
| 97 | generic_protocol->GetColor(color); | ||
| 98 | if (handle_device_type == ControllerType::Pro) { | ||
| 99 | // Some 3rd party controllers aren't pro controllers | ||
| 100 | generic_protocol->GetControllerType(device_type); | ||
| 101 | } else { | ||
| 102 | device_type = handle_device_type; | ||
| 103 | } | ||
| 104 | generic_protocol->GetSerialNumber(serial_number); | ||
| 105 | } | ||
| 106 | |||
| 99 | supported_features = GetSupportedFeatures(); | 107 | supported_features = GetSupportedFeatures(); |
| 100 | 108 | ||
| 101 | // Get Calibration data | 109 | // Get Calibration data |
| @@ -261,6 +269,10 @@ DriverResult JoyconDriver::SetPollingMode() { | |||
| 261 | generic_protocol->EnableImu(false); | 269 | generic_protocol->EnableImu(false); |
| 262 | } | 270 | } |
| 263 | 271 | ||
| 272 | if (input_only_device) { | ||
| 273 | return DriverResult::NotSupported; | ||
| 274 | } | ||
| 275 | |||
| 264 | if (irs_protocol->IsEnabled()) { | 276 | if (irs_protocol->IsEnabled()) { |
| 265 | irs_protocol->DisableIrs(); | 277 | irs_protocol->DisableIrs(); |
| 266 | } | 278 | } |
| @@ -282,6 +294,7 @@ DriverResult JoyconDriver::SetPollingMode() { | |||
| 282 | } | 294 | } |
| 283 | irs_protocol->DisableIrs(); | 295 | irs_protocol->DisableIrs(); |
| 284 | LOG_ERROR(Input, "Error enabling IRS"); | 296 | LOG_ERROR(Input, "Error enabling IRS"); |
| 297 | return result; | ||
| 285 | } | 298 | } |
| 286 | 299 | ||
| 287 | if (nfc_enabled && supported_features.nfc) { | 300 | if (nfc_enabled && supported_features.nfc) { |
| @@ -291,6 +304,7 @@ DriverResult JoyconDriver::SetPollingMode() { | |||
| 291 | } | 304 | } |
| 292 | nfc_protocol->DisableNfc(); | 305 | nfc_protocol->DisableNfc(); |
| 293 | LOG_ERROR(Input, "Error enabling NFC"); | 306 | LOG_ERROR(Input, "Error enabling NFC"); |
| 307 | return result; | ||
| 294 | } | 308 | } |
| 295 | 309 | ||
| 296 | if (hidbus_enabled && supported_features.hidbus) { | 310 | if (hidbus_enabled && supported_features.hidbus) { |
| @@ -305,6 +319,7 @@ DriverResult JoyconDriver::SetPollingMode() { | |||
| 305 | ring_connected = false; | 319 | ring_connected = false; |
| 306 | ring_protocol->DisableRingCon(); | 320 | ring_protocol->DisableRingCon(); |
| 307 | LOG_ERROR(Input, "Error enabling Ringcon"); | 321 | LOG_ERROR(Input, "Error enabling Ringcon"); |
| 322 | return result; | ||
| 308 | } | 323 | } |
| 309 | 324 | ||
| 310 | if (passive_enabled && supported_features.passive) { | 325 | if (passive_enabled && supported_features.passive) { |
| @@ -333,6 +348,10 @@ JoyconDriver::SupportedFeatures JoyconDriver::GetSupportedFeatures() { | |||
| 333 | .vibration = true, | 348 | .vibration = true, |
| 334 | }; | 349 | }; |
| 335 | 350 | ||
| 351 | if (input_only_device) { | ||
| 352 | return features; | ||
| 353 | } | ||
| 354 | |||
| 336 | if (device_type == ControllerType::Right) { | 355 | if (device_type == ControllerType::Right) { |
| 337 | features.nfc = true; | 356 | features.nfc = true; |
| 338 | features.irs = true; | 357 | features.irs = true; |
| @@ -517,6 +536,11 @@ DriverResult JoyconDriver::StopNfcPolling() { | |||
| 517 | const auto result = nfc_protocol->StopNFCPollingMode(); | 536 | const auto result = nfc_protocol->StopNFCPollingMode(); |
| 518 | disable_input_thread = false; | 537 | disable_input_thread = false; |
| 519 | 538 | ||
| 539 | if (amiibo_detected) { | ||
| 540 | amiibo_detected = false; | ||
| 541 | joycon_poller->UpdateAmiibo({}); | ||
| 542 | } | ||
| 543 | |||
| 520 | return result; | 544 | return result; |
| 521 | } | 545 | } |
| 522 | 546 | ||
diff --git a/src/input_common/helpers/joycon_driver.h b/src/input_common/helpers/joycon_driver.h index bc7025a21..45b32d2f8 100644 --- a/src/input_common/helpers/joycon_driver.h +++ b/src/input_common/helpers/joycon_driver.h | |||
| @@ -120,6 +120,7 @@ private: | |||
| 120 | // Hardware configuration | 120 | // Hardware configuration |
| 121 | u8 leds{}; | 121 | u8 leds{}; |
| 122 | ReportMode mode{}; | 122 | ReportMode mode{}; |
| 123 | bool input_only_device{}; | ||
| 123 | bool passive_enabled{}; // Low power mode, Ideal for multiple controllers at the same time | 124 | bool passive_enabled{}; // Low power mode, Ideal for multiple controllers at the same time |
| 124 | bool hidbus_enabled{}; // External device support | 125 | bool hidbus_enabled{}; // External device support |
| 125 | bool irs_enabled{}; // Infrared camera input | 126 | bool irs_enabled{}; // Infrared camera input |
diff --git a/src/input_common/helpers/joycon_protocol/common_protocol.cpp b/src/input_common/helpers/joycon_protocol/common_protocol.cpp index 51669261a..88f4cec1c 100644 --- a/src/input_common/helpers/joycon_protocol/common_protocol.cpp +++ b/src/input_common/helpers/joycon_protocol/common_protocol.cpp | |||
| @@ -73,7 +73,7 @@ DriverResult JoyconCommonProtocol::SendRawData(std::span<const u8> buffer) { | |||
| 73 | DriverResult JoyconCommonProtocol::GetSubCommandResponse(SubCommand sc, | 73 | DriverResult JoyconCommonProtocol::GetSubCommandResponse(SubCommand sc, |
| 74 | SubCommandResponse& output) { | 74 | SubCommandResponse& output) { |
| 75 | constexpr int timeout_mili = 66; | 75 | constexpr int timeout_mili = 66; |
| 76 | constexpr int MaxTries = 15; | 76 | constexpr int MaxTries = 3; |
| 77 | int tries = 0; | 77 | int tries = 0; |
| 78 | 78 | ||
| 79 | do { | 79 | do { |
| @@ -113,9 +113,7 @@ DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const | |||
| 113 | return result; | 113 | return result; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | result = GetSubCommandResponse(sc, output); | 116 | return GetSubCommandResponse(sc, output); |
| 117 | |||
| 118 | return DriverResult::Success; | ||
| 119 | } | 117 | } |
| 120 | 118 | ||
| 121 | DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const u8> buffer) { | 119 | DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const u8> buffer) { |
| @@ -158,7 +156,7 @@ DriverResult JoyconCommonProtocol::SendVibrationReport(std::span<const u8> buffe | |||
| 158 | 156 | ||
| 159 | DriverResult JoyconCommonProtocol::ReadRawSPI(SpiAddress addr, std::span<u8> output) { | 157 | DriverResult JoyconCommonProtocol::ReadRawSPI(SpiAddress addr, std::span<u8> output) { |
| 160 | constexpr std::size_t HeaderSize = 5; | 158 | constexpr std::size_t HeaderSize = 5; |
| 161 | constexpr std::size_t MaxTries = 10; | 159 | constexpr std::size_t MaxTries = 5; |
| 162 | std::size_t tries = 0; | 160 | std::size_t tries = 0; |
| 163 | SubCommandResponse response{}; | 161 | SubCommandResponse response{}; |
| 164 | std::array<u8, sizeof(ReadSpiPacket)> buffer{}; | 162 | std::array<u8, sizeof(ReadSpiPacket)> buffer{}; |