joycon_driver.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <atomic>
  5. #include <functional>
  6. #include <mutex>
  7. #include <span>
  8. #include <thread>
  9. #include "input_common/helpers/joycon_protocol/joycon_types.h"
  10. namespace InputCommon::Joycon {
  11. class CalibrationProtocol;
  12. class GenericProtocol;
  13. class IrsProtocol;
  14. class NfcProtocol;
  15. class JoyconPoller;
  16. class RingConProtocol;
  17. class RumbleProtocol;
  18. class JoyconDriver final {
  19. public:
  20. explicit JoyconDriver(std::size_t port_);
  21. ~JoyconDriver();
  22. DriverResult RequestDeviceAccess(SDL_hid_device_info* device_info);
  23. DriverResult InitializeDevice();
  24. void Stop();
  25. bool IsConnected() const;
  26. bool IsVibrationEnabled() const;
  27. FirmwareVersion GetDeviceVersion() const;
  28. Color GetDeviceColor() const;
  29. std::size_t GetDevicePort() const;
  30. ControllerType GetDeviceType() const;
  31. ControllerType GetHandleDeviceType() const;
  32. SerialNumber GetSerialNumber() const;
  33. SerialNumber GetHandleSerialNumber() const;
  34. DriverResult SetVibration(const VibrationValue& vibration);
  35. DriverResult SetLedConfig(u8 led_pattern);
  36. DriverResult SetIrsConfig(IrsMode mode_, IrsResolution format_);
  37. DriverResult SetPassiveMode();
  38. DriverResult SetActiveMode();
  39. DriverResult SetIrMode();
  40. DriverResult SetNfcMode();
  41. DriverResult SetRingConMode();
  42. void SetCallbacks(const JoyconCallbacks& callbacks);
  43. // Returns device type from hidapi handle
  44. static DriverResult GetDeviceType(SDL_hid_device_info* device_info,
  45. ControllerType& controller_type);
  46. // Returns serial number from hidapi handle
  47. static DriverResult GetSerialNumber(SDL_hid_device_info* device_info,
  48. SerialNumber& serial_number);
  49. private:
  50. struct SupportedFeatures {
  51. bool passive{};
  52. bool hidbus{};
  53. bool irs{};
  54. bool motion{};
  55. bool nfc{};
  56. bool vibration{};
  57. };
  58. /// Main thread, actively request new data from the handle
  59. void InputThread(std::stop_token stop_token);
  60. /// Called everytime a valid package arrives
  61. void OnNewData(std::span<u8> buffer);
  62. /// Updates device configuration to enable or disable features
  63. DriverResult SetPollingMode();
  64. /// Returns true if input thread is valid and doesn't need to be stopped
  65. bool IsInputThreadValid() const;
  66. /// Returns true if the data should be interpreted. Otherwise the error counter is incremented
  67. bool IsPayloadCorrect(int status, std::span<const u8> buffer);
  68. /// Returns a list of supported features that can be enabled on this device
  69. SupportedFeatures GetSupportedFeatures();
  70. // Protocol Features
  71. std::unique_ptr<CalibrationProtocol> calibration_protocol;
  72. std::unique_ptr<GenericProtocol> generic_protocol;
  73. std::unique_ptr<IrsProtocol> irs_protocol;
  74. std::unique_ptr<NfcProtocol> nfc_protocol;
  75. std::unique_ptr<JoyconPoller> joycon_poller;
  76. std::unique_ptr<RingConProtocol> ring_protocol;
  77. std::unique_ptr<RumbleProtocol> rumble_protocol;
  78. // Connection status
  79. std::atomic<bool> is_connected{};
  80. u64 delta_time;
  81. std::size_t error_counter{};
  82. std::shared_ptr<JoyconHandle> hidapi_handle;
  83. std::chrono::time_point<std::chrono::steady_clock> last_update;
  84. // External device status
  85. bool starlink_connected{};
  86. bool ring_connected{};
  87. bool amiibo_detected{};
  88. bool is_ring_disabled_by_irs{};
  89. // Harware configuration
  90. u8 leds{};
  91. ReportMode mode{};
  92. bool passive_enabled{}; // Low power mode, Ideal for multiple controllers at the same time
  93. bool hidbus_enabled{}; // External device support
  94. bool irs_enabled{}; // Infrared camera input
  95. bool motion_enabled{}; // Enables motion input
  96. bool nfc_enabled{}; // Enables Amiibo detection
  97. bool vibration_enabled{}; // Allows vibrations
  98. // Calibration data
  99. GyroSensitivity gyro_sensitivity{};
  100. GyroPerformance gyro_performance{};
  101. AccelerometerSensitivity accelerometer_sensitivity{};
  102. AccelerometerPerformance accelerometer_performance{};
  103. JoyStickCalibration left_stick_calibration{};
  104. JoyStickCalibration right_stick_calibration{};
  105. MotionCalibration motion_calibration{};
  106. RingCalibration ring_calibration{};
  107. // Fixed joycon info
  108. FirmwareVersion version{};
  109. Color color{};
  110. std::size_t port{};
  111. ControllerType device_type{}; // Device type reported by controller
  112. ControllerType handle_device_type{}; // Device type reported by hidapi
  113. SerialNumber serial_number{}; // Serial number reported by controller
  114. SerialNumber handle_serial_number{}; // Serial number type reported by hidapi
  115. SupportedFeatures supported_features{};
  116. // Thread related
  117. mutable std::mutex mutex;
  118. std::jthread input_thread;
  119. bool input_thread_running{};
  120. bool disable_input_thread{};
  121. };
  122. } // namespace InputCommon::Joycon