diff options
Diffstat (limited to 'src/input_common/gcadapter/gc_poller.cpp')
| -rw-r--r-- | src/input_common/gcadapter/gc_poller.cpp | 128 |
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 | ||
| 16 | class GCButton final : public Input::ButtonDevice { | 16 | class GCButton final : public Input::ButtonDevice { |
| 17 | public: | 17 | public: |
| 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 | |||
| 30 | private: | 38 | private: |
| 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 | ||
| 36 | class GCAxisButton final : public Input::ButtonDevice { | 44 | class 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 | ||
| 67 | GCButtonFactory::GCButtonFactory(std::shared_ptr<GCAdapter::Adapter> adapter_) | 73 | GCButtonFactory::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 | ||
| 255 | Common::ParamPackage GCAnalogFactory::GetNextInput() { | 249 | Common::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); |