summaryrefslogtreecommitdiff
path: root/src/input_common/gcadapter
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/gcadapter')
-rw-r--r--src/input_common/gcadapter/gc_adapter.cpp193
-rw-r--r--src/input_common/gcadapter/gc_adapter.h69
-rw-r--r--src/input_common/gcadapter/gc_poller.cpp84
-rw-r--r--src/input_common/gcadapter/gc_poller.h2
4 files changed, 132 insertions, 216 deletions
diff --git a/src/input_common/gcadapter/gc_adapter.cpp b/src/input_common/gcadapter/gc_adapter.cpp
index 6d9f4d9eb..c6c423c4b 100644
--- a/src/input_common/gcadapter/gc_adapter.cpp
+++ b/src/input_common/gcadapter/gc_adapter.cpp
@@ -4,6 +4,7 @@
#include <chrono>
#include <thread>
+#include <libusb.h>
#include "common/logging/log.h"
#include "input_common/gcadapter/gc_adapter.h"
@@ -23,26 +24,19 @@ Adapter::Adapter() {
}
LOG_INFO(Input, "GC Adapter Initialization started");
- current_status = NO_ADAPTER_DETECTED;
-
const int init_res = libusb_init(&libusb_ctx);
if (init_res == LIBUSB_SUCCESS) {
- StartScanThread();
+ Setup();
} else {
LOG_ERROR(Input, "libusb could not be initialized. failed with error = {}", init_res);
}
}
-GCPadStatus Adapter::GetPadStatus(int port, const std::array<u8, 37>& adapter_payload) {
+GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload) {
GCPadStatus pad = {};
- bool get_origin = false;
-
- ControllerTypes type = ControllerTypes(adapter_payload[1 + (9 * port)] >> 4);
- if (type != ControllerTypes::None) {
- get_origin = true;
- }
+ const std::size_t offset = 1 + (9 * port);
- adapter_controllers_status[port] = type;
+ adapter_controllers_status[port] = static_cast<ControllerTypes>(adapter_payload[offset] >> 4);
static constexpr std::array<PadButton, 8> b1_buttons{
PadButton::PAD_BUTTON_A, PadButton::PAD_BUTTON_B, PadButton::PAD_BUTTON_X,
@@ -57,9 +51,19 @@ GCPadStatus Adapter::GetPadStatus(int port, const std::array<u8, 37>& adapter_pa
PadButton::PAD_TRIGGER_L,
};
+ static constexpr std::array<PadAxes, 6> axes{
+ PadAxes::StickX, PadAxes::StickY, PadAxes::SubstickX,
+ PadAxes::SubstickY, PadAxes::TriggerLeft, PadAxes::TriggerRight,
+ };
+
+ if (adapter_controllers_status[port] == ControllerTypes::None && !get_origin[port]) {
+ // Controller may have been disconnected, recalibrate if reconnected.
+ get_origin[port] = true;
+ }
+
if (adapter_controllers_status[port] != ControllerTypes::None) {
- const u8 b1 = adapter_payload[1 + (9 * port) + 1];
- const u8 b2 = adapter_payload[1 + (9 * port) + 2];
+ const u8 b1 = adapter_payload[offset + 1];
+ const u8 b2 = adapter_payload[offset + 2];
for (std::size_t i = 0; i < b1_buttons.size(); ++i) {
if ((b1 & (1U << i)) != 0) {
@@ -72,17 +76,15 @@ GCPadStatus Adapter::GetPadStatus(int port, const std::array<u8, 37>& adapter_pa
pad.button |= static_cast<u16>(b2_buttons[j]);
}
}
-
- if (get_origin) {
- pad.button |= PAD_GET_ORIGIN;
+ for (PadAxes axis : axes) {
+ const std::size_t index = static_cast<std::size_t>(axis);
+ pad.axis_values[index] = adapter_payload[offset + 3 + index];
}
- pad.stick_x = adapter_payload[1 + (9 * port) + 3];
- pad.stick_y = adapter_payload[1 + (9 * port) + 4];
- pad.substick_x = adapter_payload[1 + (9 * port) + 5];
- pad.substick_y = adapter_payload[1 + (9 * port) + 6];
- pad.trigger_left = adapter_payload[1 + (9 * port) + 7];
- pad.trigger_right = adapter_payload[1 + (9 * port) + 8];
+ if (get_origin[port]) {
+ origin_status[port].axis_values = pad.axis_values;
+ get_origin[port] = false;
+ }
}
return pad;
}
@@ -93,82 +95,47 @@ void Adapter::PadToState(const GCPadStatus& pad, GCState& state) {
state.buttons.insert_or_assign(button_value, pad.button & button_value);
}
- state.axes.insert_or_assign(static_cast<u8>(PadAxes::StickX), pad.stick_x);
- state.axes.insert_or_assign(static_cast<u8>(PadAxes::StickY), pad.stick_y);
- state.axes.insert_or_assign(static_cast<u8>(PadAxes::SubstickX), pad.substick_x);
- state.axes.insert_or_assign(static_cast<u8>(PadAxes::SubstickY), pad.substick_y);
- state.axes.insert_or_assign(static_cast<u8>(PadAxes::TriggerLeft), pad.trigger_left);
- state.axes.insert_or_assign(static_cast<u8>(PadAxes::TriggerRight), pad.trigger_right);
+ for (size_t i = 0; i < pad.axis_values.size(); ++i) {
+ state.axes.insert_or_assign(static_cast<u8>(i), pad.axis_values[i]);
+ }
}
void Adapter::Read() {
LOG_DEBUG(Input, "GC Adapter Read() thread started");
- int payload_size_in, payload_size_copy;
+ int payload_size;
std::array<u8, 37> adapter_payload;
- std::array<u8, 37> adapter_payload_copy;
std::array<GCPadStatus, 4> pads;
while (adapter_thread_running) {
libusb_interrupt_transfer(usb_adapter_handle, input_endpoint, adapter_payload.data(),
- sizeof(adapter_payload), &payload_size_in, 16);
- payload_size_copy = 0;
- // this mutex might be redundant?
- {
- std::lock_guard<std::mutex> lk(s_mutex);
- std::copy(std::begin(adapter_payload), std::end(adapter_payload),
- std::begin(adapter_payload_copy));
- payload_size_copy = payload_size_in;
- }
+ sizeof(adapter_payload), &payload_size, 16);
- if (payload_size_copy != sizeof(adapter_payload_copy) ||
- adapter_payload_copy[0] != LIBUSB_DT_HID) {
- LOG_ERROR(Input, "error reading payload (size: {}, type: {:02x})", payload_size_copy,
- adapter_payload_copy[0]);
+ if (payload_size != sizeof(adapter_payload) || adapter_payload[0] != LIBUSB_DT_HID) {
+ LOG_ERROR(Input,
+ "Error reading payload (size: {}, type: {:02x}) Is the adapter connected?",
+ payload_size, adapter_payload[0]);
adapter_thread_running = false; // error reading from adapter, stop reading.
break;
}
for (std::size_t port = 0; port < pads.size(); ++port) {
- pads[port] = GetPadStatus(port, adapter_payload_copy);
+ pads[port] = GetPadStatus(port, adapter_payload);
if (DeviceConnected(port) && configuring) {
- if (pads[port].button != PAD_GET_ORIGIN) {
+ if (pads[port].button != 0) {
pad_queue[port].Push(pads[port]);
}
- // Accounting for a threshold here because of some controller variance
- if (pads[port].stick_x > pads[port].MAIN_STICK_CENTER_X + pads[port].THRESHOLD ||
- pads[port].stick_x < pads[port].MAIN_STICK_CENTER_X - pads[port].THRESHOLD) {
- pads[port].axis = GCAdapter::PadAxes::StickX;
- pads[port].axis_value = pads[port].stick_x;
- pad_queue[port].Push(pads[port]);
- }
- if (pads[port].stick_y > pads[port].MAIN_STICK_CENTER_Y + pads[port].THRESHOLD ||
- pads[port].stick_y < pads[port].MAIN_STICK_CENTER_Y - pads[port].THRESHOLD) {
- pads[port].axis = GCAdapter::PadAxes::StickY;
- pads[port].axis_value = pads[port].stick_y;
- pad_queue[port].Push(pads[port]);
- }
- if (pads[port].substick_x > pads[port].C_STICK_CENTER_X + pads[port].THRESHOLD ||
- pads[port].substick_x < pads[port].C_STICK_CENTER_X - pads[port].THRESHOLD) {
- pads[port].axis = GCAdapter::PadAxes::SubstickX;
- pads[port].axis_value = pads[port].substick_x;
- pad_queue[port].Push(pads[port]);
- }
- if (pads[port].substick_y > pads[port].C_STICK_CENTER_Y + pads[port].THRESHOLD ||
- pads[port].substick_y < pads[port].C_STICK_CENTER_Y - pads[port].THRESHOLD) {
- pads[port].axis = GCAdapter::PadAxes::SubstickY;
- pads[port].axis_value = pads[port].substick_y;
- pad_queue[port].Push(pads[port]);
- }
- if (pads[port].trigger_left > pads[port].TRIGGER_THRESHOLD) {
- pads[port].axis = GCAdapter::PadAxes::TriggerLeft;
- pads[port].axis_value = pads[port].trigger_left;
- pad_queue[port].Push(pads[port]);
- }
- if (pads[port].trigger_right > pads[port].TRIGGER_THRESHOLD) {
- pads[port].axis = GCAdapter::PadAxes::TriggerRight;
- pads[port].axis_value = pads[port].trigger_right;
- pad_queue[port].Push(pads[port]);
+ // Accounting for a threshold here to ensure an intentional press
+ for (size_t i = 0; i < pads[port].axis_values.size(); ++i) {
+ const u8 value = pads[port].axis_values[i];
+ const u8 origin = origin_status[port].axis_values[i];
+
+ if (value > origin + pads[port].THRESHOLD ||
+ value < origin - pads[port].THRESHOLD) {
+ pads[port].axis = static_cast<PadAxes>(i);
+ pads[port].axis_value = pads[port].axis_values[i];
+ pad_queue[port].Push(pads[port]);
+ }
}
}
PadToState(pads[port], state[port]);
@@ -177,42 +144,11 @@ void Adapter::Read() {
}
}
-void Adapter::ScanThreadFunc() {
- LOG_INFO(Input, "GC Adapter scanning thread started");
-
- while (detect_thread_running) {
- if (usb_adapter_handle == nullptr) {
- std::lock_guard<std::mutex> lk(initialization_mutex);
- Setup();
- }
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
- }
-}
-
-void Adapter::StartScanThread() {
- if (detect_thread_running) {
- return;
- }
- if (!libusb_ctx) {
- return;
- }
-
- detect_thread_running = true;
- detect_thread = std::thread([=] { ScanThreadFunc(); });
-}
-
-void Adapter::StopScanThread() {
- detect_thread_running = false;
- detect_thread.join();
-}
-
void Adapter::Setup() {
- // Reset the error status in case the adapter gets unplugged
- if (current_status < 0) {
- current_status = NO_ADAPTER_DETECTED;
- }
-
+ // Initialize all controllers as unplugged
adapter_controllers_status.fill(ControllerTypes::None);
+ // Initialize all ports to store axis origin values
+ get_origin.fill(true);
// pointer to list of connected usb devices
libusb_device** devices{};
@@ -221,13 +157,11 @@ void Adapter::Setup() {
const ssize_t device_count = libusb_get_device_list(libusb_ctx, &devices);
if (device_count < 0) {
LOG_ERROR(Input, "libusb_get_device_list failed with error: {}", device_count);
- detect_thread_running = false; // Stop the loop constantly checking for gc adapter
- // TODO: For hotplug+gc adapter checkbox implementation, revert this.
return;
}
if (devices != nullptr) {
- for (std::size_t index = 0; index < device_count; ++index) {
+ for (std::size_t index = 0; index < static_cast<std::size_t>(device_count); ++index) {
if (CheckDeviceAccess(devices[index])) {
// GC Adapter found and accessible, registering it
GetGCEndpoint(devices[index]);
@@ -320,31 +254,23 @@ void Adapter::GetGCEndpoint(libusb_device* device) {
sizeof(clear_payload), nullptr, 16);
adapter_thread_running = true;
- current_status = ADAPTER_DETECTED;
- adapter_input_thread = std::thread([=] { Read(); }); // Read input
+ adapter_input_thread = std::thread(&Adapter::Read, this);
}
Adapter::~Adapter() {
- StopScanThread();
Reset();
}
void Adapter::Reset() {
- std::unique_lock<std::mutex> lock(initialization_mutex, std::defer_lock);
- if (!lock.try_lock()) {
- return;
- }
- if (current_status != ADAPTER_DETECTED) {
- return;
- }
-
if (adapter_thread_running) {
adapter_thread_running = false;
}
- adapter_input_thread.join();
+ if (adapter_input_thread.joinable()) {
+ adapter_input_thread.join();
+ }
adapter_controllers_status.fill(ControllerTypes::None);
- current_status = NO_ADAPTER_DETECTED;
+ get_origin.fill(true);
if (usb_adapter_handle) {
libusb_release_interface(usb_adapter_handle, 1);
@@ -357,15 +283,16 @@ void Adapter::Reset() {
}
}
-bool Adapter::DeviceConnected(int port) {
+bool Adapter::DeviceConnected(std::size_t port) const {
return adapter_controllers_status[port] != ControllerTypes::None;
}
-void Adapter::ResetDeviceType(int port) {
+void Adapter::ResetDeviceType(std::size_t port) {
adapter_controllers_status[port] = ControllerTypes::None;
}
void Adapter::BeginConfiguration() {
+ get_origin.fill(true);
for (auto& pq : pad_queue) {
pq.Clear();
}
@@ -395,4 +322,8 @@ const std::array<GCState, 4>& Adapter::GetPadState() const {
return state;
}
+int Adapter::GetOriginValue(int port, int axis) const {
+ return origin_status[port].axis_values[axis];
+}
+
} // namespace GCAdapter
diff --git a/src/input_common/gcadapter/gc_adapter.h b/src/input_common/gcadapter/gc_adapter.h
index b1c2a1958..20e97d283 100644
--- a/src/input_common/gcadapter/gc_adapter.h
+++ b/src/input_common/gcadapter/gc_adapter.h
@@ -8,17 +8,14 @@
#include <mutex>
#include <thread>
#include <unordered_map>
-#include <libusb.h>
#include "common/common_types.h"
#include "common/threadsafe_queue.h"
-namespace GCAdapter {
+struct libusb_context;
+struct libusb_device;
+struct libusb_device_handle;
-enum {
- PAD_USE_ORIGIN = 0x0080,
- PAD_GET_ORIGIN = 0x2000,
- PAD_ERR_STATUS = 0x8000,
-};
+namespace GCAdapter {
enum class PadButton {
PAD_BUTTON_LEFT = 0x0001,
@@ -50,24 +47,10 @@ enum class PadAxes : u8 {
};
struct GCPadStatus {
- u16 button{}; // Or-ed PAD_BUTTON_* and PAD_TRIGGER_* bits
- u8 stick_x{}; // 0 <= stick_x <= 255
- u8 stick_y{}; // 0 <= stick_y <= 255
- u8 substick_x{}; // 0 <= substick_x <= 255
- u8 substick_y{}; // 0 <= substick_y <= 255
- u8 trigger_left{}; // 0 <= trigger_left <= 255
- u8 trigger_right{}; // 0 <= trigger_right <= 255
-
- static constexpr u8 MAIN_STICK_CENTER_X = 0x80;
- static constexpr u8 MAIN_STICK_CENTER_Y = 0x80;
- static constexpr u8 MAIN_STICK_RADIUS = 0x7f;
- static constexpr u8 C_STICK_CENTER_X = 0x80;
- static constexpr u8 C_STICK_CENTER_Y = 0x80;
- static constexpr u8 C_STICK_RADIUS = 0x7f;
- static constexpr u8 THRESHOLD = 10;
-
- // 256/4, at least a quarter press to count as a press. For polling mostly
- static constexpr u8 TRIGGER_THRESHOLD = 64;
+ u16 button{}; // Or-ed PAD_BUTTON_* and PAD_TRIGGER_* bits
+
+ std::array<u8, 6> axis_values{}; // Triggers and sticks, following indices defined in PadAxes
+ static constexpr u8 THRESHOLD = 50; // Threshold for axis press for polling
u8 port{};
PadAxes axis{PadAxes::Undefined};
@@ -81,11 +64,6 @@ struct GCState {
enum class ControllerTypes { None, Wired, Wireless };
-enum {
- NO_ADAPTER_DETECTED = 0,
- ADAPTER_DETECTED = 1,
-};
-
class Adapter {
public:
/// Initialize the GC Adapter capture and read sequence
@@ -97,30 +75,26 @@ public:
void BeginConfiguration();
void EndConfiguration();
+ /// Returns true if there is a device connected to port
+ bool DeviceConnected(std::size_t port) const;
+
std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue();
const std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue() const;
std::array<GCState, 4>& GetPadState();
const std::array<GCState, 4>& GetPadState() const;
+ int GetOriginValue(int port, int axis) const;
+
private:
- GCPadStatus GetPadStatus(int port, const std::array<u8, 37>& adapter_payload);
+ GCPadStatus GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload);
void PadToState(const GCPadStatus& pad, GCState& state);
void Read();
- void ScanThreadFunc();
- /// Begin scanning for the GC Adapter.
- void StartScanThread();
-
- /// Stop scanning for the adapter
- void StopScanThread();
-
- /// Returns true if there is a device connected to port
- bool DeviceConnected(int port);
/// Resets status of device connected to port
- void ResetDeviceType(int port);
+ void ResetDeviceType(std::size_t port);
/// Returns true if we successfully gain access to GC Adapter
bool CheckDeviceAccess(libusb_device* device);
@@ -134,19 +108,11 @@ private:
/// For use in initialization, querying devices to find the adapter
void Setup();
- int current_status = NO_ADAPTER_DETECTED;
libusb_device_handle* usb_adapter_handle = nullptr;
- std::array<ControllerTypes, 4> adapter_controllers_status{};
-
- std::mutex s_mutex;
std::thread adapter_input_thread;
bool adapter_thread_running;
- std::mutex initialization_mutex;
- std::thread detect_thread;
- bool detect_thread_running = false;
-
libusb_context* libusb_ctx;
u8 input_endpoint = 0;
@@ -154,8 +120,11 @@ private:
bool configuring = false;
- std::array<Common::SPSCQueue<GCPadStatus>, 4> pad_queue;
std::array<GCState, 4> state;
+ std::array<bool, 4> get_origin;
+ std::array<GCPadStatus, 4> origin_status;
+ std::array<Common::SPSCQueue<GCPadStatus>, 4> pad_queue;
+ std::array<ControllerTypes, 4> adapter_controllers_status{};
};
} // namespace GCAdapter
diff --git a/src/input_common/gcadapter/gc_poller.cpp b/src/input_common/gcadapter/gc_poller.cpp
index 385ce8430..92e9e8e89 100644
--- a/src/input_common/gcadapter/gc_poller.cpp
+++ b/src/input_common/gcadapter/gc_poller.cpp
@@ -6,6 +6,7 @@
#include <list>
#include <mutex>
#include <utility>
+#include "common/assert.h"
#include "common/threadsafe_queue.h"
#include "input_common/gcadapter/gc_adapter.h"
#include "input_common/gcadapter/gc_poller.h"
@@ -14,42 +15,44 @@ namespace InputCommon {
class GCButton final : public Input::ButtonDevice {
public:
- explicit GCButton(int port_, int button_, GCAdapter::Adapter* adapter)
+ explicit GCButton(int port_, int button_, const GCAdapter::Adapter* adapter)
: port(port_), button(button_), gcadapter(adapter) {}
~GCButton() override;
bool GetStatus() const override {
- return gcadapter->GetPadState()[port].buttons.at(button);
+ if (gcadapter->DeviceConnected(port)) {
+ return gcadapter->GetPadState()[port].buttons.at(button);
+ }
+ return false;
}
private:
const int port;
const int button;
- GCAdapter::Adapter* gcadapter;
+ const GCAdapter::Adapter* gcadapter;
};
class GCAxisButton final : public Input::ButtonDevice {
public:
explicit GCAxisButton(int port_, int axis_, float threshold_, bool trigger_if_greater_,
- GCAdapter::Adapter* adapter)
+ const GCAdapter::Adapter* adapter)
: port(port_), axis(axis_), threshold(threshold_), trigger_if_greater(trigger_if_greater_),
- gcadapter(adapter) {
- // L/R triggers range is only in positive direction beginning near 0
- // 0.0 threshold equates to near half trigger press, but threshold accounts for variability.
- if (axis > 3) {
- threshold *= -0.5;
- }
- }
+ gcadapter(adapter),
+ origin_value(static_cast<float>(adapter->GetOriginValue(port_, axis_))) {}
bool GetStatus() const override {
- const float axis_value = (gcadapter->GetPadState()[port].axes.at(axis) - 128.0f) / 128.0f;
- if (trigger_if_greater) {
- // TODO: Might be worthwile to set a slider for the trigger threshold. It is currently
- // always set to 0.5 in configure_input_player.cpp ZL/ZR HandleClick
- return axis_value > threshold;
+ if (gcadapter->DeviceConnected(port)) {
+ const float current_axis_value = gcadapter->GetPadState()[port].axes.at(axis);
+ const float axis_value = (current_axis_value - origin_value) / 128.0f;
+ if (trigger_if_greater) {
+ // TODO: Might be worthwile to set a slider for the trigger threshold. It is
+ // currently always set to 0.5 in configure_input_player.cpp ZL/ZR HandleClick
+ return axis_value > threshold;
+ }
+ return axis_value < -threshold;
}
- return axis_value < -threshold;
+ return false;
}
private:
@@ -57,7 +60,8 @@ private:
const int axis;
float threshold;
bool trigger_if_greater;
- GCAdapter::Adapter* gcadapter;
+ const GCAdapter::Adapter* gcadapter;
+ const float origin_value;
};
GCButtonFactory::GCButtonFactory(std::shared_ptr<GCAdapter::Adapter> adapter_)
@@ -73,8 +77,7 @@ std::unique_ptr<Input::ButtonDevice> GCButtonFactory::Create(const Common::Param
// button is not an axis/stick button
if (button_id != PAD_STICK_ID) {
- auto button = std::make_unique<GCButton>(port, button_id, adapter.get());
- return std::move(button);
+ return std::make_unique<GCButton>(port, button_id, adapter.get());
}
// For Axis buttons, used by the binary sticks.
@@ -94,9 +97,12 @@ std::unique_ptr<Input::ButtonDevice> GCButtonFactory::Create(const Common::Param
return std::make_unique<GCAxisButton>(port, axis, threshold, trigger_if_greater,
adapter.get());
}
+
+ UNREACHABLE();
+ return nullptr;
}
-Common::ParamPackage GCButtonFactory::GetNextInput() {
+Common::ParamPackage GCButtonFactory::GetNextInput() const {
Common::ParamPackage params;
GCAdapter::GCPadStatus pad;
auto& queue = adapter->GetPadQueue();
@@ -143,15 +149,20 @@ void GCButtonFactory::EndConfiguration() {
class GCAnalog final : public Input::AnalogDevice {
public:
- GCAnalog(int port_, int axis_x_, int axis_y_, float deadzone_, GCAdapter::Adapter* adapter)
- : port(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), gcadapter(adapter) {}
+ GCAnalog(int port_, int axis_x_, int axis_y_, float deadzone_,
+ const GCAdapter::Adapter* adapter, float range_)
+ : port(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), gcadapter(adapter),
+ origin_value_x(static_cast<float>(adapter->GetOriginValue(port_, axis_x_))),
+ origin_value_y(static_cast<float>(adapter->GetOriginValue(port_, axis_y_))),
+ range(range_) {}
float GetAxis(int axis) const {
- std::lock_guard lock{mutex};
- // division is not by a perfect 128 to account for some variance in center location
- // e.g. my device idled at 131 in X, 120 in Y, and full range of motion was in range
- // [20-230]
- return (gcadapter->GetPadState()[port].axes.at(axis) - 128.0f) / 95.0f;
+ if (gcadapter->DeviceConnected(port)) {
+ std::lock_guard lock{mutex};
+ const auto origin_value = axis % 2 == 0 ? origin_value_x : origin_value_y;
+ return (gcadapter->GetPadState()[port].axes.at(axis) - origin_value) / (100.0f * range);
+ }
+ return 0.0f;
}
std::pair<float, float> GetAnalog(int axis_x, int axis_y) const {
@@ -182,7 +193,7 @@ public:
bool GetAnalogDirectionStatus(Input::AnalogDirection direction) const override {
const auto [x, y] = GetStatus();
- const float directional_deadzone = 0.4f;
+ const float directional_deadzone = 0.5f;
switch (direction) {
case Input::AnalogDirection::RIGHT:
return x > directional_deadzone;
@@ -201,8 +212,11 @@ private:
const int axis_x;
const int axis_y;
const float deadzone;
+ const GCAdapter::Adapter* gcadapter;
+ const float origin_value_x;
+ const float origin_value_y;
+ const float range;
mutable std::mutex mutex;
- GCAdapter::Adapter* gcadapter;
};
/// An analog device factory that creates analog devices from GC Adapter
@@ -220,9 +234,10 @@ std::unique_ptr<Input::AnalogDevice> GCAnalogFactory::Create(const Common::Param
const int port = params.Get("port", 0);
const int axis_x = params.Get("axis_x", 0);
const int axis_y = params.Get("axis_y", 1);
- const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, .99f);
+ const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
+ const float range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
- return std::make_unique<GCAnalog>(port, axis_x, axis_y, deadzone, adapter.get());
+ return std::make_unique<GCAnalog>(port, axis_x, axis_y, deadzone, adapter.get(), range);
}
void GCAnalogFactory::BeginConfiguration() {
@@ -249,8 +264,9 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() {
const u8 axis = static_cast<u8>(pad.axis);
if (analog_x_axis == -1) {
analog_x_axis = axis;
- controller_number = port;
- } else if (analog_y_axis == -1 && analog_x_axis != axis && controller_number == port) {
+ controller_number = static_cast<int>(port);
+ } else if (analog_y_axis == -1 && analog_x_axis != axis &&
+ controller_number == static_cast<int>(port)) {
analog_y_axis = axis;
}
}
diff --git a/src/input_common/gcadapter/gc_poller.h b/src/input_common/gcadapter/gc_poller.h
index e96af7d51..0527f328f 100644
--- a/src/input_common/gcadapter/gc_poller.h
+++ b/src/input_common/gcadapter/gc_poller.h
@@ -25,7 +25,7 @@ public:
*/
std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override;
- Common::ParamPackage GetNextInput();
+ Common::ParamPackage GetNextInput() const;
/// For device input configuration/polling
void BeginConfiguration();