citra-emu
/
citra
Archived
1
0
Fork 0

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

2
externals/catch vendored

@ -1 +1 @@
Subproject commit de6fe184a9ac1a06895cdd1c9b437f0a0bdf14ad Subproject commit 15cf3caaceb21172ea42a24e595a2eb58c3ec960

2
externals/dynarmic vendored

@ -1 +1 @@
Subproject commit 358cf6f0357baae3e3bb5788431acf1068f897b5 Subproject commit f9d84871fb6dd41c47945d649dc9017aa3762125

View File

@ -274,7 +274,8 @@ ConfigureInput::ConfigureInput(QWidget* parent)
}); });
connect(analog_map_deadzone_and_modifier_slider[analog_id], &QSlider::valueChanged, [=] { connect(analog_map_deadzone_and_modifier_slider[analog_id], &QSlider::valueChanged, [=] {
const int slider_value = analog_map_deadzone_and_modifier_slider[analog_id]->value(); const int slider_value = analog_map_deadzone_and_modifier_slider[analog_id]->value();
if (analogs_param[analog_id].Get("engine", "") == "sdl") { const auto engine = analogs_param[analog_id].Get("engine", "");
if (engine == "sdl" || engine == "gcpad") {
analog_map_deadzone_and_modifier_slider_label[analog_id]->setText( analog_map_deadzone_and_modifier_slider_label[analog_id]->setText(
tr("Deadzone: %1%").arg(slider_value)); tr("Deadzone: %1%").arg(slider_value));
analogs_param[analog_id].Set("deadzone", slider_value / 100.0f); analogs_param[analog_id].Set("deadzone", slider_value / 100.0f);
@ -461,16 +462,14 @@ void ConfigureInput::MapFromButton(const Common::ParamPackage& params) {
Common::ParamPackage aux_param; Common::ParamPackage aux_param;
bool mapped = false; bool mapped = false;
for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) { for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) {
aux_param = InputCommon::GetSDLControllerButtonBindByGUID(params.Get("guid", "0"), aux_param = InputCommon::GetControllerButtonBinds(params, button_id);
params.Get("port", 0), button_id);
if (aux_param.Has("engine")) { if (aux_param.Has("engine")) {
buttons_param[button_id] = aux_param; buttons_param[button_id] = aux_param;
mapped = true; mapped = true;
} }
} }
for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) { for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) {
aux_param = InputCommon::GetSDLControllerAnalogBindByGUID(params.Get("guid", "0"), aux_param = InputCommon::GetControllerAnalogBinds(params, analog_id);
params.Get("port", 0), analog_id);
if (aux_param.Has("engine")) { if (aux_param.Has("engine")) {
analogs_param[analog_id] = aux_param; analogs_param[analog_id] = aux_param;
mapped = true; mapped = true;

View File

@ -12,7 +12,27 @@
#include "input_common/gcadapter/gc_poller.h" #include "input_common/gcadapter/gc_poller.h"
namespace InputCommon { 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 { class GCButton final : public Input::ButtonDevice {
public: public:
explicit GCButton(int port_, int button_, GCAdapter::Adapter* adapter) explicit GCButton(int port_, int button_, GCAdapter::Adapter* adapter)
@ -126,6 +146,17 @@ Common::ParamPackage GCButtonFactory::GetNextInput() {
return params; 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() { void GCButtonFactory::Start() {
polling = true; polling = true;
adapter->BeginConfiguration(); adapter->BeginConfiguration();
@ -269,4 +300,24 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() {
return params; 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 } // namespace InputCommon

View File

@ -6,6 +6,7 @@
#include <memory> #include <memory>
#include "core/frontend/input.h" #include "core/frontend/input.h"
#include "core/settings.h"
#include "input_common/gcadapter/gc_adapter.h" #include "input_common/gcadapter/gc_adapter.h"
#include "input_common/main.h" #include "input_common/main.h"
@ -24,6 +25,7 @@ public:
std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override; std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override;
Common::ParamPackage GetNextInput() override; Common::ParamPackage GetNextInput() override;
Common::ParamPackage GetGcTo3DSMappedButton(int port, Settings::NativeButton::Values button);
/// For device input configuration/polling /// For device input configuration/polling
void Start() override; void Start() override;
@ -47,6 +49,7 @@ public:
std::unique_ptr<Input::AnalogDevice> Create(const Common::ParamPackage& params) override; std::unique_ptr<Input::AnalogDevice> Create(const Common::ParamPackage& params) override;
Common::ParamPackage GetNextInput() override; Common::ParamPackage GetNextInput() override;
Common::ParamPackage GetGcTo3DSMappedAnalog(int port, Settings::NativeAnalog::Values analog);
/// For device input configuration/polling /// For device input configuration/polling
void Start() override; 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(); return circle_pad_param.Serialize();
} }
Common::ParamPackage GetSDLControllerButtonBindByGUID(const std::string& guid, int port, Common::ParamPackage GetControllerButtonBinds(const Common::ParamPackage& params, int button) {
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( return dynamic_cast<SDL::SDLState*>(sdl.get())->GetSDLControllerButtonBindByGUID(
guid, port, static_cast<Settings::NativeButton::Values>(button)); 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, Common::ParamPackage GetControllerAnalogBinds(const Common::ParamPackage& params, int analog) {
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( return dynamic_cast<SDL::SDLState*>(sdl.get())->GetSDLControllerAnalogBindByGUID(
guid, port, static_cast<Settings::NativeAnalog::Values>(analog)); 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() { 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, std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right,
int key_modifier, float modifier_scale); int key_modifier, float modifier_scale);
Common::ParamPackage GetSDLControllerButtonBindByGUID(const std::string& guid, int port, Common::ParamPackage GetControllerButtonBinds(const Common::ParamPackage& params, int button);
int button); Common::ParamPackage GetControllerAnalogBinds(const Common::ParamPackage& params, int analog);
Common::ParamPackage GetSDLControllerAnalogBindByGUID(const std::string& guid, int port,
int analog);
/// Reloads the input devices /// Reloads the input devices
void ReloadInputDevices(); void ReloadInputDevices();