| | |
| | |
| |
|
| | #pragma once |
| |
|
| | #include <array> |
| | #include <memory> |
| | #include <string> |
| | #include <thread> |
| |
|
| | #include "common/polyfill_thread.h" |
| | #include "input_common/input_engine.h" |
| |
|
| | struct libusb_context; |
| | struct libusb_device; |
| | struct libusb_device_handle; |
| |
|
| | namespace InputCommon { |
| |
|
| | class LibUSBContext; |
| | class LibUSBDeviceHandle; |
| |
|
| | class GCAdapter : public InputEngine { |
| | public: |
| | explicit GCAdapter(std::string input_engine_); |
| | ~GCAdapter() override; |
| |
|
| | Common::Input::DriverResult SetVibration( |
| | const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; |
| |
|
| | bool IsVibrationEnabled(const PadIdentifier& identifier) override; |
| |
|
| | |
| | std::vector<Common::ParamPackage> GetInputDevices() const override; |
| | ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override; |
| | AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) override; |
| | Common::Input::ButtonNames GetUIName(const Common::ParamPackage& params) const override; |
| |
|
| | bool IsStickInverted(const Common::ParamPackage& params) override; |
| |
|
| | private: |
| | enum class PadButton { |
| | Undefined = 0x0000, |
| | ButtonLeft = 0x0001, |
| | ButtonRight = 0x0002, |
| | ButtonDown = 0x0004, |
| | ButtonUp = 0x0008, |
| | TriggerZ = 0x0010, |
| | TriggerR = 0x0020, |
| | TriggerL = 0x0040, |
| | ButtonA = 0x0100, |
| | ButtonB = 0x0200, |
| | ButtonX = 0x0400, |
| | ButtonY = 0x0800, |
| | ButtonStart = 0x1000, |
| | }; |
| |
|
| | enum class PadAxes : u8 { |
| | StickX, |
| | StickY, |
| | SubstickX, |
| | SubstickY, |
| | TriggerLeft, |
| | TriggerRight, |
| | Undefined, |
| | }; |
| |
|
| | enum class ControllerTypes { |
| | None, |
| | Wired, |
| | Wireless, |
| | }; |
| |
|
| | struct GCController { |
| | ControllerTypes type = ControllerTypes::None; |
| | PadIdentifier identifier{}; |
| | bool enable_vibration = false; |
| | u8 rumble_amplitude{}; |
| | std::array<u8, 6> axis_origin{}; |
| | u8 reset_origin_counter{}; |
| | }; |
| |
|
| | using AdapterPayload = std::array<u8, 37>; |
| |
|
| | void UpdatePadType(std::size_t port, ControllerTypes pad_type); |
| | void UpdateControllers(const AdapterPayload& adapter_payload); |
| | void UpdateStateButtons(std::size_t port, u8 b1, u8 b2); |
| | void UpdateStateAxes(std::size_t port, const AdapterPayload& adapter_payload); |
| |
|
| | void AdapterInputThread(std::stop_token stop_token); |
| |
|
| | void AdapterScanThread(std::stop_token stop_token); |
| |
|
| | bool IsPayloadCorrect(const AdapterPayload& adapter_payload, s32 payload_size); |
| |
|
| | |
| | bool Setup(); |
| |
|
| | |
| | bool CheckDeviceAccess(); |
| |
|
| | |
| | |
| | bool GetGCEndpoint(libusb_device* device); |
| |
|
| | |
| | bool DeviceConnected(std::size_t port) const; |
| |
|
| | |
| | void Reset(); |
| |
|
| | void UpdateVibrations(); |
| |
|
| | |
| | void SendVibrations(); |
| |
|
| | Common::Input::ButtonNames GetUIButtonName(const Common::ParamPackage& params) const; |
| |
|
| | std::unique_ptr<LibUSBDeviceHandle> usb_adapter_handle; |
| | std::array<GCController, 4> pads; |
| |
|
| | std::jthread adapter_input_thread; |
| | std::jthread adapter_scan_thread; |
| | bool restart_scan_thread{}; |
| |
|
| | std::unique_ptr<LibUSBContext> libusb_ctx; |
| |
|
| | u8 input_endpoint{0}; |
| | u8 output_endpoint{0}; |
| | u8 input_error_counter{0}; |
| | u8 output_error_counter{0}; |
| | int vibration_counter{0}; |
| |
|
| | bool rumble_enabled{true}; |
| | bool vibration_changed{true}; |
| | }; |
| | } |
| |
|