diff options
author | Narr the Reg <juangerman-13@hotmail.com> | 2022-12-20 20:27:34 -0600 |
---|---|---|
committer | Narr the Reg <juangerman-13@hotmail.com> | 2023-01-19 18:05:21 -0600 |
commit | f09a023292e659af46d551b9b134d94d000a57c7 (patch) | |
tree | f34ef390cac9f32f7d807614505601635ac62e28 /src/input_common/helpers/joycon_driver.cpp | |
parent | 5676c2e17fe895e450e185029991fc20bdf56ec5 (diff) |
input_common: Add support for joycon input reports
Diffstat (limited to 'src/input_common/helpers/joycon_driver.cpp')
-rw-r--r-- | src/input_common/helpers/joycon_driver.cpp | 100 |
1 files changed, 40 insertions, 60 deletions
diff --git a/src/input_common/helpers/joycon_driver.cpp b/src/input_common/helpers/joycon_driver.cpp index ac11be1c17..5d0aeabf5f 100644 --- a/src/input_common/helpers/joycon_driver.cpp +++ b/src/input_common/helpers/joycon_driver.cpp @@ -66,6 +66,7 @@ DriverResult JoyconDriver::InitializeDevice() { // Initialize HW Protocols calibration_protocol = std::make_unique<CalibrationProtocol>(hidapi_handle); generic_protocol = std::make_unique<GenericProtocol>(hidapi_handle); + rumble_protocol = std::make_unique<RumbleProtocol>(hidapi_handle); // Get fixed joycon info generic_protocol->GetVersionNumber(version); @@ -90,6 +91,10 @@ DriverResult JoyconDriver::InitializeDevice() { // Apply HW configuration SetPollingMode(); + // Initialize joycon poller + joycon_poller = std::make_unique<JoyconPoller>(device_type, left_stick_calibration, + right_stick_calibration, motion_calibration); + // Start pooling for data is_connected = true; if (!input_thread_running) { @@ -142,15 +147,40 @@ void JoyconDriver::InputThread(std::stop_token stop_token) { void JoyconDriver::OnNewData(std::span<u8> buffer) { const auto report_mode = static_cast<InputReport>(buffer[0]); + // Packages can be a litte bit inconsistent. Average the delta time to provide a smoother motion + // experience + switch (report_mode) { + case InputReport::STANDARD_FULL_60HZ: + case InputReport::NFC_IR_MODE_60HZ: + case InputReport::SIMPLE_HID_MODE: { + const auto now = std::chrono::steady_clock::now(); + const auto new_delta_time = static_cast<u64>( + std::chrono::duration_cast<std::chrono::microseconds>(now - last_update).count()); + delta_time = ((delta_time * 8) + (new_delta_time * 2)) / 10; + last_update = now; + joycon_poller->UpdateColor(color); + break; + } + default: + break; + } + + const MotionStatus motion_status{ + .is_enabled = motion_enabled, + .delta_time = delta_time, + .gyro_sensitivity = gyro_sensitivity, + .accelerometer_sensitivity = accelerometer_sensitivity, + }; + switch (report_mode) { case InputReport::STANDARD_FULL_60HZ: - ReadActiveMode(buffer); + joycon_poller->ReadActiveMode(buffer, motion_status); break; case InputReport::NFC_IR_MODE_60HZ: - ReadNfcIRMode(buffer); + joycon_poller->ReadNfcIRMode(buffer, motion_status); break; case InputReport::SIMPLE_HID_MODE: - ReadPassiveMode(buffer); + joycon_poller->ReadPassiveMode(buffer); break; case InputReport::SUBCMD_REPLY: LOG_DEBUG(Input, "Unhandled command reply"); @@ -164,6 +194,8 @@ void JoyconDriver::OnNewData(std::span<u8> buffer) { void JoyconDriver::SetPollingMode() { disable_input_thread = true; + rumble_protocol->EnableRumble(vibration_enabled && supported_features.vibration); + if (motion_enabled && supported_features.motion) { generic_protocol->EnableImu(true); generic_protocol->SetImuConfig(gyro_sensitivity, gyro_performance, @@ -209,62 +241,6 @@ JoyconDriver::SupportedFeatures JoyconDriver::GetSupportedFeatures() { return features; } -void JoyconDriver::ReadActiveMode(std::span<u8> buffer) { - InputReportActive data{}; - memcpy(&data, buffer.data(), sizeof(InputReportActive)); - - // Packages can be a litte bit inconsistent. Average the delta time to provide a smoother motion - // experience - const auto now = std::chrono::steady_clock::now(); - const auto new_delta_time = - std::chrono::duration_cast<std::chrono::microseconds>(now - last_update).count(); - delta_time = static_cast<u64>((delta_time * 0.8f) + (new_delta_time * 0.2)); - last_update = now; - - switch (device_type) { - case Joycon::ControllerType::Left: - break; - case Joycon::ControllerType::Right: - break; - case Joycon::ControllerType::Pro: - break; - case Joycon::ControllerType::Grip: - case Joycon::ControllerType::Dual: - case Joycon::ControllerType::None: - break; - } - - on_battery_data(data.battery_status); - on_color_data(color); -} - -void JoyconDriver::ReadPassiveMode(std::span<u8> buffer) { - InputReportPassive data{}; - memcpy(&data, buffer.data(), sizeof(InputReportPassive)); - - switch (device_type) { - case Joycon::ControllerType::Left: - break; - case Joycon::ControllerType::Right: - break; - case Joycon::ControllerType::Pro: - break; - case Joycon::ControllerType::Grip: - case Joycon::ControllerType::Dual: - case Joycon::ControllerType::None: - break; - } -} - -void JoyconDriver::ReadNfcIRMode(std::span<u8> buffer) { - // This mode is compatible with the active mode - ReadActiveMode(buffer); - - if (!nfc_enabled) { - return; - } -} - bool JoyconDriver::IsInputThreadValid() const { if (!is_connected) { return false; @@ -302,7 +278,7 @@ DriverResult JoyconDriver::SetVibration(const VibrationValue& vibration) { if (disable_input_thread) { return DriverResult::HandleInUse; } - return DriverResult::NotSupported; + return rumble_protocol->SendVibration(vibration); } DriverResult JoyconDriver::SetLedConfig(u8 led_pattern) { @@ -398,6 +374,10 @@ SerialNumber JoyconDriver::GetHandleSerialNumber() const { return handle_serial_number; } +void JoyconDriver::SetCallbacks(const Joycon::JoyconCallbacks& callbacks) { + joycon_poller->SetCallbacks(callbacks); +} + Joycon::DriverResult JoyconDriver::GetDeviceType(SDL_hid_device_info* device_info, ControllerType& controller_type) { std::array<std::pair<u32, Joycon::ControllerType>, 4> supported_devices{ |