summaryrefslogtreecommitdiff
path: root/src/input_common
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common')
-rw-r--r--src/input_common/drivers/sdl_driver.cpp28
-rw-r--r--src/input_common/helpers/joycon_driver.cpp42
-rw-r--r--src/input_common/helpers/joycon_driver.h1
-rw-r--r--src/input_common/helpers/joycon_protocol/common_protocol.cpp8
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) {
73DriverResult JoyconCommonProtocol::GetSubCommandResponse(SubCommand sc, 73DriverResult 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
121DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const u8> buffer) { 119DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const u8> buffer) {
@@ -158,7 +156,7 @@ DriverResult JoyconCommonProtocol::SendVibrationReport(std::span<const u8> buffe
158 156
159DriverResult JoyconCommonProtocol::ReadRawSPI(SpiAddress addr, std::span<u8> output) { 157DriverResult 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{};