summaryrefslogtreecommitdiff
path: root/src/input_common/gcadapter/gc_poller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/gcadapter/gc_poller.cpp')
-rw-r--r--src/input_common/gcadapter/gc_poller.cpp128
1 files changed, 70 insertions, 58 deletions
diff --git a/src/input_common/gcadapter/gc_poller.cpp b/src/input_common/gcadapter/gc_poller.cpp
index 893556916..6bd6f57fc 100644
--- a/src/input_common/gcadapter/gc_poller.cpp
+++ b/src/input_common/gcadapter/gc_poller.cpp
@@ -15,22 +15,30 @@ namespace InputCommon {
15 15
16class GCButton final : public Input::ButtonDevice { 16class GCButton final : public Input::ButtonDevice {
17public: 17public:
18 explicit GCButton(u32 port_, int button_, const GCAdapter::Adapter* adapter) 18 explicit GCButton(u32 port_, s32 button_, GCAdapter::Adapter* adapter)
19 : port(port_), button(button_), gcadapter(adapter) {} 19 : port(port_), button(button_), gcadapter(adapter) {}
20 20
21 ~GCButton() override; 21 ~GCButton() override;
22 22
23 bool GetStatus() const override { 23 bool GetStatus() const override {
24 if (gcadapter->DeviceConnected(port)) { 24 if (gcadapter->DeviceConnected(port)) {
25 return gcadapter->GetPadState()[port].buttons.at(button); 25 return (gcadapter->GetPadState(port).buttons & button) != 0;
26 } 26 }
27 return false; 27 return false;
28 } 28 }
29 29
30 bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const override {
31 const float amplitude = amp_high + amp_low > 2.0f ? 1.0f : (amp_high + amp_low) * 0.5f;
32 const auto new_amp =
33 static_cast<f32>(pow(amplitude, 0.5f) * (3.0f - 2.0f * pow(amplitude, 0.15f)));
34
35 return gcadapter->RumblePlay(port, new_amp);
36 }
37
30private: 38private:
31 const u32 port; 39 const u32 port;
32 const int button; 40 const s32 button;
33 const GCAdapter::Adapter* gcadapter; 41 GCAdapter::Adapter* gcadapter;
34}; 42};
35 43
36class GCAxisButton final : public Input::ButtonDevice { 44class GCAxisButton final : public Input::ButtonDevice {
@@ -38,13 +46,12 @@ public:
38 explicit GCAxisButton(u32 port_, u32 axis_, float threshold_, bool trigger_if_greater_, 46 explicit GCAxisButton(u32 port_, u32 axis_, float threshold_, bool trigger_if_greater_,
39 const GCAdapter::Adapter* adapter) 47 const GCAdapter::Adapter* adapter)
40 : port(port_), axis(axis_), threshold(threshold_), trigger_if_greater(trigger_if_greater_), 48 : port(port_), axis(axis_), threshold(threshold_), trigger_if_greater(trigger_if_greater_),
41 gcadapter(adapter), 49 gcadapter(adapter) {}
42 origin_value(static_cast<float>(adapter->GetOriginValue(port_, axis_))) {}
43 50
44 bool GetStatus() const override { 51 bool GetStatus() const override {
45 if (gcadapter->DeviceConnected(port)) { 52 if (gcadapter->DeviceConnected(port)) {
46 const float current_axis_value = gcadapter->GetPadState()[port].axes.at(axis); 53 const float current_axis_value = gcadapter->GetPadState(port).axis_values.at(axis);
47 const float axis_value = (current_axis_value - origin_value) / 128.0f; 54 const float axis_value = current_axis_value / 128.0f;
48 if (trigger_if_greater) { 55 if (trigger_if_greater) {
49 // TODO: Might be worthwile to set a slider for the trigger threshold. It is 56 // TODO: Might be worthwile to set a slider for the trigger threshold. It is
50 // currently always set to 0.5 in configure_input_player.cpp ZL/ZR HandleClick 57 // currently always set to 0.5 in configure_input_player.cpp ZL/ZR HandleClick
@@ -61,7 +68,6 @@ private:
61 float threshold; 68 float threshold;
62 bool trigger_if_greater; 69 bool trigger_if_greater;
63 const GCAdapter::Adapter* gcadapter; 70 const GCAdapter::Adapter* gcadapter;
64 const float origin_value;
65}; 71};
66 72
67GCButtonFactory::GCButtonFactory(std::shared_ptr<GCAdapter::Adapter> adapter_) 73GCButtonFactory::GCButtonFactory(std::shared_ptr<GCAdapter::Adapter> adapter_)
@@ -73,7 +79,7 @@ std::unique_ptr<Input::ButtonDevice> GCButtonFactory::Create(const Common::Param
73 const auto button_id = params.Get("button", 0); 79 const auto button_id = params.Get("button", 0);
74 const auto port = static_cast<u32>(params.Get("port", 0)); 80 const auto port = static_cast<u32>(params.Get("port", 0));
75 81
76 constexpr int PAD_STICK_ID = static_cast<u16>(GCAdapter::PadButton::PAD_STICK); 82 constexpr s32 PAD_STICK_ID = static_cast<s32>(GCAdapter::PadButton::Stick);
77 83
78 // button is not an axis/stick button 84 // button is not an axis/stick button
79 if (button_id != PAD_STICK_ID) { 85 if (button_id != PAD_STICK_ID) {
@@ -106,32 +112,25 @@ Common::ParamPackage GCButtonFactory::GetNextInput() const {
106 Common::ParamPackage params; 112 Common::ParamPackage params;
107 GCAdapter::GCPadStatus pad; 113 GCAdapter::GCPadStatus pad;
108 auto& queue = adapter->GetPadQueue(); 114 auto& queue = adapter->GetPadQueue();
109 for (std::size_t port = 0; port < queue.size(); ++port) { 115 while (queue.Pop(pad)) {
110 while (queue[port].Pop(pad)) { 116 // This while loop will break on the earliest detected button
111 // This while loop will break on the earliest detected button 117 params.Set("engine", "gcpad");
112 params.Set("engine", "gcpad"); 118 params.Set("port", static_cast<s32>(pad.port));
113 params.Set("port", static_cast<int>(port)); 119 if (pad.button != GCAdapter::PadButton::Undefined) {
114 for (const auto& button : GCAdapter::PadButtonArray) { 120 params.Set("button", static_cast<u16>(pad.button));
115 const u16 button_value = static_cast<u16>(button); 121 }
116 if (pad.button & button_value) {
117 params.Set("button", button_value);
118 break;
119 }
120 }
121 122
122 // For Axis button implementation 123 // For Axis button implementation
123 if (pad.axis != GCAdapter::PadAxes::Undefined) { 124 if (pad.axis != GCAdapter::PadAxes::Undefined) {
124 params.Set("axis", static_cast<u8>(pad.axis)); 125 params.Set("axis", static_cast<u8>(pad.axis));
125 params.Set("button", static_cast<u16>(GCAdapter::PadButton::PAD_STICK)); 126 params.Set("button", static_cast<u16>(GCAdapter::PadButton::Stick));
126 if (pad.axis_value > 128) { 127 params.Set("threshold", "0.25");
127 params.Set("direction", "+"); 128 if (pad.axis_value > 0) {
128 params.Set("threshold", "0.25"); 129 params.Set("direction", "+");
129 } else { 130 } else {
130 params.Set("direction", "-"); 131 params.Set("direction", "-");
131 params.Set("threshold", "-0.25");
132 }
133 break;
134 } 132 }
133 break;
135 } 134 }
136 } 135 }
137 return params; 136 return params;
@@ -152,17 +151,14 @@ public:
152 explicit GCAnalog(u32 port_, u32 axis_x_, u32 axis_y_, float deadzone_, 151 explicit GCAnalog(u32 port_, u32 axis_x_, u32 axis_y_, float deadzone_,
153 const GCAdapter::Adapter* adapter, float range_) 152 const GCAdapter::Adapter* adapter, float range_)
154 : port(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), gcadapter(adapter), 153 : port(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), gcadapter(adapter),
155 origin_value_x(static_cast<float>(adapter->GetOriginValue(port_, axis_x_))),
156 origin_value_y(static_cast<float>(adapter->GetOriginValue(port_, axis_y_))),
157 range(range_) {} 154 range(range_) {}
158 155
159 float GetAxis(u32 axis) const { 156 float GetAxis(u32 axis) const {
160 if (gcadapter->DeviceConnected(port)) { 157 if (gcadapter->DeviceConnected(port)) {
161 std::lock_guard lock{mutex}; 158 std::lock_guard lock{mutex};
162 const auto origin_value = axis % 2 == 0 ? origin_value_x : origin_value_y;
163 const auto axis_value = 159 const auto axis_value =
164 static_cast<float>(gcadapter->GetPadState()[port].axes.at(axis)); 160 static_cast<float>(gcadapter->GetPadState(port).axis_values.at(axis));
165 return (axis_value - origin_value) / (100.0f * range); 161 return (axis_value) / (100.0f * range);
166 } 162 }
167 return 0.0f; 163 return 0.0f;
168 } 164 }
@@ -215,8 +211,6 @@ private:
215 const u32 axis_y; 211 const u32 axis_y;
216 const float deadzone; 212 const float deadzone;
217 const GCAdapter::Adapter* gcadapter; 213 const GCAdapter::Adapter* gcadapter;
218 const float origin_value_x;
219 const float origin_value_y;
220 const float range; 214 const float range;
221 mutable std::mutex mutex; 215 mutable std::mutex mutex;
222}; 216};
@@ -254,26 +248,44 @@ void GCAnalogFactory::EndConfiguration() {
254 248
255Common::ParamPackage GCAnalogFactory::GetNextInput() { 249Common::ParamPackage GCAnalogFactory::GetNextInput() {
256 GCAdapter::GCPadStatus pad; 250 GCAdapter::GCPadStatus pad;
251 Common::ParamPackage params;
257 auto& queue = adapter->GetPadQueue(); 252 auto& queue = adapter->GetPadQueue();
258 for (std::size_t port = 0; port < queue.size(); ++port) { 253 while (queue.Pop(pad)) {
259 while (queue[port].Pop(pad)) { 254 if (pad.button != GCAdapter::PadButton::Undefined) {
260 if (pad.axis == GCAdapter::PadAxes::Undefined || 255 params.Set("engine", "gcpad");
261 std::abs((static_cast<float>(pad.axis_value) - 128.0f) / 128.0f) < 0.1f) { 256 params.Set("port", static_cast<s32>(pad.port));
262 continue; 257 params.Set("button", static_cast<u16>(pad.button));
263 } 258 return params;
264 // An analog device needs two axes, so we need to store the axis for later and wait for 259 }
265 // a second input event. The axes also must be from the same joystick. 260 if (pad.axis == GCAdapter::PadAxes::Undefined ||
266 const u8 axis = static_cast<u8>(pad.axis); 261 std::abs(static_cast<float>(pad.axis_value) / 128.0f) < 0.1f) {
267 if (analog_x_axis == -1) { 262 continue;
268 analog_x_axis = axis; 263 }
269 controller_number = static_cast<int>(port); 264 // An analog device needs two axes, so we need to store the axis for later and wait for
270 } else if (analog_y_axis == -1 && analog_x_axis != axis && 265 // a second input event. The axes also must be from the same joystick.
271 controller_number == static_cast<int>(port)) { 266 const u8 axis = static_cast<u8>(pad.axis);
272 analog_y_axis = axis; 267 if (axis == 0 || axis == 1) {
273 } 268 analog_x_axis = 0;
269 analog_y_axis = 1;
270 controller_number = static_cast<s32>(pad.port);
271 break;
272 }
273 if (axis == 2 || axis == 3) {
274 analog_x_axis = 2;
275 analog_y_axis = 3;
276 controller_number = static_cast<s32>(pad.port);
277 break;
278 }
279
280 if (analog_x_axis == -1) {
281 analog_x_axis = axis;
282 controller_number = static_cast<s32>(pad.port);
283 } else if (analog_y_axis == -1 && analog_x_axis != axis &&
284 controller_number == static_cast<s32>(pad.port)) {
285 analog_y_axis = axis;
286 break;
274 } 287 }
275 } 288 }
276 Common::ParamPackage params;
277 if (analog_x_axis != -1 && analog_y_axis != -1) { 289 if (analog_x_axis != -1 && analog_y_axis != -1) {
278 params.Set("engine", "gcpad"); 290 params.Set("engine", "gcpad");
279 params.Set("port", controller_number); 291 params.Set("port", controller_number);