From ce53c412050c39c161a2ce2f6e18bdf6a9554a27 Mon Sep 17 00:00:00 2001 From: fireph <443370+fireph@users.noreply.github.com> Date: Mon, 7 Oct 2024 23:15:30 -0700 Subject: [PATCH] Add support to click touchpad using back button on non PS4/5 controllers (#1258) * Working touchpad support Tested on PS5 controller plugged in via USB. * fix lint * Add support to click touchpad using back button on other controllers Takes the back button and allows the user to change the behavior of how it clicks the touchpad. The current options are left, right, center, and none. * add description text * make more generic so translations can be supported in combobox * fix lint * linter again * support back button to touchpad for spacebar as well * linter at it again --- README.md | 2 +- src/common/config.cpp | 12 ++++++++ src/common/config.h | 2 ++ src/qt_gui/settings_dialog.cpp | 24 ++++++++++++++++ src/qt_gui/settings_dialog.ui | 52 +++++++++++++++++++++++++--------- src/qt_gui/translations/en.ts | 35 +++++++++++++++++++++++ src/sdl_window.cpp | 26 +++++++++++++++-- 7 files changed, 136 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index da01833e5..95428dfd0 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ PAD DOWN | DOWN | PAD LEFT | LEFT | PAD RIGHT | RIGHT | OPTIONS | RETURN | -TOUCH PAD | SPACE | +BACK BUTTON / TOUCH PAD | SPACE | L1 | Q | R1 | U | L2 | E | diff --git a/src/common/config.cpp b/src/common/config.cpp index 8ac3c694b..8c1c4f79d 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -41,6 +41,7 @@ static std::string logFilter; static std::string logType = "async"; static std::string userName = "shadPS4"; static std::string updateChannel; +static std::string backButtonBehavior = "left"; static bool useSpecialPad = false; static int specialPadClass = 1; static bool isDebugDump = false; @@ -123,6 +124,10 @@ std::string getUpdateChannel() { return updateChannel; } +std::string getBackButtonBehavior() { + return backButtonBehavior; +} + bool getUseSpecialPad() { return useSpecialPad; } @@ -275,6 +280,10 @@ void setUpdateChannel(const std::string& type) { updateChannel = type; } +void setBackButtonBehavior(const std::string& type) { + backButtonBehavior = type; +} + void setUseSpecialPad(bool use) { useSpecialPad = use; } @@ -435,6 +444,7 @@ void load(const std::filesystem::path& path) { } isShowSplash = toml::find_or(general, "showSplash", true); isAutoUpdate = toml::find_or(general, "autoUpdate", false); + backButtonBehavior = toml::find_or(general, "backButtonBehavior", "left"); } if (data.contains("Input")) { @@ -533,6 +543,7 @@ void save(const std::filesystem::path& path) { data["General"]["updateChannel"] = updateChannel; data["General"]["showSplash"] = isShowSplash; data["General"]["autoUpdate"] = isAutoUpdate; + data["General"]["backButtonBehavior"] = backButtonBehavior; data["Input"]["useSpecialPad"] = useSpecialPad; data["Input"]["specialPadClass"] = specialPadClass; data["GPU"]["screenWidth"] = screenWidth; @@ -591,6 +602,7 @@ void setDefaultValues() { } else { updateChannel = "Nightly"; } + backButtonBehavior = "left"; useSpecialPad = false; specialPadClass = 1; isDebugDump = false; diff --git a/src/common/config.h b/src/common/config.h index daee9e078..4aad7bede 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -20,6 +20,7 @@ std::string getLogFilter(); std::string getLogType(); std::string getUserName(); std::string getUpdateChannel(); +std::string getBackButtonBehavior(); bool getUseSpecialPad(); int getSpecialPadClass(); @@ -54,6 +55,7 @@ void setLanguage(u32 language); void setNeoMode(bool enable); void setUserName(const std::string& type); void setUpdateChannel(const std::string& type); +void setBackButtonBehavior(const std::string& type); void setUseSpecialPad(bool use); void setSpecialPadClass(int type); diff --git a/src/qt_gui/settings_dialog.cpp b/src/qt_gui/settings_dialog.cpp index 1c0b0bc07..bcf5762f2 100644 --- a/src/qt_gui/settings_dialog.cpp +++ b/src/qt_gui/settings_dialog.cpp @@ -98,6 +98,15 @@ SettingsDialog::SettingsDialog(std::span physical_devices, QWidge ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->setText(tr("Restore Defaults")); ui->buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close")); + ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Left"), "left"); + ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Center"), "center"); + ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Right"), "right"); + ui->backButtonBehaviorComboBox->addItem(tr("None"), "none"); + + QString currentBackButtonBehavior = QString::fromStdString(Config::getBackButtonBehavior()); + int index = ui->backButtonBehaviorComboBox->findData(currentBackButtonBehavior); + ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0); + connect(ui->tabWidgetSettings, &QTabWidget::currentChanged, this, [this]() { ui->buttonBox->button(QDialogButtonBox::Close)->setFocus(); }); @@ -151,6 +160,14 @@ SettingsDialog::SettingsDialog(std::span physical_devices, QWidge Config::setBGMvolume(val); BackgroundMusicPlayer::getInstance().setVolume(val); }); + + connect(ui->backButtonBehaviorComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, [this](int index) { + if (index >= 0 && index < ui->backButtonBehaviorComboBox->count()) { + QString data = ui->backButtonBehaviorComboBox->itemData(index).toString(); + Config::setBackButtonBehavior(data.toStdString()); + } + }); } // GPU TAB @@ -204,6 +221,7 @@ SettingsDialog::SettingsDialog(std::span physical_devices, QWidge ui->logFilter->installEventFilter(this); ui->updaterGroupBox->installEventFilter(this); ui->GUIgroupBox->installEventFilter(this); + ui->backButtonBehaviorGroupBox->installEventFilter(this); // Graphics ui->graphicsAdapterGroupBox->installEventFilter(this); @@ -258,6 +276,10 @@ void SettingsDialog::LoadValuesFromConfig() { } } ui->updateComboBox->setCurrentText(QString::fromStdString(updateChannel)); + + QString backButtonBehavior = QString::fromStdString(Config::getBackButtonBehavior()); + int index = ui->backButtonBehaviorComboBox->findData(backButtonBehavior); + ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0); } void SettingsDialog::InitializeEmulatorLanguages() { @@ -319,6 +341,8 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) { text = tr("updaterGroupBox"); } else if (elementName == "GUIgroupBox") { text = tr("GUIgroupBox"); + } else if (elementName == "backButtonBehaviorGroupBox") { + text = tr("backButtonBehaviorGroupBox"); } // Graphics diff --git a/src/qt_gui/settings_dialog.ui b/src/qt_gui/settings_dialog.ui index 4edec9e1b..a6264af6f 100644 --- a/src/qt_gui/settings_dialog.ui +++ b/src/qt_gui/settings_dialog.ui @@ -442,20 +442,44 @@ - - - Qt::Orientation::Horizontal - - - QSizePolicy::Policy::Expanding - - - - 0 - 0 - - - + + + + + + 0 + 0 + + + + Controller Settings + + + + + 12 + 30 + 241 + 65 + + + + Back Button Behavior + + + + + 12 + 30 + 217 + 28 + + + + + + + diff --git a/src/qt_gui/translations/en.ts b/src/qt_gui/translations/en.ts index 4052b4ef5..18c54428f 100644 --- a/src/qt_gui/translations/en.ts +++ b/src/qt_gui/translations/en.ts @@ -534,6 +534,16 @@ Volume Volume + + + Controller Settings + Controller Settings + + + + Back Button Behavior + Back Button Behavior + MainWindow @@ -1023,6 +1033,31 @@ GUIgroupBox Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI. + + + backButtonBehaviorGroupBox + Back Button Behavior:\nAllows setting which part of the touchpad the back button will emulate a touch on. + + + + Touchpad Left + Touchpad Left + + + + Touchpad Right + Touchpad Right + + + + Touchpad Center + Touchpad Center + + + + None + None + graphicsAdapterGroupBox diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index 4a4020a42..470f12de3 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -145,6 +145,7 @@ void WindowSDL::onKeyPress(const SDL_Event* event) { Input::Axis axis = Input::Axis::AxisMax; int axisvalue = 0; int ax = 0; + std::string backButtonBehavior = Config::getBackButtonBehavior(); switch (event->key.key) { case SDLK_UP: button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_UP; @@ -278,7 +279,15 @@ void WindowSDL::onKeyPress(const SDL_Event* event) { ax = Input::GetAxis(0, 0x80, axisvalue); break; case SDLK_SPACE: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TOUCH_PAD; + if (backButtonBehavior != "none") { + float x = backButtonBehavior == "left" ? 0.25f + : (backButtonBehavior == "right" ? 0.75f : 0.5f); + // trigger a touchpad event so that the touchpad emulation for back button works + controller->SetTouchpadState(0, true, x, 0.5f); + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TOUCH_PAD; + } else { + button = 0; + } break; case SDLK_F11: if (event->type == SDL_EVENT_KEY_DOWN) { @@ -330,7 +339,20 @@ void WindowSDL::onGamepadEvent(const SDL_Event* event) { case SDL_EVENT_GAMEPAD_BUTTON_UP: button = sdlGamepadToOrbisButton(event->gbutton.button); if (button != 0) { - controller->CheckButton(0, button, event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN); + if (event->gbutton.button == SDL_GAMEPAD_BUTTON_BACK) { + std::string backButtonBehavior = Config::getBackButtonBehavior(); + if (backButtonBehavior != "none") { + float x = backButtonBehavior == "left" + ? 0.25f + : (backButtonBehavior == "right" ? 0.75f : 0.5f); + // trigger a touchpad event so that the touchpad emulation for back button works + controller->SetTouchpadState(0, true, x, 0.5f); + controller->CheckButton(0, button, + event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN); + } + } else { + controller->CheckButton(0, button, event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN); + } } if (SDL_GetCursor() != NULL) { SDL_HideCursor();