From d80e6c399bf8196646cca5ac1265d122638bb96b Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Tue, 20 Dec 2022 11:34:33 -0600 Subject: input_common: Initial skeleton for custom joycon driver --- src/input_common/helpers/joycon_driver.h | 146 +++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 src/input_common/helpers/joycon_driver.h (limited to 'src/input_common/helpers/joycon_driver.h') diff --git a/src/input_common/helpers/joycon_driver.h b/src/input_common/helpers/joycon_driver.h new file mode 100644 index 000000000..be3053a7b --- /dev/null +++ b/src/input_common/helpers/joycon_driver.h @@ -0,0 +1,146 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include + +#include "input_common/helpers/joycon_protocol/joycon_types.h" + +namespace InputCommon::Joycon { + +class JoyconDriver final { +public: + explicit JoyconDriver(std::size_t port_); + + ~JoyconDriver(); + + DriverResult RequestDeviceAccess(SDL_hid_device_info* device_info); + DriverResult InitializeDevice(); + void Stop(); + + bool IsConnected() const; + bool IsVibrationEnabled() const; + + FirmwareVersion GetDeviceVersion() const; + Color GetDeviceColor() const; + std::size_t GetDevicePort() const; + ControllerType GetDeviceType() const; + ControllerType GetHandleDeviceType() const; + SerialNumber GetSerialNumber() const; + SerialNumber GetHandleSerialNumber() const; + + DriverResult SetVibration(const VibrationValue& vibration); + DriverResult SetLedConfig(u8 led_pattern); + DriverResult SetPasiveMode(); + DriverResult SetActiveMode(); + DriverResult SetNfcMode(); + DriverResult SetRingConMode(); + + // Returns device type from hidapi handle + static Joycon::DriverResult GetDeviceType(SDL_hid_device_info* device_info, + Joycon::ControllerType& controller_type); + + // Returns serial number from hidapi handle + static Joycon::DriverResult GetSerialNumber(SDL_hid_device_info* device_info, + Joycon::SerialNumber& serial_number); + + std::function on_battery_data; + std::function on_color_data; + std::function on_button_data; + std::function on_stick_data; + std::function on_motion_data; + std::function on_ring_data; + std::function&)> on_amiibo_data; + +private: + struct SupportedFeatures { + bool passive{}; + bool hidbus{}; + bool irs{}; + bool motion{}; + bool nfc{}; + bool vibration{}; + }; + + /// Main thread, actively request new data from the handle + void InputThread(std::stop_token stop_token); + + /// Called everytime a valid package arrives + void OnNewData(std::span buffer); + + /// Updates device configuration to enable or disable features + void SetPollingMode(); + + /// Returns true if input thread is valid and doesn't need to be stopped + bool IsInputThreadValid() const; + + /// Returns true if the data should be interpreted. Otherwise the error counter is incremented + bool IsPayloadCorrect(int status, std::span buffer); + + /// Returns a list of supported features that can be enabled on this device + SupportedFeatures GetSupportedFeatures(); + + /// Handles data from passive packages + void ReadPassiveMode(std::span buffer); + + /// Handles data from active packages + void ReadActiveMode(std::span buffer); + + /// Handles data from nfc or ir packages + void ReadNfcIRMode(std::span buffer); + + // Protocol Features + + // Connection status + bool is_connected{}; + u64 delta_time; + std::size_t error_counter{}; + std::shared_ptr hidapi_handle = nullptr; + std::chrono::time_point last_update; + + // External device status + bool starlink_connected{}; + bool ring_connected{}; + bool amiibo_detected{}; + + // Harware configuration + u8 leds{}; + ReportMode mode{}; + bool passive_enabled{}; // Low power mode, Ideal for multiple controllers at the same time + bool hidbus_enabled{}; // External device support + bool irs_enabled{}; // Infrared camera input + bool motion_enabled{}; // Enables motion input + bool nfc_enabled{}; // Enables Amiibo detection + bool vibration_enabled{}; // Allows vibrations + + // Calibration data + GyroSensitivity gyro_sensitivity{}; + GyroPerformance gyro_performance{}; + AccelerometerSensitivity accelerometer_sensitivity{}; + AccelerometerPerformance accelerometer_performance{}; + JoyStickCalibration left_stick_calibration{}; + JoyStickCalibration right_stick_calibration{}; + MotionCalibration motion_calibration{}; + + // Fixed joycon info + FirmwareVersion version{}; + Color color{}; + std::size_t port{}; + ControllerType device_type{}; // Device type reported by controller + ControllerType handle_device_type{}; // Device type reported by hidapi + SerialNumber serial_number{}; // Serial number reported by controller + SerialNumber handle_serial_number{}; // Serial number type reported by hidapi + SupportedFeatures supported_features{}; + + // Thread related + mutable std::mutex mutex; + std::jthread input_thread; + bool input_thread_running{}; + bool disable_input_thread{}; +}; + +} // namespace InputCommon::Joycon -- cgit v1.2.3