joycon_driver.h 5.9 KB

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