summaryrefslogtreecommitdiff
path: root/src/input_common/gcadapter/gc_adapter.cpp
diff options
context:
space:
mode:
authorGravatar Ameer2020-06-21 18:43:01 -0400
committerGravatar Ameer2020-06-21 21:17:07 -0400
commit121af3646dad0f80453d2ffffa688dd4435d3acc (patch)
tree020971e22b4423f63a0a04da7fa4087bf85e2bb9 /src/input_common/gcadapter/gc_adapter.cpp
parentClang Formatting (diff)
downloadyuzu-121af3646dad0f80453d2ffffa688dd4435d3acc.tar.gz
yuzu-121af3646dad0f80453d2ffffa688dd4435d3acc.tar.xz
yuzu-121af3646dad0f80453d2ffffa688dd4435d3acc.zip
Singleton GC Adapter class, remove globals, fix naming convention
Fix clang formatting Manual fix for configure_input_player formatting Add missing lib usb cmake command
Diffstat (limited to 'src/input_common/gcadapter/gc_adapter.cpp')
-rw-r--r--src/input_common/gcadapter/gc_adapter.cpp176
1 files changed, 87 insertions, 89 deletions
diff --git a/src/input_common/gcadapter/gc_adapter.cpp b/src/input_common/gcadapter/gc_adapter.cpp
index dc04116ce..0696a96c7 100644
--- a/src/input_common/gcadapter/gc_adapter.cpp
+++ b/src/input_common/gcadapter/gc_adapter.cpp
@@ -3,45 +3,41 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "common/threadsafe_queue.h"
7#include "input_common/gcadapter/gc_adapter.h" 6#include "input_common/gcadapter/gc_adapter.h"
8 7
9Common::SPSCQueue<GCPadStatus> pad_queue[4];
10struct GCState state[4];
11
12namespace GCAdapter { 8namespace GCAdapter {
9Adapter* Adapter::adapter_instance{nullptr};
13 10
14static libusb_device_handle* usb_adapter_handle = nullptr; 11Adapter::Adapter() {
15static u8 adapter_controllers_status[4] = { 12 if (usb_adapter_handle != nullptr) {
16 ControllerTypes::CONTROLLER_NONE, ControllerTypes::CONTROLLER_NONE, 13 return;
17 ControllerTypes::CONTROLLER_NONE, ControllerTypes::CONTROLLER_NONE}; 14 }
18 15 LOG_INFO(Input, "GC Adapter Initialization started");
19static std::mutex s_mutex;
20
21static std::thread adapter_input_thread;
22static bool adapter_thread_running;
23
24static std::mutex initialization_mutex;
25static std::thread detect_thread;
26static bool detect_thread_running = false;
27 16
28static libusb_context* libusb_ctx; 17 current_status = NO_ADAPTER_DETECTED;
18 libusb_init(&libusb_ctx);
29 19
30static u8 input_endpoint = 0; 20 StartScanThread();
21}
31 22
32static bool configuring = false; 23Adapter* Adapter::GetInstance() {
24 if (!adapter_instance) {
25 adapter_instance = new Adapter;
26 }
27 return adapter_instance;
28}
33 29
34GCPadStatus CheckStatus(int port, u8 adapter_payload[37]) { 30GCPadStatus Adapter::CheckStatus(int port, u8 adapter_payload[37]) {
35 GCPadStatus pad = {}; 31 GCPadStatus pad = {};
36 bool get_origin = false; 32 bool get_origin = false;
37 33
38 u8 type = adapter_payload[1 + (9 * port)] >> 4; 34 ControllerTypes type = ControllerTypes(adapter_payload[1 + (9 * port)] >> 4);
39 if (type) 35 if (type != ControllerTypes::None)
40 get_origin = true; 36 get_origin = true;
41 37
42 adapter_controllers_status[port] = type; 38 adapter_controllers_status[port] = type;
43 39
44 if (adapter_controllers_status[port] != ControllerTypes::CONTROLLER_NONE) { 40 if (adapter_controllers_status[port] != ControllerTypes::None) {
45 u8 b1 = adapter_payload[1 + (9 * port) + 1]; 41 u8 b1 = adapter_payload[1 + (9 * port) + 1];
46 u8 b2 = adapter_payload[1 + (9 * port) + 2]; 42 u8 b2 = adapter_payload[1 + (9 * port) + 2];
47 43
@@ -88,18 +84,17 @@ GCPadStatus CheckStatus(int port, u8 adapter_payload[37]) {
88 pad.button |= PAD_GET_ORIGIN; 84 pad.button |= PAD_GET_ORIGIN;
89 } 85 }
90 86
91 pad.stickX = adapter_payload[1 + (9 * port) + 3]; 87 pad.stick_x = adapter_payload[1 + (9 * port) + 3];
92 pad.stickY = adapter_payload[1 + (9 * port) + 4]; 88 pad.stick_y = adapter_payload[1 + (9 * port) + 4];
93 pad.substickX = adapter_payload[1 + (9 * port) + 5]; 89 pad.substick_x = adapter_payload[1 + (9 * port) + 5];
94 pad.substickY = adapter_payload[1 + (9 * port) + 6]; 90 pad.substick_y = adapter_payload[1 + (9 * port) + 6];
95 pad.triggerLeft = adapter_payload[1 + (9 * port) + 7]; 91 pad.trigger_left = adapter_payload[1 + (9 * port) + 7];
96 pad.triggerRight = adapter_payload[1 + (9 * port) + 8]; 92 pad.trigger_right = adapter_payload[1 + (9 * port) + 8];
97 } 93 }
98 return pad; 94 return pad;
99} 95}
100 96
101void PadToState(GCPadStatus pad, GCState& state) { 97void Adapter::PadToState(GCPadStatus pad, GCState& state) {
102 // std::lock_guard lock{s_mutex};
103 state.buttons.insert_or_assign(PAD_BUTTON_A, pad.button & PAD_BUTTON_A); 98 state.buttons.insert_or_assign(PAD_BUTTON_A, pad.button & PAD_BUTTON_A);
104 state.buttons.insert_or_assign(PAD_BUTTON_B, pad.button & PAD_BUTTON_B); 99 state.buttons.insert_or_assign(PAD_BUTTON_B, pad.button & PAD_BUTTON_B);
105 state.buttons.insert_or_assign(PAD_BUTTON_X, pad.button & PAD_BUTTON_X); 100 state.buttons.insert_or_assign(PAD_BUTTON_X, pad.button & PAD_BUTTON_X);
@@ -112,15 +107,15 @@ void PadToState(GCPadStatus pad, GCState& state) {
112 state.buttons.insert_or_assign(PAD_TRIGGER_Z, pad.button & PAD_TRIGGER_Z); 107 state.buttons.insert_or_assign(PAD_TRIGGER_Z, pad.button & PAD_TRIGGER_Z);
113 state.buttons.insert_or_assign(PAD_TRIGGER_L, pad.button & PAD_TRIGGER_L); 108 state.buttons.insert_or_assign(PAD_TRIGGER_L, pad.button & PAD_TRIGGER_L);
114 state.buttons.insert_or_assign(PAD_TRIGGER_R, pad.button & PAD_TRIGGER_R); 109 state.buttons.insert_or_assign(PAD_TRIGGER_R, pad.button & PAD_TRIGGER_R);
115 state.axes.insert_or_assign(STICK_X, pad.stickX); 110 state.axes.insert_or_assign(static_cast<u8>(PadAxes::StickX), pad.stick_x);
116 state.axes.insert_or_assign(STICK_Y, pad.stickY); 111 state.axes.insert_or_assign(static_cast<u8>(PadAxes::StickY), pad.stick_y);
117 state.axes.insert_or_assign(SUBSTICK_X, pad.substickX); 112 state.axes.insert_or_assign(static_cast<u8>(PadAxes::SubstickX), pad.substick_x);
118 state.axes.insert_or_assign(SUBSTICK_Y, pad.substickY); 113 state.axes.insert_or_assign(static_cast<u8>(PadAxes::SubstickY), pad.substick_y);
119 state.axes.insert_or_assign(TRIGGER_LEFT, pad.triggerLeft); 114 state.axes.insert_or_assign(static_cast<u8>(PadAxes::TriggerLeft), pad.trigger_left);
120 state.axes.insert_or_assign(TRIGGER_RIGHT, pad.triggerRight); 115 state.axes.insert_or_assign(static_cast<u8>(PadAxes::TriggerRight), pad.trigger_right);
121} 116}
122 117
123static void Read() { 118void Adapter::Read() {
124 LOG_INFO(Input, "GC Adapter Read() thread started"); 119 LOG_INFO(Input, "GC Adapter Read() thread started");
125 120
126 int payload_size_in; 121 int payload_size_in;
@@ -145,8 +140,9 @@ static void Read() {
145 LOG_ERROR(Input, "error reading payload (size: %d, type: %02x)", payload_size, 140 LOG_ERROR(Input, "error reading payload (size: %d, type: %02x)", payload_size,
146 controller_payload_copy[0]); 141 controller_payload_copy[0]);
147 } else { 142 } else {
148 for (int i = 0; i < 4; i++) 143 for (int port = 0; port < 4; port++) {
149 pad[i] = CheckStatus(i, controller_payload_copy); 144 pad[port] = CheckStatus(port, controller_payload_copy);
145 }
150 } 146 }
151 for (int port = 0; port < 4; port++) { 147 for (int port = 0; port < 4; port++) {
152 if (DeviceConnected(port) && configuring) { 148 if (DeviceConnected(port) && configuring) {
@@ -155,28 +151,36 @@ static void Read() {
155 } 151 }
156 152
157 // Accounting for a threshold here because of some controller variance 153 // Accounting for a threshold here because of some controller variance
158 if (pad[port].stickX > pad[port].MAIN_STICK_CENTER_X + pad[port].THRESHOLD || 154 if (pad[port].stick_x >
159 pad[port].stickX < pad[port].MAIN_STICK_CENTER_X - pad[port].THRESHOLD) { 155 pad_constants.MAIN_STICK_CENTER_X + pad_constants.THRESHOLD ||
160 pad[port].axis_which = STICK_X; 156 pad[port].stick_x <
161 pad[port].axis_value = pad[port].stickX; 157 pad_constants.MAIN_STICK_CENTER_X - pad_constants.THRESHOLD) {
158 pad[port].axis = GCAdapter::PadAxes::StickX;
159 pad[port].axis_value = pad[port].stick_x;
162 pad_queue[port].Push(pad[port]); 160 pad_queue[port].Push(pad[port]);
163 } 161 }
164 if (pad[port].stickY > pad[port].MAIN_STICK_CENTER_Y + pad[port].THRESHOLD || 162 if (pad[port].stick_y >
165 pad[port].stickY < pad[port].MAIN_STICK_CENTER_Y - pad[port].THRESHOLD) { 163 pad_constants.MAIN_STICK_CENTER_Y + pad_constants.THRESHOLD ||
166 pad[port].axis_which = STICK_Y; 164 pad[port].stick_y <
167 pad[port].axis_value = pad[port].stickY; 165 pad_constants.MAIN_STICK_CENTER_Y - pad_constants.THRESHOLD) {
166 pad[port].axis = GCAdapter::PadAxes::StickY;
167 pad[port].axis_value = pad[port].stick_y;
168 pad_queue[port].Push(pad[port]); 168 pad_queue[port].Push(pad[port]);
169 } 169 }
170 if (pad[port].substickX > pad[port].C_STICK_CENTER_X + pad[port].THRESHOLD || 170 if (pad[port].substick_x >
171 pad[port].substickX < pad[port].C_STICK_CENTER_X - pad[port].THRESHOLD) { 171 pad_constants.C_STICK_CENTER_X + pad_constants.THRESHOLD ||
172 pad[port].axis_which = SUBSTICK_X; 172 pad[port].substick_x <
173 pad[port].axis_value = pad[port].substickX; 173 pad_constants.C_STICK_CENTER_X - pad_constants.THRESHOLD) {
174 pad[port].axis = GCAdapter::PadAxes::SubstickX;
175 pad[port].axis_value = pad[port].substick_x;
174 pad_queue[port].Push(pad[port]); 176 pad_queue[port].Push(pad[port]);
175 } 177 }
176 if (pad[port].substickY > pad[port].C_STICK_CENTER_Y + pad[port].THRESHOLD || 178 if (pad[port].substick_y >
177 pad[port].substickY < pad[port].C_STICK_CENTER_Y - pad[port].THRESHOLD) { 179 pad_constants.C_STICK_CENTER_Y + pad_constants.THRESHOLD ||
178 pad[port].axis_which = SUBSTICK_Y; 180 pad[port].substick_y <
179 pad[port].axis_value = pad[port].substickY; 181 pad_constants.C_STICK_CENTER_Y - pad_constants.THRESHOLD) {
182 pad[port].axis = GCAdapter::PadAxes::SubstickY;
183 pad[port].axis_value = pad[port].substick_y;
180 pad_queue[port].Push(pad[port]); 184 pad_queue[port].Push(pad[port]);
181 } 185 }
182 } 186 }
@@ -186,7 +190,7 @@ static void Read() {
186 } 190 }
187} 191}
188 192
189static void ScanThreadFunc() { 193void Adapter::ScanThreadFunc() {
190 LOG_INFO(Input, "GC Adapter scanning thread started"); 194 LOG_INFO(Input, "GC Adapter scanning thread started");
191 195
192 while (detect_thread_running) { 196 while (detect_thread_running) {
@@ -198,20 +202,7 @@ static void ScanThreadFunc() {
198 } 202 }
199} 203}
200 204
201void Init() { 205void Adapter::StartScanThread() {
202
203 if (usb_adapter_handle != nullptr) {
204 return;
205 }
206 LOG_INFO(Input, "GC Adapter Initialization started");
207
208 current_status = NO_ADAPTER_DETECTED;
209 libusb_init(&libusb_ctx);
210
211 StartScanThread();
212}
213
214void StartScanThread() {
215 if (detect_thread_running) { 206 if (detect_thread_running) {
216 return; 207 return;
217 } 208 }
@@ -220,21 +211,21 @@ void StartScanThread() {
220 } 211 }
221 212
222 detect_thread_running = true; 213 detect_thread_running = true;
223 detect_thread = std::thread(ScanThreadFunc); 214 detect_thread = std::thread([=] { ScanThreadFunc(); });
224} 215}
225 216
226void StopScanThread() { 217void Adapter::StopScanThread() {
227 detect_thread.join(); 218 detect_thread.join();
228} 219}
229 220
230static void Setup() { 221void Adapter::Setup() {
231 // Reset the error status in case the adapter gets unplugged 222 // Reset the error status in case the adapter gets unplugged
232 if (current_status < 0) { 223 if (current_status < 0) {
233 current_status = NO_ADAPTER_DETECTED; 224 current_status = NO_ADAPTER_DETECTED;
234 } 225 }
235 226
236 for (int i = 0; i < 4; i++) { 227 for (int i = 0; i < 4; i++) {
237 adapter_controllers_status[i] = ControllerTypes::CONTROLLER_NONE; 228 adapter_controllers_status[i] = ControllerTypes::None;
238 } 229 }
239 230
240 libusb_device** devs; // pointer to list of connected usb devices 231 libusb_device** devs; // pointer to list of connected usb devices
@@ -250,7 +241,7 @@ static void Setup() {
250 } 241 }
251} 242}
252 243
253static bool CheckDeviceAccess(libusb_device* device) { 244bool Adapter::CheckDeviceAccess(libusb_device* device) {
254 libusb_device_descriptor desc; 245 libusb_device_descriptor desc;
255 int ret = libusb_get_device_descriptor(device, &desc); 246 int ret = libusb_get_device_descriptor(device, &desc);
256 if (ret) { 247 if (ret) {
@@ -300,7 +291,7 @@ static bool CheckDeviceAccess(libusb_device* device) {
300 return true; 291 return true;
301} 292}
302 293
303static void GetGCEndpoint(libusb_device* device) { 294void Adapter::GetGCEndpoint(libusb_device* device) {
304 libusb_config_descriptor* config = nullptr; 295 libusb_config_descriptor* config = nullptr;
305 libusb_get_config_descriptor(device, 0, &config); 296 libusb_get_config_descriptor(device, 0, &config);
306 for (u8 ic = 0; ic < config->bNumInterfaces; ic++) { 297 for (u8 ic = 0; ic < config->bNumInterfaces; ic++) {
@@ -318,18 +309,17 @@ static void GetGCEndpoint(libusb_device* device) {
318 309
319 adapter_thread_running = true; 310 adapter_thread_running = true;
320 current_status = ADAPTER_DETECTED; 311 current_status = ADAPTER_DETECTED;
321 312 adapter_input_thread = std::thread([=] { Read(); }); // Read input
322 adapter_input_thread = std::thread(Read); // Read input
323} 313}
324 314
325void Shutdown() { 315Adapter::~Adapter() {
326 StopScanThread(); 316 StopScanThread();
327 Reset(); 317 Reset();
328 318
329 current_status = NO_ADAPTER_DETECTED; 319 current_status = NO_ADAPTER_DETECTED;
330} 320}
331 321
332static void Reset() { 322void Adapter::Reset() {
333 std::unique_lock<std::mutex> lock(initialization_mutex, std::defer_lock); 323 std::unique_lock<std::mutex> lock(initialization_mutex, std::defer_lock);
334 if (!lock.try_lock()) { 324 if (!lock.try_lock()) {
335 return; 325 return;
@@ -343,7 +333,7 @@ static void Reset() {
343 } 333 }
344 334
345 for (int i = 0; i < 4; i++) { 335 for (int i = 0; i < 4; i++) {
346 adapter_controllers_status[i] = ControllerTypes::CONTROLLER_NONE; 336 adapter_controllers_status[i] = ControllerTypes::None;
347 } 337 }
348 338
349 current_status = NO_ADAPTER_DETECTED; 339 current_status = NO_ADAPTER_DETECTED;
@@ -355,20 +345,28 @@ static void Reset() {
355 } 345 }
356} 346}
357 347
358bool DeviceConnected(int port) { 348bool Adapter::DeviceConnected(int port) {
359 return adapter_controllers_status[port] != ControllerTypes::CONTROLLER_NONE; 349 return adapter_controllers_status[port] != ControllerTypes::None;
360} 350}
361 351
362void ResetDeviceType(int port) { 352void Adapter::ResetDeviceType(int port) {
363 adapter_controllers_status[port] = ControllerTypes::CONTROLLER_NONE; 353 adapter_controllers_status[port] = ControllerTypes::None;
364} 354}
365 355
366void BeginConfiguration() { 356void Adapter::BeginConfiguration() {
367 configuring = true; 357 configuring = true;
368} 358}
369 359
370void EndConfiguration() { 360void Adapter::EndConfiguration() {
371 configuring = false; 361 configuring = false;
372} 362}
373 363
364std::array<Common::SPSCQueue<GCPadStatus>, 4>& Adapter::GetPadQueue() {
365 return pad_queue;
366}
367
368std::array<GCState, 4>& Adapter::GetPadState() {
369 return state;
370}
371
374} // end of namespace GCAdapter 372} // end of namespace GCAdapter