summaryrefslogtreecommitdiff
path: root/src/input_common/helpers/joycon_driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/helpers/joycon_driver.cpp')
-rw-r--r--src/input_common/helpers/joycon_driver.cpp100
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 ac11be1c1..5d0aeabf5 100644
--- a/src/input_common/helpers/joycon_driver.cpp
+++ b/src/input_common/helpers/joycon_driver.cpp
@@ -66,6 +66,7 @@ DriverResult JoyconDriver::InitializeDevice() {
66 // Initialize HW Protocols 66 // Initialize HW Protocols
67 calibration_protocol = std::make_unique<CalibrationProtocol>(hidapi_handle); 67 calibration_protocol = std::make_unique<CalibrationProtocol>(hidapi_handle);
68 generic_protocol = std::make_unique<GenericProtocol>(hidapi_handle); 68 generic_protocol = std::make_unique<GenericProtocol>(hidapi_handle);
69 rumble_protocol = std::make_unique<RumbleProtocol>(hidapi_handle);
69 70
70 // Get fixed joycon info 71 // Get fixed joycon info
71 generic_protocol->GetVersionNumber(version); 72 generic_protocol->GetVersionNumber(version);
@@ -90,6 +91,10 @@ DriverResult JoyconDriver::InitializeDevice() {
90 // Apply HW configuration 91 // Apply HW configuration
91 SetPollingMode(); 92 SetPollingMode();
92 93
94 // Initialize joycon poller
95 joycon_poller = std::make_unique<JoyconPoller>(device_type, left_stick_calibration,
96 right_stick_calibration, motion_calibration);
97
93 // Start pooling for data 98 // Start pooling for data
94 is_connected = true; 99 is_connected = true;
95 if (!input_thread_running) { 100 if (!input_thread_running) {
@@ -142,15 +147,40 @@ void JoyconDriver::InputThread(std::stop_token stop_token) {
142void JoyconDriver::OnNewData(std::span<u8> buffer) { 147void JoyconDriver::OnNewData(std::span<u8> buffer) {
143 const auto report_mode = static_cast<InputReport>(buffer[0]); 148 const auto report_mode = static_cast<InputReport>(buffer[0]);
144 149
150 // Packages can be a litte bit inconsistent. Average the delta time to provide a smoother motion
151 // experience
152 switch (report_mode) {
153 case InputReport::STANDARD_FULL_60HZ:
154 case InputReport::NFC_IR_MODE_60HZ:
155 case InputReport::SIMPLE_HID_MODE: {
156 const auto now = std::chrono::steady_clock::now();
157 const auto new_delta_time = static_cast<u64>(
158 std::chrono::duration_cast<std::chrono::microseconds>(now - last_update).count());
159 delta_time = ((delta_time * 8) + (new_delta_time * 2)) / 10;
160 last_update = now;
161 joycon_poller->UpdateColor(color);
162 break;
163 }
164 default:
165 break;
166 }
167
168 const MotionStatus motion_status{
169 .is_enabled = motion_enabled,
170 .delta_time = delta_time,
171 .gyro_sensitivity = gyro_sensitivity,
172 .accelerometer_sensitivity = accelerometer_sensitivity,
173 };
174
145 switch (report_mode) { 175 switch (report_mode) {
146 case InputReport::STANDARD_FULL_60HZ: 176 case InputReport::STANDARD_FULL_60HZ:
147 ReadActiveMode(buffer); 177 joycon_poller->ReadActiveMode(buffer, motion_status);
148 break; 178 break;
149 case InputReport::NFC_IR_MODE_60HZ: 179 case InputReport::NFC_IR_MODE_60HZ:
150 ReadNfcIRMode(buffer); 180 joycon_poller->ReadNfcIRMode(buffer, motion_status);
151 break; 181 break;
152 case InputReport::SIMPLE_HID_MODE: 182 case InputReport::SIMPLE_HID_MODE:
153 ReadPassiveMode(buffer); 183 joycon_poller->ReadPassiveMode(buffer);
154 break; 184 break;
155 case InputReport::SUBCMD_REPLY: 185 case InputReport::SUBCMD_REPLY:
156 LOG_DEBUG(Input, "Unhandled command reply"); 186 LOG_DEBUG(Input, "Unhandled command reply");
@@ -164,6 +194,8 @@ void JoyconDriver::OnNewData(std::span<u8> buffer) {
164void JoyconDriver::SetPollingMode() { 194void JoyconDriver::SetPollingMode() {
165 disable_input_thread = true; 195 disable_input_thread = true;
166 196
197 rumble_protocol->EnableRumble(vibration_enabled && supported_features.vibration);
198
167 if (motion_enabled && supported_features.motion) { 199 if (motion_enabled && supported_features.motion) {
168 generic_protocol->EnableImu(true); 200 generic_protocol->EnableImu(true);
169 generic_protocol->SetImuConfig(gyro_sensitivity, gyro_performance, 201 generic_protocol->SetImuConfig(gyro_sensitivity, gyro_performance,
@@ -209,62 +241,6 @@ JoyconDriver::SupportedFeatures JoyconDriver::GetSupportedFeatures() {
209 return features; 241 return features;
210} 242}
211 243
212void JoyconDriver::ReadActiveMode(std::span<u8> buffer) {
213 InputReportActive data{};
214 memcpy(&data, buffer.data(), sizeof(InputReportActive));
215
216 // Packages can be a litte bit inconsistent. Average the delta time to provide a smoother motion
217 // experience
218 const auto now = std::chrono::steady_clock::now();
219 const auto new_delta_time =
220 std::chrono::duration_cast<std::chrono::microseconds>(now - last_update).count();
221 delta_time = static_cast<u64>((delta_time * 0.8f) + (new_delta_time * 0.2));
222 last_update = now;
223
224 switch (device_type) {
225 case Joycon::ControllerType::Left:
226 break;
227 case Joycon::ControllerType::Right:
228 break;
229 case Joycon::ControllerType::Pro:
230 break;
231 case Joycon::ControllerType::Grip:
232 case Joycon::ControllerType::Dual:
233 case Joycon::ControllerType::None:
234 break;
235 }
236
237 on_battery_data(data.battery_status);
238 on_color_data(color);
239}
240
241void JoyconDriver::ReadPassiveMode(std::span<u8> buffer) {
242 InputReportPassive data{};
243 memcpy(&data, buffer.data(), sizeof(InputReportPassive));
244
245 switch (device_type) {
246 case Joycon::ControllerType::Left:
247 break;
248 case Joycon::ControllerType::Right:
249 break;
250 case Joycon::ControllerType::Pro:
251 break;
252 case Joycon::ControllerType::Grip:
253 case Joycon::ControllerType::Dual:
254 case Joycon::ControllerType::None:
255 break;
256 }
257}
258
259void JoyconDriver::ReadNfcIRMode(std::span<u8> buffer) {
260 // This mode is compatible with the active mode
261 ReadActiveMode(buffer);
262
263 if (!nfc_enabled) {
264 return;
265 }
266}
267
268bool JoyconDriver::IsInputThreadValid() const { 244bool JoyconDriver::IsInputThreadValid() const {
269 if (!is_connected) { 245 if (!is_connected) {
270 return false; 246 return false;
@@ -302,7 +278,7 @@ DriverResult JoyconDriver::SetVibration(const VibrationValue& vibration) {
302 if (disable_input_thread) { 278 if (disable_input_thread) {
303 return DriverResult::HandleInUse; 279 return DriverResult::HandleInUse;
304 } 280 }
305 return DriverResult::NotSupported; 281 return rumble_protocol->SendVibration(vibration);
306} 282}
307 283
308DriverResult JoyconDriver::SetLedConfig(u8 led_pattern) { 284DriverResult JoyconDriver::SetLedConfig(u8 led_pattern) {
@@ -398,6 +374,10 @@ SerialNumber JoyconDriver::GetHandleSerialNumber() const {
398 return handle_serial_number; 374 return handle_serial_number;
399} 375}
400 376
377void JoyconDriver::SetCallbacks(const Joycon::JoyconCallbacks& callbacks) {
378 joycon_poller->SetCallbacks(callbacks);
379}
380
401Joycon::DriverResult JoyconDriver::GetDeviceType(SDL_hid_device_info* device_info, 381Joycon::DriverResult JoyconDriver::GetDeviceType(SDL_hid_device_info* device_info,
402 ControllerType& controller_type) { 382 ControllerType& controller_type) {
403 std::array<std::pair<u32, Joycon::ControllerType>, 4> supported_devices{ 383 std::array<std::pair<u32, Joycon::ControllerType>, 4> supported_devices{