summaryrefslogtreecommitdiff
path: root/src/input_common/gcadapter/gc_poller.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_poller.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_poller.cpp')
-rw-r--r--src/input_common/gcadapter/gc_poller.cpp125
1 files changed, 65 insertions, 60 deletions
diff --git a/src/input_common/gcadapter/gc_poller.cpp b/src/input_common/gcadapter/gc_poller.cpp
index 51b3362d6..0e591baca 100644
--- a/src/input_common/gcadapter/gc_poller.cpp
+++ b/src/input_common/gcadapter/gc_poller.cpp
@@ -10,35 +10,34 @@
10#include "input_common/gcadapter/gc_adapter.h" 10#include "input_common/gcadapter/gc_adapter.h"
11#include "input_common/gcadapter/gc_poller.h" 11#include "input_common/gcadapter/gc_poller.h"
12 12
13// Using extern as to avoid multply defined symbols.
14extern Common::SPSCQueue<GCPadStatus> pad_queue[4];
15extern struct GCState state[4];
16
17namespace InputCommon { 13namespace InputCommon {
18 14
19class GCButton final : public Input::ButtonDevice { 15class GCButton final : public Input::ButtonDevice {
20public: 16public:
21 explicit GCButton(int port_, int button_, int axis_) : port(port_), button(button_) {} 17 explicit GCButton(int port_, int button_, int axis_, GCAdapter::Adapter* adapter)
18 : port(port_), button(button_), gcadapter(adapter) {}
22 19
23 ~GCButton() override; 20 ~GCButton() override;
24 21
25 bool GetStatus() const override { 22 bool GetStatus() const override {
26 return state[port].buttons.at(button); 23 return gcadapter->GetPadState()[port].buttons.at(button);
27 } 24 }
28 25
29private: 26private:
30 const int port; 27 const int port;
31 const int button; 28 const int button;
29 GCAdapter::Adapter* gcadapter;
32}; 30};
33 31
34class GCAxisButton final : public Input::ButtonDevice { 32class GCAxisButton final : public Input::ButtonDevice {
35public: 33public:
36 explicit GCAxisButton(int port_, int axis_, float threshold_, bool trigger_if_greater_) 34 explicit GCAxisButton(int port_, int axis_, float threshold_, bool trigger_if_greater_,
37 : port(port_), axis(axis_), threshold(threshold_), trigger_if_greater(trigger_if_greater_) { 35 GCAdapter::Adapter* adapter)
38 } 36 : port(port_), axis(axis_), threshold(threshold_), trigger_if_greater(trigger_if_greater_),
37 gcadapter(adapter) {}
39 38
40 bool GetStatus() const override { 39 bool GetStatus() const override {
41 const float axis_value = (state[port].axes.at(axis) - 128.0f) / 128.0f; 40 const float axis_value = (gcadapter->GetPadState()[port].axes.at(axis) - 128.0f) / 128.0f;
42 if (trigger_if_greater) { 41 if (trigger_if_greater) {
43 return axis_value > 0.10f; // TODO(ameerj) : Fix threshold. 42 return axis_value > 0.10f; // TODO(ameerj) : Fix threshold.
44 } 43 }
@@ -50,14 +49,15 @@ private:
50 const int axis; 49 const int axis;
51 float threshold; 50 float threshold;
52 bool trigger_if_greater; 51 bool trigger_if_greater;
52 GCAdapter::Adapter* gcadapter;
53}; 53};
54 54
55GCButtonFactory::GCButtonFactory() { 55GCButtonFactory::GCButtonFactory() {
56 GCAdapter::Init(); 56 adapter = GCAdapter::Adapter::GetInstance();
57} 57}
58 58
59GCButton::~GCButton() { 59GCButton::~GCButton() {
60 GCAdapter::Shutdown(); 60 // GCAdapter::Shutdown();
61} 61}
62 62
63std::unique_ptr<Input::ButtonDevice> GCButtonFactory::Create(const Common::ParamPackage& params) { 63std::unique_ptr<Input::ButtonDevice> GCButtonFactory::Create(const Common::ParamPackage& params) {
@@ -77,76 +77,76 @@ std::unique_ptr<Input::ButtonDevice> GCButtonFactory::Create(const Common::Param
77 trigger_if_greater = true; 77 trigger_if_greater = true;
78 LOG_ERROR(Input, "Unknown direction {}", direction_name); 78 LOG_ERROR(Input, "Unknown direction {}", direction_name);
79 } 79 }
80 return std::make_unique<GCAxisButton>(port, axis, threshold, trigger_if_greater); 80 return std::make_unique<GCAxisButton>(port, axis, threshold, trigger_if_greater, adapter);
81 } 81 }
82 82
83 std::unique_ptr<GCButton> button = 83 std::unique_ptr<GCButton> button =
84 std::make_unique<GCButton>(port, button_id, params.Get("axis", 0)); 84 std::make_unique<GCButton>(port, button_id, params.Get("axis", 0), adapter);
85 return std::move(button); 85 return std::move(button);
86} 86}
87 87
88Common::ParamPackage GCButtonFactory::GetNextInput() { 88Common::ParamPackage GCButtonFactory::GetNextInput() {
89 Common::ParamPackage params; 89 Common::ParamPackage params;
90 GCPadStatus pad; 90 GCAdapter::GCPadStatus pad;
91 for (int i = 0; i < 4; i++) { 91 for (int i = 0; i < 4; i++) {
92 while (pad_queue[i].Pop(pad)) { 92 while (adapter->GetPadQueue()[i].Pop(pad)) {
93 // This while loop will break on the earliest detected button 93 // This while loop will break on the earliest detected button
94 params.Set("engine", "gcpad"); 94 params.Set("engine", "gcpad");
95 params.Set("port", i); 95 params.Set("port", i);
96 // I was debating whether to keep these verbose for ease of reading 96 // I was debating whether to keep these verbose for ease of reading
97 // or to use a while loop shifting the bits to test and set the value. 97 // or to use a while loop shifting the bits to test and set the value.
98 if (pad.button & PAD_BUTTON_A) { 98 if (pad.button & GCAdapter::PAD_BUTTON_A) {
99 params.Set("button", PAD_BUTTON_A); 99 params.Set("button", GCAdapter::PAD_BUTTON_A);
100 break; 100 break;
101 } 101 }
102 if (pad.button & PAD_BUTTON_B) { 102 if (pad.button & GCAdapter::PAD_BUTTON_B) {
103 params.Set("button", PAD_BUTTON_B); 103 params.Set("button", GCAdapter::PAD_BUTTON_B);
104 break; 104 break;
105 } 105 }
106 if (pad.button & PAD_BUTTON_X) { 106 if (pad.button & GCAdapter::PAD_BUTTON_X) {
107 params.Set("button", PAD_BUTTON_X); 107 params.Set("button", GCAdapter::PAD_BUTTON_X);
108 break; 108 break;
109 } 109 }
110 if (pad.button & PAD_BUTTON_Y) { 110 if (pad.button & GCAdapter::PAD_BUTTON_Y) {
111 params.Set("button", PAD_BUTTON_Y); 111 params.Set("button", GCAdapter::PAD_BUTTON_Y);
112 break; 112 break;
113 } 113 }
114 if (pad.button & PAD_BUTTON_DOWN) { 114 if (pad.button & GCAdapter::PAD_BUTTON_DOWN) {
115 params.Set("button", PAD_BUTTON_DOWN); 115 params.Set("button", GCAdapter::PAD_BUTTON_DOWN);
116 break; 116 break;
117 } 117 }
118 if (pad.button & PAD_BUTTON_LEFT) { 118 if (pad.button & GCAdapter::PAD_BUTTON_LEFT) {
119 params.Set("button", PAD_BUTTON_LEFT); 119 params.Set("button", GCAdapter::PAD_BUTTON_LEFT);
120 break; 120 break;
121 } 121 }
122 if (pad.button & PAD_BUTTON_RIGHT) { 122 if (pad.button & GCAdapter::PAD_BUTTON_RIGHT) {
123 params.Set("button", PAD_BUTTON_RIGHT); 123 params.Set("button", GCAdapter::PAD_BUTTON_RIGHT);
124 break; 124 break;
125 } 125 }
126 if (pad.button & PAD_BUTTON_UP) { 126 if (pad.button & GCAdapter::PAD_BUTTON_UP) {
127 params.Set("button", PAD_BUTTON_UP); 127 params.Set("button", GCAdapter::PAD_BUTTON_UP);
128 break; 128 break;
129 } 129 }
130 if (pad.button & PAD_TRIGGER_L) { 130 if (pad.button & GCAdapter::PAD_TRIGGER_L) {
131 params.Set("button", PAD_TRIGGER_L); 131 params.Set("button", GCAdapter::PAD_TRIGGER_L);
132 break; 132 break;
133 } 133 }
134 if (pad.button & PAD_TRIGGER_R) { 134 if (pad.button & GCAdapter::PAD_TRIGGER_R) {
135 params.Set("button", PAD_TRIGGER_R); 135 params.Set("button", GCAdapter::PAD_TRIGGER_R);
136 break; 136 break;
137 } 137 }
138 if (pad.button & PAD_TRIGGER_Z) { 138 if (pad.button & GCAdapter::PAD_TRIGGER_Z) {
139 params.Set("button", PAD_TRIGGER_Z); 139 params.Set("button", GCAdapter::PAD_TRIGGER_Z);
140 break; 140 break;
141 } 141 }
142 if (pad.button & PAD_BUTTON_START) { 142 if (pad.button & GCAdapter::PAD_BUTTON_START) {
143 params.Set("button", PAD_BUTTON_START); 143 params.Set("button", GCAdapter::PAD_BUTTON_START);
144 break; 144 break;
145 } 145 }
146 // For Axis button implementation 146 // For Axis button implementation
147 if (pad.axis_which != 255) { 147 if (pad.axis != GCAdapter::PadAxes::Undefined) {
148 params.Set("axis", pad.axis_which); 148 params.Set("axis", static_cast<u8>(pad.axis));
149 params.Set("button", PAD_STICK); 149 params.Set("button", GCAdapter::PAD_STICK);
150 if (pad.axis_value > 128) { 150 if (pad.axis_value > 128) {
151 params.Set("direction", "+"); 151 params.Set("direction", "+");
152 params.Set("threshold", "0.5"); 152 params.Set("threshold", "0.5");
@@ -164,30 +164,30 @@ Common::ParamPackage GCButtonFactory::GetNextInput() {
164void GCButtonFactory::BeginConfiguration() { 164void GCButtonFactory::BeginConfiguration() {
165 polling = true; 165 polling = true;
166 for (int i = 0; i < 4; i++) { 166 for (int i = 0; i < 4; i++) {
167 pad_queue[i].Clear(); 167 adapter->GetPadQueue()[i].Clear();
168 } 168 }
169 GCAdapter::BeginConfiguration(); 169 adapter->BeginConfiguration();
170} 170}
171 171
172void GCButtonFactory::EndConfiguration() { 172void GCButtonFactory::EndConfiguration() {
173 polling = false; 173 polling = false;
174 for (int i = 0; i < 4; i++) { 174 for (int i = 0; i < 4; i++) {
175 pad_queue[i].Clear(); 175 adapter->GetPadQueue()[i].Clear();
176 } 176 }
177 GCAdapter::EndConfiguration(); 177 adapter->EndConfiguration();
178} 178}
179 179
180class GCAnalog final : public Input::AnalogDevice { 180class GCAnalog final : public Input::AnalogDevice {
181public: 181public:
182 GCAnalog(int port_, int axis_x_, int axis_y_, float deadzone_) 182 GCAnalog(int port_, int axis_x_, int axis_y_, float deadzone_, GCAdapter::Adapter* adapter)
183 : port(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_) {} 183 : port(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), gcadapter(adapter) {}
184 184
185 float GetAxis(int axis) const { 185 float GetAxis(int axis) const {
186 std::lock_guard lock{mutex}; 186 std::lock_guard lock{mutex};
187 // division is not by a perfect 128 to account for some variance in center location 187 // division is not by a perfect 128 to account for some variance in center location
188 // e.g. my device idled at 131 in X, 120 in Y, and full range of motion was in range 188 // e.g. my device idled at 131 in X, 120 in Y, and full range of motion was in range
189 // [20-230] 189 // [20-230]
190 return (state[port].axes.at(axis) - 128.0f) / 95.0f; 190 return (gcadapter->GetPadState()[port].axes.at(axis) - 128.0f) / 95.0f;
191 } 191 }
192 192
193 std::tuple<float, float> GetAnalog(int axis_x, int axis_y) const { 193 std::tuple<float, float> GetAnalog(int axis_x, int axis_y) const {
@@ -238,10 +238,13 @@ private:
238 const int axis_y; 238 const int axis_y;
239 const float deadzone; 239 const float deadzone;
240 mutable std::mutex mutex; 240 mutable std::mutex mutex;
241 GCAdapter::Adapter* gcadapter;
241}; 242};
242 243
243/// An analog device factory that creates analog devices from GC Adapter 244/// An analog device factory that creates analog devices from GC Adapter
244GCAnalogFactory::GCAnalogFactory(){}; 245GCAnalogFactory::GCAnalogFactory() {
246 adapter = GCAdapter::Adapter::GetInstance();
247};
245 248
246/** 249/**
247 * Creates analog device from joystick axes 250 * Creates analog device from joystick axes
@@ -257,35 +260,36 @@ std::unique_ptr<Input::AnalogDevice> GCAnalogFactory::Create(const Common::Param
257 const int axis_y = params.Get("axis_y", 1); 260 const int axis_y = params.Get("axis_y", 1);
258 const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, .99f); 261 const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, .99f);
259 262
260 return std::make_unique<GCAnalog>(port, axis_x, axis_y, deadzone); 263 return std::make_unique<GCAnalog>(port, axis_x, axis_y, deadzone, adapter);
261} 264}
262 265
263void GCAnalogFactory::BeginConfiguration() { 266void GCAnalogFactory::BeginConfiguration() {
264 polling = true; 267 polling = true;
265 for (int i = 0; i < 4; i++) { 268 for (int i = 0; i < 4; i++) {
266 pad_queue[i].Clear(); 269 adapter->GetPadQueue()[i].Clear();
267 } 270 }
268 GCAdapter::BeginConfiguration(); 271 adapter->BeginConfiguration();
269} 272}
270 273
271void GCAnalogFactory::EndConfiguration() { 274void GCAnalogFactory::EndConfiguration() {
272 polling = false; 275 polling = false;
273 for (int i = 0; i < 4; i++) { 276 for (int i = 0; i < 4; i++) {
274 pad_queue[i].Clear(); 277 adapter->GetPadQueue()[i].Clear();
275 } 278 }
276 GCAdapter::EndConfiguration(); 279 adapter->EndConfiguration();
277} 280}
278 281
279Common::ParamPackage GCAnalogFactory::GetNextInput() { 282Common::ParamPackage GCAnalogFactory::GetNextInput() {
280 GCPadStatus pad; 283 GCAdapter::GCPadStatus pad;
281 for (int i = 0; i < 4; i++) { 284 for (int i = 0; i < 4; i++) {
282 while (pad_queue[i].Pop(pad)) { 285 while (adapter->GetPadQueue()[i].Pop(pad)) {
283 if (pad.axis_which == 255 || std::abs((pad.axis_value - 128.0f) / 128.0f) < 0.1) { 286 if (pad.axis == GCAdapter::PadAxes::Undefined ||
287 std::abs((pad.axis_value - 128.0f) / 128.0f) < 0.1) {
284 continue; 288 continue;
285 } 289 }
286 // An analog device needs two axes, so we need to store the axis for later and wait for 290 // An analog device needs two axes, so we need to store the axis for later and wait for
287 // a second SDL event. The axes also must be from the same joystick. 291 // a second SDL event. The axes also must be from the same joystick.
288 const int axis = pad.axis_which; 292 const u8 axis = static_cast<u8>(pad.axis);
289 if (analog_x_axis == -1) { 293 if (analog_x_axis == -1) {
290 analog_x_axis = axis; 294 analog_x_axis = axis;
291 controller_number = i; 295 controller_number = i;
@@ -307,4 +311,5 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() {
307 } 311 }
308 return params; 312 return params;
309} 313}
314
310} // namespace InputCommon 315} // namespace InputCommon