diff --git a/src/frontend/qt_sdl/Config.cpp b/src/frontend/qt_sdl/Config.cpp index 86516a91..86d59d0d 100644 --- a/src/frontend/qt_sdl/Config.cpp +++ b/src/frontend/qt_sdl/Config.cpp @@ -103,6 +103,7 @@ DefaultList DefaultBools = {"Emu.DirectBoot", true}, {"Instance*.DS.Battery.LevelOkay", true}, {"Instance*.DSi.Battery.Charging", true}, + {"Instance*.Joystick.AutoMap", true}, #ifdef JIT_ENABLED {"JIT.BranchOptimisations", true}, {"JIT.LiteralOptimisations", true}, diff --git a/src/frontend/qt_sdl/EmuInstance.h b/src/frontend/qt_sdl/EmuInstance.h index b77ee917..d2ac3087 100755 --- a/src/frontend/qt_sdl/EmuInstance.h +++ b/src/frontend/qt_sdl/EmuInstance.h @@ -155,6 +155,7 @@ public: void setJoystick(int id); int getJoystickID() { return joystickID; } SDL_Joystick* getJoystick() { return joystick; } + bool autoJoystickMapping; void touchScreen(int x, int y); void releaseScreen(); diff --git a/src/frontend/qt_sdl/EmuInstanceInput.cpp b/src/frontend/qt_sdl/EmuInstanceInput.cpp index ef4637ea..29939ab8 100644 --- a/src/frontend/qt_sdl/EmuInstanceInput.cpp +++ b/src/frontend/qt_sdl/EmuInstanceInput.cpp @@ -43,6 +43,24 @@ const char* EmuInstance::buttonNames[12] = "Y" }; +SDL_GameControllerButton sdlButtons[12] = +{ + // SDL uses A/B for south/east, X/Y for west/north, opposite of the DS + // so we swap the buttons so they map to where they are on the DS positionally + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_X +}; + const char* EmuInstance::hotkeyNames[HK_MAX] = { "HK_Lid", @@ -116,6 +134,8 @@ void EmuInstance::inputLoadConfig() hkJoyMapping[i] = joycfg.GetInt(hotkeyNames[i]); } + autoJoystickMapping = joycfg.GetBool("AutoMap"); + setJoystick(localCfg.GetInt("JoystickID")); } @@ -397,7 +417,14 @@ void EmuInstance::inputProcess() } joyInputMask = 0xFFF; - if (joystick) + + if (autoJoystickMapping && controller != nullptr) + { + for (int i = 0; i < 12; i++) + if (SDL_GameControllerGetButton(controller, sdlButtons[i])) + joyInputMask &= ~(1 << i); + } + else if (joystick) { for (int i = 0; i < 12; i++) if (joystickButtonDown(joyMapping[i])) diff --git a/src/frontend/qt_sdl/InputConfig/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfig/InputConfigDialog.cpp index ade03f32..e5dda338 100644 --- a/src/frontend/qt_sdl/InputConfig/InputConfigDialog.cpp +++ b/src/frontend/qt_sdl/InputConfig/InputConfigDialog.cpp @@ -94,6 +94,8 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new ui->cbxJoystick->setEnabled(false); } + ui->cbAutoMap->setChecked(joycfg.GetBool("AutoMap")); + setupKeypadPage(); int inst = emuInstance->getInstanceID(); @@ -124,7 +126,7 @@ void InputConfigDialog::setupKeypadPage() delete pushButtonKey; delete pushButtonJoy; - if (ui->cbxJoystick->isEnabled()) + if (ui->cbxJoystick->isEnabled() && !ui->cbAutoMap->isChecked()) { ui->stackMapping->setCurrentIndex(1); } @@ -214,6 +216,7 @@ void InputConfigDialog::on_InputConfigDialog_accepted() } instcfg.SetInt("JoystickID", joystickID); + joycfg.SetBool("AutoMap", ui->cbAutoMap->isChecked()); Config::Save(); emuInstance->inputLoadConfig(); @@ -246,6 +249,25 @@ void InputConfigDialog::on_cbxJoystick_currentIndexChanged(int id) joystickID = id; emuInstance->setJoystick(id); + setJoyMappingEnabled(ui->cbAutoMap->isChecked()); +} + +void InputConfigDialog::on_cbAutoMap_checkStateChanged(Qt::CheckState state) +{ + setJoyMappingEnabled(state); +} + +void InputConfigDialog::setJoyMappingEnabled(bool enable) +{ + if (enable && SDL_IsGameController(emuInstance->getJoystickID())) + { + ui->stackMapping->setCurrentIndex(0); + ui->btnJoyMapSwitch->setEnabled(false); + } + else + { + ui->btnJoyMapSwitch->setEnabled(true); + } } SDL_Joystick* InputConfigDialog::getJoystick() diff --git a/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h b/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h index 47857f94..9f7a8f9e 100644 --- a/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h +++ b/src/frontend/qt_sdl/InputConfig/InputConfigDialog.h @@ -131,6 +131,7 @@ private slots: void on_btnKeyMapSwitch_clicked(); void on_btnJoyMapSwitch_clicked(); void on_cbxJoystick_currentIndexChanged(int id); + void on_cbAutoMap_checkStateChanged(Qt::CheckState state); private: void populatePage(QWidget* page, @@ -138,6 +139,8 @@ private: int* keymap, int* joymap); void setupKeypadPage(); + void setJoyMappingEnabled(bool enabled); + Ui::InputConfigDialog* ui; EmuInstance* emuInstance; diff --git a/src/frontend/qt_sdl/InputConfig/InputConfigDialog.ui b/src/frontend/qt_sdl/InputConfig/InputConfigDialog.ui index 61d7e454..7619e77a 100644 --- a/src/frontend/qt_sdl/InputConfig/InputConfigDialog.ui +++ b/src/frontend/qt_sdl/InputConfig/InputConfigDialog.ui @@ -2280,7 +2280,7 @@ - + 0 @@ -2293,7 +2293,20 @@ 0 - + + + + + 0 + 0 + + + + <html><head/><body><p>Selects which joystick will be used for joystick input, if any is present.</p></body></html> + + + + @@ -2306,16 +2319,13 @@ - - - - - 0 - 0 - + + + + <html><head/><body><p>Automatically map joystick buttons to their closest equivalents on the DS for controllers that are known to SDL's game controller database.</p><p>The joystick mappings page will be disabled when automatic mapping is in effect.</p></body></html> - - <html><head/><body><p>Selects which joystick will be used for joystick input, if any is present.</p></body></html> + + Automatically map joystick buttons diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 65142663..55afe601 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -298,6 +298,9 @@ int main(int argc, char** argv) // http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); + // Use position-based button mapping instead of label-based + // Needed to make auto mapping map the face buttons correctly regardless of layout + SDL_SetHint(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0"); SDL_SetHint(SDL_HINT_APP_NAME, "melonDS");