gcadapter: Implement auto map feature

Implements the auto map functionality for the GC adapter.
The controls map nicely to the original 3ds controls, with the select button being mapped to the Z button on GC.
The ZL/ZR buttons are not mapped by this feature.
This commit is contained in:
ameerj 2021-03-12 14:32:30 -05:00
parent 161e6a541b
commit a80e566464
7 changed files with 85 additions and 20 deletions

View file

@ -12,7 +12,27 @@
#include "input_common/gcadapter/gc_poller.h"
namespace InputCommon {
namespace {
constexpr std::array<GCAdapter::PadButton, Settings::NativeButton::NumButtons> gc_to_3ds_mapping{{
GCAdapter::PadButton::ButtonA,
GCAdapter::PadButton::ButtonB,
GCAdapter::PadButton::ButtonX,
GCAdapter::PadButton::ButtonY,
GCAdapter::PadButton::ButtonUp,
GCAdapter::PadButton::ButtonDown,
GCAdapter::PadButton::ButtonLeft,
GCAdapter::PadButton::ButtonRight,
GCAdapter::PadButton::TriggerL,
GCAdapter::PadButton::TriggerR,
GCAdapter::PadButton::ButtonStart,
GCAdapter::PadButton::TriggerZ,
GCAdapter::PadButton::Undefined,
GCAdapter::PadButton::Undefined,
GCAdapter::PadButton::Undefined,
GCAdapter::PadButton::Undefined,
GCAdapter::PadButton::Undefined,
}};
}
class GCButton final : public Input::ButtonDevice {
public:
explicit GCButton(int port_, int button_, GCAdapter::Adapter* adapter)
@ -126,6 +146,17 @@ Common::ParamPackage GCButtonFactory::GetNextInput() {
return params;
}
Common::ParamPackage GCButtonFactory::GetGcTo3DSMappedButton(
int port, Settings::NativeButton::Values button) {
Common::ParamPackage params({{"engine", "gcpad"}});
params.Set("port", port);
auto mapped_button = gc_to_3ds_mapping[static_cast<int>(button)];
if (mapped_button != GCAdapter::PadButton::Undefined) {
params.Set("button", static_cast<u16>(mapped_button));
}
return params;
}
void GCButtonFactory::Start() {
polling = true;
adapter->BeginConfiguration();
@ -269,4 +300,24 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() {
return params;
}
Common::ParamPackage GCAnalogFactory::GetGcTo3DSMappedAnalog(
int port, Settings::NativeAnalog::Values analog) {
int x_axis, y_axis;
Common::ParamPackage params({{"engine", "gcpad"}});
params.Set("port", port);
if (analog == Settings::NativeAnalog::Values::CirclePad) {
x_axis = static_cast<s32>(GCAdapter::PadAxes::StickX);
y_axis = static_cast<s32>(GCAdapter::PadAxes::StickY);
} else if (analog == Settings::NativeAnalog::Values::CStick) {
x_axis = static_cast<s32>(GCAdapter::PadAxes::SubstickX);
y_axis = static_cast<s32>(GCAdapter::PadAxes::SubstickY);
} else {
LOG_WARNING(Input, "analog value out of range {}", analog);
return {{}};
}
params.Set("axis_x", x_axis);
params.Set("axis_y", y_axis);
return params;
}
} // namespace InputCommon

View file

@ -6,6 +6,7 @@
#include <memory>
#include "core/frontend/input.h"
#include "core/settings.h"
#include "input_common/gcadapter/gc_adapter.h"
#include "input_common/main.h"
@ -24,6 +25,7 @@ public:
std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override;
Common::ParamPackage GetNextInput() override;
Common::ParamPackage GetGcTo3DSMappedButton(int port, Settings::NativeButton::Values button);
/// For device input configuration/polling
void Start() override;
@ -47,6 +49,7 @@ public:
std::unique_ptr<Input::AnalogDevice> Create(const Common::ParamPackage& params) override;
Common::ParamPackage GetNextInput() override;
Common::ParamPackage GetGcTo3DSMappedAnalog(int port, Settings::NativeAnalog::Values analog);
/// For device input configuration/polling
void Start() override;

View file

@ -91,16 +91,30 @@ std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left,
return circle_pad_param.Serialize();
}
Common::ParamPackage GetSDLControllerButtonBindByGUID(const std::string& guid, int port,
int button) {
return dynamic_cast<SDL::SDLState*>(sdl.get())->GetSDLControllerButtonBindByGUID(
guid, port, static_cast<Settings::NativeButton::Values>(button));
Common::ParamPackage GetControllerButtonBinds(const Common::ParamPackage& params, int button) {
const auto native_button{static_cast<Settings::NativeButton::Values>(button)};
const auto engine{params.Get("engine", "")};
if (engine == "sdl") {
return dynamic_cast<SDL::SDLState*>(sdl.get())->GetSDLControllerButtonBindByGUID(
params.Get("guid", "0"), params.Get("port", 0), native_button);
}
if (engine == "gcpad") {
return gcbuttons->GetGcTo3DSMappedButton(params.Get("port", 0), native_button);
}
return {};
}
Common::ParamPackage GetSDLControllerAnalogBindByGUID(const std::string& guid, int port,
int analog) {
return dynamic_cast<SDL::SDLState*>(sdl.get())->GetSDLControllerAnalogBindByGUID(
guid, port, static_cast<Settings::NativeAnalog::Values>(analog));
Common::ParamPackage GetControllerAnalogBinds(const Common::ParamPackage& params, int analog) {
const auto native_analog{static_cast<Settings::NativeAnalog::Values>(analog)};
const auto engine{params.Get("engine", "")};
if (engine == "sdl") {
return dynamic_cast<SDL::SDLState*>(sdl.get())->GetSDLControllerAnalogBindByGUID(
params.Get("guid", "0"), params.Get("port", 0), native_analog);
}
if (engine == "gcpad") {
return gcanalog->GetGcTo3DSMappedAnalog(params.Get("port", 0), native_analog);
}
return {};
}
void ReloadInputDevices() {

View file

@ -37,10 +37,8 @@ std::string GenerateKeyboardParam(int key_code);
std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right,
int key_modifier, float modifier_scale);
Common::ParamPackage GetSDLControllerButtonBindByGUID(const std::string& guid, int port,
int button);
Common::ParamPackage GetSDLControllerAnalogBindByGUID(const std::string& guid, int port,
int analog);
Common::ParamPackage GetControllerButtonBinds(const Common::ParamPackage& params, int button);
Common::ParamPackage GetControllerAnalogBinds(const Common::ParamPackage& params, int analog);
/// Reloads the input devices
void ReloadInputDevices();