summaryrefslogtreecommitdiff
path: root/src/input_common/drivers/gc_adapter.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/input_common/drivers/gc_adapter.h128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/input_common/drivers/gc_adapter.h b/src/input_common/drivers/gc_adapter.h
new file mode 100644
index 000000000..c0bf1ed7a
--- /dev/null
+++ b/src/input_common/drivers/gc_adapter.h
@@ -0,0 +1,128 @@
1// Copyright 2014 Dolphin Emulator Project
2// Licensed under GPLv2+
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <mutex>
8#include <stop_token>
9#include <thread>
10
11#include "input_common/input_engine.h"
12
13struct libusb_context;
14struct libusb_device;
15struct libusb_device_handle;
16
17namespace InputCommon {
18
19class LibUSBContext;
20class LibUSBDeviceHandle;
21
22class GCAdapter : public InputCommon::InputEngine {
23public:
24 explicit GCAdapter(const std::string input_engine_);
25 ~GCAdapter();
26
27 bool SetRumble(const PadIdentifier& identifier,
28 const Input::VibrationStatus vibration) override;
29
30 /// Used for automapping features
31 std::vector<Common::ParamPackage> GetInputDevices() const override;
32 ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override;
33 AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) override;
34 std::string GetUIName(const Common::ParamPackage& params) const override;
35
36private:
37 enum class PadButton {
38 Undefined = 0x0000,
39 ButtonLeft = 0x0001,
40 ButtonRight = 0x0002,
41 ButtonDown = 0x0004,
42 ButtonUp = 0x0008,
43 TriggerZ = 0x0010,
44 TriggerR = 0x0020,
45 TriggerL = 0x0040,
46 ButtonA = 0x0100,
47 ButtonB = 0x0200,
48 ButtonX = 0x0400,
49 ButtonY = 0x0800,
50 ButtonStart = 0x1000,
51 };
52
53 enum class PadAxes : u8 {
54 StickX,
55 StickY,
56 SubstickX,
57 SubstickY,
58 TriggerLeft,
59 TriggerRight,
60 Undefined,
61 };
62
63 enum class ControllerTypes {
64 None,
65 Wired,
66 Wireless,
67 };
68
69 struct GCController {
70 ControllerTypes type = ControllerTypes::None;
71 PadIdentifier identifier{};
72 bool enable_vibration = false;
73 u8 rumble_amplitude{};
74 std::array<u8, 6> axis_origin{};
75 u8 reset_origin_counter{};
76 };
77
78 using AdapterPayload = std::array<u8, 37>;
79
80 void UpdatePadType(std::size_t port, ControllerTypes pad_type);
81 void UpdateControllers(const AdapterPayload& adapter_payload);
82 void UpdateStateButtons(std::size_t port, u8 b1, u8 b2);
83 void UpdateStateAxes(std::size_t port, const AdapterPayload& adapter_payload);
84
85 void AdapterInputThread(std::stop_token stop_token);
86
87 void AdapterScanThread(std::stop_token stop_token);
88
89 bool IsPayloadCorrect(const AdapterPayload& adapter_payload, s32 payload_size);
90
91 /// For use in initialization, querying devices to find the adapter
92 bool Setup();
93
94 /// Returns true if we successfully gain access to GC Adapter
95 bool CheckDeviceAccess();
96
97 /// Captures GC Adapter endpoint address
98 /// Returns true if the endpoint was set correctly
99 bool GetGCEndpoint(libusb_device* device);
100
101 /// Returns true if there is a device connected to port
102 bool DeviceConnected(std::size_t port) const;
103
104 /// For shutting down, clear all data, join all threads, release usb
105 void Reset();
106
107 void UpdateVibrations();
108 // Updates vibration state of all controllers
109 void SendVibrations();
110 std::unique_ptr<LibUSBDeviceHandle> usb_adapter_handle;
111 std::array<GCController, 4> pads;
112
113 std::jthread adapter_input_thread;
114 std::jthread adapter_scan_thread;
115 bool restart_scan_thread{};
116
117 std::unique_ptr<LibUSBContext> libusb_ctx;
118
119 u8 input_endpoint{0};
120 u8 output_endpoint{0};
121 u8 input_error_counter{0};
122 u8 output_error_counter{0};
123 int vibration_counter{0};
124
125 bool rumble_enabled{true};
126 bool vibration_changed{true};
127};
128} // namespace InputCommon