2022-12-20 11:34:33 -06:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2023-01-13 23:29:05 -06:00
|
|
|
#include <atomic>
|
2022-12-20 11:34:33 -06:00
|
|
|
#include <functional>
|
|
|
|
#include <mutex>
|
|
|
|
#include <span>
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
#include "input_common/helpers/joycon_protocol/joycon_types.h"
|
|
|
|
|
|
|
|
namespace InputCommon::Joycon {
|
2022-12-22 01:07:46 -06:00
|
|
|
class CalibrationProtocol;
|
|
|
|
class GenericProtocol;
|
2022-12-28 15:21:12 -06:00
|
|
|
class IrsProtocol;
|
2022-12-22 01:07:46 -06:00
|
|
|
class NfcProtocol;
|
|
|
|
class JoyconPoller;
|
|
|
|
class RingConProtocol;
|
|
|
|
class RumbleProtocol;
|
2022-12-20 11:34:33 -06:00
|
|
|
|
|
|
|
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);
|
2022-12-28 15:21:12 -06:00
|
|
|
DriverResult SetIrsConfig(IrsMode mode_, IrsResolution format_);
|
2023-03-07 20:15:46 -06:00
|
|
|
DriverResult SetPassiveMode();
|
2022-12-20 11:34:33 -06:00
|
|
|
DriverResult SetActiveMode();
|
2022-12-28 15:21:12 -06:00
|
|
|
DriverResult SetIrMode();
|
2022-12-20 11:34:33 -06:00
|
|
|
DriverResult SetNfcMode();
|
|
|
|
DriverResult SetRingConMode();
|
2023-05-17 23:17:16 -05:00
|
|
|
DriverResult WriteNfcData(std::span<const u8> data);
|
2022-12-20 11:34:33 -06:00
|
|
|
|
2022-12-26 11:11:01 -06:00
|
|
|
void SetCallbacks(const JoyconCallbacks& callbacks);
|
2022-12-20 20:27:34 -06:00
|
|
|
|
2022-12-20 11:34:33 -06:00
|
|
|
// Returns device type from hidapi handle
|
2022-12-26 11:11:01 -06:00
|
|
|
static DriverResult GetDeviceType(SDL_hid_device_info* device_info,
|
|
|
|
ControllerType& controller_type);
|
2022-12-20 11:34:33 -06:00
|
|
|
|
|
|
|
// Returns serial number from hidapi handle
|
2022-12-26 11:11:01 -06:00
|
|
|
static DriverResult GetSerialNumber(SDL_hid_device_info* device_info,
|
|
|
|
SerialNumber& serial_number);
|
2022-12-20 11:34:33 -06:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2023-03-11 21:10:38 -06:00
|
|
|
/// Called every time a valid package arrives
|
2022-12-20 11:34:33 -06:00
|
|
|
void OnNewData(std::span<u8> buffer);
|
|
|
|
|
|
|
|
/// Updates device configuration to enable or disable features
|
2022-12-26 12:49:49 -06:00
|
|
|
DriverResult SetPollingMode();
|
2022-12-20 11:34:33 -06:00
|
|
|
|
|
|
|
/// 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<const u8> buffer);
|
|
|
|
|
|
|
|
/// Returns a list of supported features that can be enabled on this device
|
|
|
|
SupportedFeatures GetSupportedFeatures();
|
|
|
|
|
|
|
|
// Protocol Features
|
2022-12-22 01:07:46 -06:00
|
|
|
std::unique_ptr<CalibrationProtocol> calibration_protocol;
|
|
|
|
std::unique_ptr<GenericProtocol> generic_protocol;
|
2022-12-28 15:21:12 -06:00
|
|
|
std::unique_ptr<IrsProtocol> irs_protocol;
|
2022-12-22 01:07:46 -06:00
|
|
|
std::unique_ptr<NfcProtocol> nfc_protocol;
|
|
|
|
std::unique_ptr<JoyconPoller> joycon_poller;
|
|
|
|
std::unique_ptr<RingConProtocol> ring_protocol;
|
|
|
|
std::unique_ptr<RumbleProtocol> rumble_protocol;
|
2022-12-20 11:34:33 -06:00
|
|
|
|
|
|
|
// Connection status
|
2023-01-13 23:29:05 -06:00
|
|
|
std::atomic<bool> is_connected{};
|
2022-12-20 11:34:33 -06:00
|
|
|
u64 delta_time;
|
|
|
|
std::size_t error_counter{};
|
2022-12-22 01:07:46 -06:00
|
|
|
std::shared_ptr<JoyconHandle> hidapi_handle;
|
2022-12-20 11:34:33 -06:00
|
|
|
std::chrono::time_point<std::chrono::steady_clock> last_update;
|
|
|
|
|
|
|
|
// External device status
|
|
|
|
bool starlink_connected{};
|
|
|
|
bool ring_connected{};
|
|
|
|
bool amiibo_detected{};
|
2023-01-02 22:11:03 -06:00
|
|
|
bool is_ring_disabled_by_irs{};
|
2022-12-20 11:34:33 -06:00
|
|
|
|
2023-03-11 21:10:38 -06:00
|
|
|
// Hardware configuration
|
2022-12-20 11:34:33 -06:00
|
|
|
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{};
|
2022-12-20 19:10:42 -06:00
|
|
|
RingCalibration ring_calibration{};
|
2022-12-20 11:34:33 -06:00
|
|
|
|
|
|
|
// 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
|