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
This commit is contained in:
fireph 2024-10-07 23:15:30 -07:00 committed by GitHub
parent 7389cf3e89
commit ce53c41205
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 136 additions and 17 deletions

View file

@ -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 |

View file

@ -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<bool>(general, "showSplash", true);
isAutoUpdate = toml::find_or<bool>(general, "autoUpdate", false);
backButtonBehavior = toml::find_or<std::string>(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;

View file

@ -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);

View file

@ -98,6 +98,15 @@ SettingsDialog::SettingsDialog(std::span<const QString> 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<const QString> physical_devices, QWidge
Config::setBGMvolume(val);
BackgroundMusicPlayer::getInstance().setVolume(val);
});
connect(ui->backButtonBehaviorComboBox, QOverload<int>::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<const QString> 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

View file

@ -442,20 +442,44 @@
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
<layout class="QVBoxLayout" name="ControllerTabLayoutRight" stretch="1">
<item>
<widget class="QGroupBox" name="ControllerGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Controller Settings</string>
</property>
<widget class="QGroupBox" name="backButtonBehaviorGroupBox">
<property name="geometry">
<rect>
<x>12</x>
<y>30</y>
<width>241</width>
<height>65</height>
</rect>
</property>
<property name="title">
<string>Back Button Behavior</string>
</property>
<widget class="QComboBox" name="backButtonBehaviorComboBox">
<property name="geometry">
<rect>
<x>12</x>
<y>30</y>
<width>217</width>
<height>28</height>
</rect>
</property>
</widget>
</widget>
</widget>
</item>
</layout>
</item>
</layout>
</item>

View file

@ -534,6 +534,16 @@
<source>Volume</source>
<translation>Volume</translation>
</message>
<message>
<location filename="../settings_dialog.ui" line="455"/>
<source>Controller Settings</source>
<translation>Controller Settings</translation>
</message>
<message>
<location filename="../settings_dialog.ui" line="467"/>
<source>Back Button Behavior</source>
<translation>Back Button Behavior</translation>
</message>
</context>
<context>
<name>MainWindow</name>
@ -1023,6 +1033,31 @@
<source>GUIgroupBox</source>
<translation>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp" line="330"/>
<source>backButtonBehaviorGroupBox</source>
<translation>Back Button Behavior:\nAllows setting which part of the touchpad the back button will emulate a touch on.</translation>
</message>
<message>
<location filename="../settings_dialog.cpp" line="101"/>
<source>Touchpad Left</source>
<translation>Touchpad Left</translation>
</message>
<message>
<location filename="../settings_dialog.cpp" line="102"/>
<source>Touchpad Right</source>
<translation>Touchpad Right</translation>
</message>
<message>
<location filename="../settings_dialog.cpp" line="103"/>
<source>Touchpad Center</source>
<translation>Touchpad Center</translation>
</message>
<message>
<location filename="../settings_dialog.cpp" line="104"/>
<source>None</source>
<translation>None</translation>
</message>
<message>
<location filename="../settings_dialog.cpp" line="312"/>
<source>graphicsAdapterGroupBox</source>

View file

@ -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();