summaryrefslogtreecommitdiffstats
path: root/src/input_common
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/input_common/gcadapter/gc_adapter.cpp88
-rw-r--r--src/input_common/gcadapter/gc_adapter.h5
-rw-r--r--src/input_common/main.cpp11
3 files changed, 103 insertions, 1 deletions
diff --git a/src/input_common/gcadapter/gc_adapter.cpp b/src/input_common/gcadapter/gc_adapter.cpp
index c507c9891..89c148aba 100644
--- a/src/input_common/gcadapter/gc_adapter.cpp
+++ b/src/input_common/gcadapter/gc_adapter.cpp
@@ -15,7 +15,9 @@
#endif
#include "common/logging/log.h"
+#include "common/param_package.h"
#include "input_common/gcadapter/gc_adapter.h"
+#include "input_common/settings.h"
namespace GCAdapter {
@@ -292,6 +294,92 @@ void Adapter::Reset() {
}
}
+std::vector<Common::ParamPackage> Adapter::GetInputDevices() const {
+ std::vector<Common::ParamPackage> devices;
+ for (std::size_t port = 0; port < state.size(); ++port) {
+ if (!DeviceConnected(port)) {
+ continue;
+ }
+ std::string name = fmt::format("Gamecube Controller {}", port);
+ devices.emplace_back(Common::ParamPackage{
+ {"class", "gcpad"},
+ {"display", std::move(name)},
+ {"port", std::to_string(port)},
+ });
+ }
+ return devices;
+}
+
+InputCommon::ButtonMapping Adapter::GetButtonMappingForDevice(
+ const Common::ParamPackage& params) const {
+ // This list is missing ZL/ZR since those are not considered buttons.
+ // We will add those afterwards
+ // This list also excludes any button that can't be really mapped
+ static constexpr std::array<std::pair<Settings::NativeButton::Values, PadButton>, 12>
+ switch_to_gcadapter_button = {
+ std::pair{Settings::NativeButton::A, PadButton::PAD_BUTTON_A},
+ {Settings::NativeButton::B, PadButton::PAD_BUTTON_B},
+ {Settings::NativeButton::X, PadButton::PAD_BUTTON_X},
+ {Settings::NativeButton::Y, PadButton::PAD_BUTTON_Y},
+ {Settings::NativeButton::Plus, PadButton::PAD_BUTTON_START},
+ {Settings::NativeButton::DLeft, PadButton::PAD_BUTTON_LEFT},
+ {Settings::NativeButton::DUp, PadButton::PAD_BUTTON_UP},
+ {Settings::NativeButton::DRight, PadButton::PAD_BUTTON_RIGHT},
+ {Settings::NativeButton::DDown, PadButton::PAD_BUTTON_DOWN},
+ {Settings::NativeButton::SL, PadButton::PAD_TRIGGER_L},
+ {Settings::NativeButton::SR, PadButton::PAD_TRIGGER_R},
+ {Settings::NativeButton::R, PadButton::PAD_TRIGGER_Z},
+ };
+ if (!params.Has("port")) {
+ return {};
+ }
+
+ InputCommon::ButtonMapping mapping{};
+ for (const auto& [switch_button, gcadapter_button] : switch_to_gcadapter_button) {
+ Common::ParamPackage button_params({{"engine", "gcpad"}});
+ button_params.Set("port", params.Get("port", 0));
+ button_params.Set("button", static_cast<int>(gcadapter_button));
+ mapping.insert_or_assign(switch_button, std::move(button_params));
+ }
+
+ // Add the missing bindings for ZL/ZR
+ static constexpr std::array<std::pair<Settings::NativeButton::Values, PadAxes>, 2>
+ switch_to_gcadapter_axis = {
+ std::pair{Settings::NativeButton::ZL, PadAxes::TriggerLeft},
+ {Settings::NativeButton::ZR, PadAxes::TriggerRight},
+ };
+ for (const auto& [switch_button, gcadapter_axis] : switch_to_gcadapter_axis) {
+ Common::ParamPackage button_params({{"engine", "gcpad"}});
+ button_params.Set("port", params.Get("port", 0));
+ button_params.Set("button", static_cast<int>(PadButton::PAD_STICK));
+ button_params.Set("axis", static_cast<int>(gcadapter_axis));
+ mapping.insert_or_assign(switch_button, std::move(button_params));
+ }
+ return mapping;
+}
+
+InputCommon::AnalogMapping Adapter::GetAnalogMappingForDevice(
+ const Common::ParamPackage& params) const {
+ if (!params.Has("port")) {
+ return {};
+ }
+
+ InputCommon::AnalogMapping mapping = {};
+ Common::ParamPackage left_analog_params;
+ left_analog_params.Set("engine", "gcpad");
+ left_analog_params.Set("port", params.Get("port", 0));
+ left_analog_params.Set("axis_x", static_cast<int>(PadAxes::StickX));
+ left_analog_params.Set("axis_y", static_cast<int>(PadAxes::StickY));
+ mapping.insert_or_assign(Settings::NativeAnalog::LStick, std::move(left_analog_params));
+ Common::ParamPackage right_analog_params;
+ right_analog_params.Set("engine", "gcpad");
+ right_analog_params.Set("port", params.Get("port", 0));
+ right_analog_params.Set("axis_x", static_cast<int>(PadAxes::SubstickX));
+ right_analog_params.Set("axis_y", static_cast<int>(PadAxes::SubstickY));
+ mapping.insert_or_assign(Settings::NativeAnalog::RStick, std::move(right_analog_params));
+ return mapping;
+}
+
bool Adapter::DeviceConnected(std::size_t port) const {
return adapter_controllers_status[port] != ControllerTypes::None;
}
diff --git a/src/input_common/gcadapter/gc_adapter.h b/src/input_common/gcadapter/gc_adapter.h
index 20e97d283..75bf9fe74 100644
--- a/src/input_common/gcadapter/gc_adapter.h
+++ b/src/input_common/gcadapter/gc_adapter.h
@@ -10,6 +10,7 @@
#include <unordered_map>
#include "common/common_types.h"
#include "common/threadsafe_queue.h"
+#include "input_common/main.h"
struct libusb_context;
struct libusb_device;
@@ -75,6 +76,10 @@ public:
void BeginConfiguration();
void EndConfiguration();
+ std::vector<Common::ParamPackage> GetInputDevices() const;
+ InputCommon::ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) const;
+ InputCommon::AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) const;
+
/// Returns true if there is a device connected to port
bool DeviceConnected(std::size_t port) const;
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index 062ec66b5..8da829132 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -22,7 +22,7 @@ namespace InputCommon {
struct InputSubsystem::Impl {
void Initialize() {
- auto gcadapter = std::make_shared<GCAdapter::Adapter>();
+ gcadapter = std::make_shared<GCAdapter::Adapter>();
gcbuttons = std::make_shared<GCButtonFactory>(gcadapter);
Input::RegisterFactory<Input::ButtonDevice>("gcpad", gcbuttons);
gcanalog = std::make_shared<GCAnalogFactory>(gcadapter);
@@ -82,6 +82,8 @@ struct InputSubsystem::Impl {
#endif
auto udp_devices = udp->GetInputDevices();
devices.insert(devices.end(), udp_devices.begin(), udp_devices.end());
+ auto gcpad_devices = gcadapter->GetInputDevices();
+ devices.insert(devices.end(), gcpad_devices.begin(), gcpad_devices.end());
return devices;
}
@@ -94,6 +96,9 @@ struct InputSubsystem::Impl {
// TODO consider returning the SDL key codes for the default keybindings
return {};
}
+ if (params.Get("class", "") == "gcpad") {
+ return gcadapter->GetAnalogMappingForDevice(params);
+ }
#ifdef HAVE_SDL2
if (params.Get("class", "") == "sdl") {
return sdl->GetAnalogMappingForDevice(params);
@@ -111,6 +116,9 @@ struct InputSubsystem::Impl {
// TODO consider returning the SDL key codes for the default keybindings
return {};
}
+ if (params.Get("class", "") == "gcpad") {
+ return gcadapter->GetButtonMappingForDevice(params);
+ }
#ifdef HAVE_SDL2
if (params.Get("class", "") == "sdl") {
return sdl->GetButtonMappingForDevice(params);
@@ -141,6 +149,7 @@ struct InputSubsystem::Impl {
std::shared_ptr<UDPMotionFactory> udpmotion;
std::shared_ptr<UDPTouchFactory> udptouch;
std::shared_ptr<CemuhookUDP::Client> udp;
+ std::shared_ptr<GCAdapter::Adapter> gcadapter;
};
InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {}