Add "Press A (right) button" command to input automap that will map in nintendo layout if the user has a nintendo layout / prefers to match letters rather than position.

This commit is contained in:
David Griswold 2026-04-01 16:31:21 +03:00
parent 7d55d3a642
commit 30db1a71fd
6 changed files with 55 additions and 9 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -15,6 +15,7 @@
<file alias="48x48/sd_card.png">icons/48x48/sd_card.png</file>
<file alias="128x128/cartridge.png">icons/128x128/cartridge.png</file>
<file alias="256x256/azahar.png">icons/256x256/azahar.png</file>
<file alias="256x256/automap_face_buttons.png">icons/256x256/automap_face_buttons.png</file>
<file alias="48x48/star.png">icons/48x48/star.png</file>
<file alias="256x256/plus_folder.png">icons/256x256/plus_folder.png</file>
</qresource>

View File

@ -531,9 +531,15 @@ void ConfigureInput::MapFromButton(const Common::ParamPackage& params) {
void ConfigureInput::AutoMap() {
ui->buttonAutoMap->setEnabled(false);
if (QMessageBox::information(this, tr("Information"),
tr("After pressing OK, press any button on your joystick"),
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) {
QMessageBox box(this);
box.setWindowTitle(tr("Auto map Controller"));
box.setText(tr("After pressing OK, press the A (right) button on your gamepad"));
box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
QPixmap pixmap(QStringLiteral(":/icons/default/256x256/automap_face_buttons.png"));
pixmap = pixmap.scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation);
box.setIconPixmap(pixmap);
int result = box.exec();
if (result == QMessageBox::Cancel) {
ui->buttonAutoMap->setEnabled(true);
return;
}

View File

@ -202,8 +202,8 @@ Common::ParamPackage GetControllerButtonBinds(const Common::ParamPackage& params
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())->GetSDLControllerButtonBind(
params.Get("guid", "0"), params.Get("port", 0), native_button);
return dynamic_cast<SDL::SDLState*>(sdl.get())->GetSDLControllerButtonBind(params,
native_button);
}
#ifdef ENABLE_GCADAPTER
if (engine == "gcpad") {

View File

@ -169,6 +169,27 @@ constexpr std::array<SDL_GameControllerButton, Settings::NativeButton::NumButton
SDL_CONTROLLER_BUTTON_GUIDE,
SDL_CONTROLLER_BUTTON_INVALID,
}};
constexpr std::array<SDL_GameControllerButton, Settings::NativeButton::NumButtons>
nintendo_to_3ds_mapping = {{
SDL_CONTROLLER_BUTTON_A,
SDL_CONTROLLER_BUTTON_B,
SDL_CONTROLLER_BUTTON_X,
SDL_CONTROLLER_BUTTON_Y,
SDL_CONTROLLER_BUTTON_DPAD_UP,
SDL_CONTROLLER_BUTTON_DPAD_DOWN,
SDL_CONTROLLER_BUTTON_DPAD_LEFT,
SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
SDL_CONTROLLER_BUTTON_START,
SDL_CONTROLLER_BUTTON_BACK,
SDL_CONTROLLER_BUTTON_INVALID,
SDL_CONTROLLER_BUTTON_INVALID,
SDL_CONTROLLER_BUTTON_INVALID,
SDL_CONTROLLER_BUTTON_INVALID,
SDL_CONTROLLER_BUTTON_GUIDE,
SDL_CONTROLLER_BUTTON_INVALID,
}};
const std::map<Uint8, std::string> axis_names = {
{SDL_CONTROLLER_AXIS_LEFTX, "Left Stick X"},
@ -249,13 +270,31 @@ std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickBySDLID(SDL_JoystickID sdl_
return nullptr;
}
Common::ParamPackage SDLState::GetSDLControllerButtonBind(const std::string& guid, int port,
Settings::NativeButton::Values button) {
/**
* Return the button binds param package for the button assuming the params passed in is for the
* n3ds "A" button to determine whether this is xbox or nintendo layout. If the passed in button
* is neither A nor B, default to xbox layout as the most common on desktop.
*/
Common::ParamPackage SDLState::GetSDLControllerButtonBind(
const Common::ParamPackage a_button_params, Settings::NativeButton::Values button) {
auto guid = a_button_params.Get("guid", 0);
auto port = a_button_params.Get("port", 0);
auto a_button = a_button_params.Get("button", -1);
auto api = a_button_params.Get("api", "joystick");
// for xinputs, the "A" or right button would normally register as the B button. But if the
// user is either using a nintendo-layout controller or using xinput but would rather the labels
// match than the icons, they can press the button that appears as "A" and trigger nintendo
// automap
bool is_nintendo_layout =
api == "controller" && a_button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A;
Common::ParamPackage params({{"engine", "sdl"}});
params.Set("guid", guid);
params.Set("port", port);
auto mapped_button = xinput_to_3ds_mapping[static_cast<int>(button)];
auto mapped_button = is_nintendo_layout ? nintendo_to_3ds_mapping[static_cast<int>(button)]
: xinput_to_3ds_mapping[static_cast<int>(button)];
params.Set("api", "controller");
if (button == Settings::NativeButton::Values::ZL) {
params.Set("axis", SDL_CONTROLLER_AXIS_TRIGGERLEFT);

View File

@ -36,7 +36,7 @@ public:
const std::string& guid);
std::shared_ptr<SDLJoystick> GetSDLJoystickBySDLID(SDL_JoystickID sdl_id);
Common::ParamPackage GetSDLControllerButtonBind(const std::string& guid, int port,
Common::ParamPackage GetSDLControllerButtonBind(const Common::ParamPackage a_button_params,
Settings::NativeButton::Values button);
Common::ParamPackage GetSDLControllerAnalogBindByGUID(const std::string& guid, int port,
Settings::NativeAnalog::Values analog);