From dd61c2a0d1841101bb8cf67aed06149567e1925d Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Wed, 11 Sep 2024 12:56:27 +0300 Subject: [PATCH] Revert "Add UI to configure keyboard-to-controller mapping (#308)" This reverts commit fdb13a3b90236cd6c6e9c6e097b5e69f29efe04c. --- .ci/clang-format.sh | 19 +- .github/workflows/linux-qt.yml | 8 +- .reuse/dep5 | 1 - CMakeLists.txt | 4 - src/common/config.cpp | 45 +-- src/common/config.h | 5 - src/emulator.cpp | 2 +- src/emulator.h | 2 +- src/images/PS4_controller_scheme.png | Bin 30766 -> 0 bytes src/input/keys_constants.h | 30 -- src/qt_gui/keyboardcontrolswindow.cpp | 524 -------------------------- src/qt_gui/keyboardcontrolswindow.h | 40 -- src/qt_gui/keyboardcontrolswindow.ui | 439 --------------------- src/qt_gui/main_window.cpp | 12 - src/qt_gui/main_window.h | 5 - src/sdl_window.cpp | 443 ++++++++-------------- src/sdl_window.h | 29 +- src/shadps4.qrc | 1 - 18 files changed, 173 insertions(+), 1436 deletions(-) delete mode 100644 src/images/PS4_controller_scheme.png delete mode 100644 src/input/keys_constants.h delete mode 100644 src/qt_gui/keyboardcontrolswindow.cpp delete mode 100644 src/qt_gui/keyboardcontrolswindow.h delete mode 100644 src/qt_gui/keyboardcontrolswindow.ui diff --git a/.ci/clang-format.sh b/.ci/clang-format.sh index b9018f508..0ccd4062d 100755 --- a/.ci/clang-format.sh +++ b/.ci/clang-format.sh @@ -3,11 +3,6 @@ # SPDX-FileCopyrightText: 2023 Citra Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later -fix=false -if [ "$1" == "--fix" ]; then - fix=true -fi - if grep -nrI '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .ci* dist/*.desktop \ dist/*.svg dist/*.xml; then echo Trailing whitespace found, aborting @@ -30,15 +25,11 @@ fi set +x for f in $files_to_lint; do - if [ "$fix" = true ]; then - $CLANG_FORMAT -i "$f" - else - d=$(diff -u "$f" <($CLANG_FORMAT "$f") || true) - if ! [ -z "$d" ]; then - echo "!!! $f not compliant to coding style, here is the fix:" - echo "$d" - fail=1 - fi + d=$(diff -u "$f" <($CLANG_FORMAT "$f") || true) + if ! [ -z "$d" ]; then + echo "!!! $f not compliant to coding style, here is the fix:" + echo "$d" + fail=1 fi done diff --git a/.github/workflows/linux-qt.yml b/.github/workflows/linux-qt.yml index 466554ca6..6848f203b 100644 --- a/.github/workflows/linux-qt.yml +++ b/.github/workflows/linux-qt.yml @@ -23,13 +23,7 @@ jobs: - name: Install misc packages run: > - sudo apt-get update && sudo apt install libx11-dev libxext-dev libwayland-dev libfuse2 clang build-essential - - - name: Setup Qt - uses: jurplel/install-qt-action@v4 - with: - arch: linux_gcc_64 - version: 6.7.1 + sudo apt-get update && sudo apt install libx11-dev libxext-dev libwayland-dev libfuse2 clang build-essential qt6-base-dev qt6-tools-dev - name: Cache CMake dependency source code uses: actions/cache@v4 diff --git a/.reuse/dep5 b/.reuse/dep5 index 88c3e9969..0140c0c02 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -15,7 +15,6 @@ Files: CMakeSettings.json documents/Screenshots/Undertale.png documents/Screenshots/We are DOOMED.png scripts/ps4_names.txt - src/images/PS4_controller_scheme.png src/images/about_icon.png src/images/controller_icon.png src/images/exit_icon.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 20e2143b5..9101af9df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -607,7 +607,6 @@ set(IMGUI src/imgui/imgui_config.h set(INPUT src/input/controller.cpp src/input/controller.h - src/input/keys_constants.h ) set(EMULATOR src/emulator.cpp @@ -652,9 +651,6 @@ set(QT_GUI src/qt_gui/about_dialog.cpp src/qt_gui/settings_dialog.cpp src/qt_gui/settings_dialog.h src/qt_gui/settings_dialog.ui - src/qt_gui/keyboardcontrolswindow.h - src/qt_gui/keyboardcontrolswindow.cpp - src/qt_gui/keyboardcontrolswindow.ui src/qt_gui/main.cpp ${EMULATOR} ${RESOURCE_FILES} diff --git a/src/common/config.cpp b/src/common/config.cpp index 1063dfca9..fb6ee120a 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -53,7 +53,6 @@ std::vector m_recent_files; std::string emulator_language = "en"; // Settings u32 m_language = 1; // english -std::map m_keyboard_binding_map; bool isNeoMode() { return isNeo; @@ -284,12 +283,7 @@ void setRecentFiles(const std::vector& recentFiles) { void setEmulatorLanguage(std::string language) { emulator_language = language; } -void setKeyboardBindingMap(std::map map) { - m_keyboard_binding_map = map; -} -const std::map& getKeyboardBindingMap() { - return m_keyboard_binding_map; -} + u32 getMainWindowGeometryX() { return main_window_geometry_x; } @@ -437,34 +431,6 @@ void load(const std::filesystem::path& path) { m_language = toml::find_or(settings, "consoleLanguage", 1); } - - if (data.contains("Controls")) { - auto controls = toml::find(data, "Controls"); - - toml::table keyboardBindings{}; - auto it = controls.find("keyboardBindings"); - if (it != controls.end() && it->second.is_table()) { - keyboardBindings = it->second.as_table(); - } - - // Convert TOML table to std::map - for (const auto& [key, value] : keyboardBindings) { - try { - Uint32 int_key = static_cast(std::stoll(key)); - if (value.is_integer()) { - // Convert the TOML integer value to KeysMapping (int) - int int_value = value.as_integer(); - - // Add to the map - m_keyboard_binding_map[int_key] = static_cast(int_value); - } else { - fmt::print("Unexpected type for value: expected integer, got other type\n"); - } - } catch (const std::exception& e) { - fmt::print("Error processing key-value pair: {}\n", e.what()); - } - } - } } void save(const std::filesystem::path& path) { toml::value data; @@ -526,15 +492,6 @@ void save(const std::filesystem::path& path) { data["GUI"]["recentFiles"] = m_recent_files; data["GUI"]["emulatorLanguage"] = emulator_language; - // Create a TOML table with keyboard bindings - toml::table keyboardBindingsTable; - // Serialize the map to the TOML table - for (const auto& [key, value] : m_keyboard_binding_map) { - keyboardBindingsTable[std::to_string(key)] = static_cast(value); - } - - data["Controls"]["keyboardBindings"] = keyboardBindingsTable; - data["Settings"]["consoleLanguage"] = m_language; std::ofstream file(path, std::ios::out); diff --git a/src/common/config.h b/src/common/config.h index ff76f7765..7e717fe71 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -4,10 +4,7 @@ #pragma once #include -#include #include -#include "SDL3/SDL_stdinc.h" -#include "input/keys_constants.h" #include "types.h" namespace Config { @@ -82,8 +79,6 @@ void setPkgViewer(const std::vector& pkgList); void setElfViewer(const std::vector& elfList); void setRecentFiles(const std::vector& recentFiles); void setEmulatorLanguage(std::string language); -void setKeyboardBindingMap(std::map map); -const std::map& getKeyboardBindingMap(); u32 getMainWindowGeometryX(); u32 getMainWindowGeometryY(); diff --git a/src/emulator.cpp b/src/emulator.cpp index 3006de1e8..9c41a3dbd 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -146,7 +146,7 @@ void Emulator::Run(const std::filesystem::path& file) { } window = std::make_unique( Config::getScreenWidth(), Config::getScreenHeight(), controller, window_title); - window->setKeysBindingsMap(Config::getKeyboardBindingMap()); + g_window = window.get(); const auto& mount_data_dir = Common::FS::GetUserPath(Common::FS::PathType::GameDataDir) / id; diff --git a/src/emulator.h b/src/emulator.h index b1f779898..01bce7e7c 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -34,6 +34,6 @@ private: Input::GameController* controller; Core::Linker* linker; std::unique_ptr window; - std::map m_keysBindingsMap; }; + } // namespace Core diff --git a/src/images/PS4_controller_scheme.png b/src/images/PS4_controller_scheme.png deleted file mode 100644 index 9e095a063fb3ce8077d9ba5fed344f4687a6f7ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30766 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 YK%{qgoHl(3 -#include - -#include - -namespace { -static constexpr auto keyBindingsSettingsKey = "ShadPS4_Keyboard_Settings_KEY"; -static constexpr auto inputErrorTimerTimeout = 2000; -} // namespace - -void showError(const QString& message) { - QMessageBox::critical(nullptr, "Error", message, QMessageBox::Ok); -} - -void showWarning(const QString& message) { - QMessageBox::warning(nullptr, "Warning", message, QMessageBox::Ok); -} - -void showInfo(const QString& message) { - QMessageBox::information(nullptr, "Info", message, QMessageBox::Ok); -} - -KeyboardControlsWindow::KeyboardControlsWindow(QWidget* parent) - : QDialog(parent), ui(new Ui::KeyboardControlsWindow) { - ui->setupUi(this); - - m_keysMap = Config::getKeyboardBindingMap(); - - for (auto& pair : m_keysMap) { - m_reverseKeysMap.emplace(pair.second, pair.first); - } - - m_listOfKeySequenceEdits = {ui->StartKeySequenceEdit, ui->SelectKeySequenceEdit, - ui->LAnalogDownkeySequenceEdit, ui->LAnalogLeftkeySequenceEdit, - ui->LAnalogUpkeySequenceEdit, ui->LAnalogRightkeySequenceEdit, - ui->PSkeySequenceEdit, ui->RAnalogDownkeySequenceEdit, - ui->RAnalogLeftkeySequenceEdit, ui->RAnalogUpkeySequenceEdit, - ui->RAnalogRightkeySequenceEdit, ui->DPadLeftkeySequenceEdit, - ui->DPadRightkeySequenceEdit, ui->DPadUpkeySequenceEdit, - ui->DPadDownkeySequenceEdit, ui->L2keySequenceEdit, - ui->L1keySequenceEdit, ui->CrossKeySequenceEdit, - ui->R2KeySequenceEdit, ui->CircleKeySequenceEdit, - ui->R1KeySequenceEdit, ui->SquareKeySequenceEdit, - ui->TriangleKeySequenceEdit}; - - for (auto edit : m_listOfKeySequenceEdits) { - edit->setStyleSheet("QLineEdit { qproperty-alignment: AlignCenter; }"); - QObject::connect(edit, &QKeySequenceEdit::editingFinished, this, - &KeyboardControlsWindow::onEditingFinished); - } - - ui->StartKeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::Start_Key])); - ui->SelectKeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::Select_Key])); - ui->LAnalogDownkeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::LAnalogDown_Key])); - ui->LAnalogLeftkeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::LAnalogLeft_Key])); - ui->LAnalogUpkeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::LAnalogUp_Key])); - ui->LAnalogRightkeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::LAnalogRight_Key])); - ui->PSkeySequenceEdit->setKeySequence(convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::PS_Key])); - ui->RAnalogDownkeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::RAnalogDown_Key])); - ui->RAnalogLeftkeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::RAnalogLeft_Key])); - ui->RAnalogUpkeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::RAnalogUp_Key])); - ui->RAnalogRightkeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::RAnalogRight_Key])); - ui->DPadLeftkeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::DPadLeft_Key])); - ui->DPadRightkeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::DPadRight_Key])); - ui->DPadUpkeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::DPadUp_Key])); - ui->DPadDownkeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::DPadDown_Key])); - ui->L2keySequenceEdit->setKeySequence(convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::L2_Key])); - ui->L1keySequenceEdit->setKeySequence(convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::L1_Key])); - ui->CrossKeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::Cross_Key])); - ui->R2KeySequenceEdit->setKeySequence(convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::R2_Key])); - ui->CircleKeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::Circle_Key])); - ui->R1KeySequenceEdit->setKeySequence(convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::R1_Key])); - ui->SquareKeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::Square_Key])); - ui->TriangleKeySequenceEdit->setKeySequence( - convertSDLKeyToQt(m_reverseKeysMap[KeysMapping::Triangle_Key])); - - QObject::connect(ui->applyButton, &QPushButton::clicked, - [this]() { validateAndSaveKeyBindings(); }); - - QObject::connect(ui->cancelButton, &QPushButton::clicked, [this]() { this->close(); }); -} - -KeyboardControlsWindow::~KeyboardControlsWindow() { - delete ui; -} - -const std::map& KeyboardControlsWindow::getKeysMapping() const { - return m_keysMap; -} - -void KeyboardControlsWindow::validateAndSaveKeyBindings() { - int nOfUnconfiguredButtons = 0; - for (auto& keyEdit : m_listOfKeySequenceEdits) { - auto keySequence = keyEdit->keySequence(); - // If key sequence is empty (i.e. there is no key assigned to it) we highlight it in red - if (keySequence.isEmpty()) { - keyEdit->setStyleSheet("background-color: red; qproperty-alignment: AlignCenter;"); - QTimer::singleShot(inputErrorTimerTimeout, keyEdit, [keyEdit]() { - keyEdit->setStyleSheet("qproperty-alignment: AlignCenter;"); // Reset to default - }); - - ++nOfUnconfiguredButtons; - } - } - - if (nOfUnconfiguredButtons > 0) { - showError("Some of the buttons were not configured"); - return; - } - - m_keysMap.clear(); - m_reverseKeysMap.clear(); - - m_keysMap.emplace(convertQtKeyToSDL(ui->LAnalogDownkeySequenceEdit->keySequence()[0].key()), - KeysMapping::LAnalogDown_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->LAnalogLeftkeySequenceEdit->keySequence()[0].key()), - KeysMapping::LAnalogLeft_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->LAnalogUpkeySequenceEdit->keySequence()[0].key()), - KeysMapping::LAnalogUp_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->LAnalogRightkeySequenceEdit->keySequence()[0].key()), - KeysMapping::LAnalogRight_Key); - - m_keysMap.emplace(convertQtKeyToSDL(ui->PSkeySequenceEdit->keySequence()[0].key()), - KeysMapping::PS_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->StartKeySequenceEdit->keySequence()[0].key()), - KeysMapping::Start_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->SelectKeySequenceEdit->keySequence()[0].key()), - KeysMapping::Select_Key); - - m_keysMap.emplace(convertQtKeyToSDL(ui->RAnalogDownkeySequenceEdit->keySequence()[0].key()), - KeysMapping::RAnalogDown_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->RAnalogLeftkeySequenceEdit->keySequence()[0].key()), - KeysMapping::RAnalogLeft_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->RAnalogUpkeySequenceEdit->keySequence()[0].key()), - KeysMapping::RAnalogUp_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->RAnalogRightkeySequenceEdit->keySequence()[0].key()), - KeysMapping::RAnalogRight_Key); - - m_keysMap.emplace(convertQtKeyToSDL(ui->DPadLeftkeySequenceEdit->keySequence()[0].key()), - KeysMapping::DPadLeft_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->DPadRightkeySequenceEdit->keySequence()[0].key()), - KeysMapping::DPadRight_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->DPadUpkeySequenceEdit->keySequence()[0].key()), - KeysMapping::DPadUp_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->DPadDownkeySequenceEdit->keySequence()[0].key()), - KeysMapping::DPadDown_Key); - - m_keysMap.emplace(convertQtKeyToSDL(ui->L1keySequenceEdit->keySequence()[0].key()), - KeysMapping::L1_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->L2keySequenceEdit->keySequence()[0].key()), - KeysMapping::L2_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->R1KeySequenceEdit->keySequence()[0].key()), - KeysMapping::R1_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->R2KeySequenceEdit->keySequence()[0].key()), - KeysMapping::R2_Key); - - m_keysMap.emplace(convertQtKeyToSDL(ui->CrossKeySequenceEdit->keySequence()[0].key()), - KeysMapping::Cross_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->CircleKeySequenceEdit->keySequence()[0].key()), - KeysMapping::Circle_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->SquareKeySequenceEdit->keySequence()[0].key()), - KeysMapping::Square_Key); - m_keysMap.emplace(convertQtKeyToSDL(ui->TriangleKeySequenceEdit->keySequence()[0].key()), - KeysMapping::Triangle_Key); - - for (auto& pair : m_keysMap) { - m_reverseKeysMap.emplace(pair.second, pair.first); - } - - // Saving into settings (for permanent storage) - Config::setKeyboardBindingMap(m_keysMap); - - this->close(); -} - -Qt::Key KeyboardControlsWindow::convertSDLKeyToQt(SDL_Keycode sdlKey) { - switch (sdlKey) { - case SDLK_A: - return Qt::Key_A; - case SDLK_B: - return Qt::Key_B; - case SDLK_C: - return Qt::Key_C; - case SDLK_D: - return Qt::Key_D; - case SDLK_E: - return Qt::Key_E; - case SDLK_F: - return Qt::Key_F; - case SDLK_G: - return Qt::Key_G; - case SDLK_H: - return Qt::Key_H; - case SDLK_I: - return Qt::Key_I; - case SDLK_J: - return Qt::Key_J; - case SDLK_K: - return Qt::Key_K; - case SDLK_L: - return Qt::Key_L; - case SDLK_M: - return Qt::Key_M; - case SDLK_N: - return Qt::Key_N; - case SDLK_O: - return Qt::Key_O; - case SDLK_P: - return Qt::Key_P; - case SDLK_Q: - return Qt::Key_Q; - case SDLK_R: - return Qt::Key_R; - case SDLK_S: - return Qt::Key_S; - case SDLK_T: - return Qt::Key_T; - case SDLK_U: - return Qt::Key_U; - case SDLK_V: - return Qt::Key_V; - case SDLK_W: - return Qt::Key_W; - case SDLK_X: - return Qt::Key_X; - case SDLK_Y: - return Qt::Key_Y; - case SDLK_Z: - return Qt::Key_Z; - case SDLK_0: - return Qt::Key_0; - case SDLK_1: - return Qt::Key_1; - case SDLK_2: - return Qt::Key_2; - case SDLK_3: - return Qt::Key_3; - case SDLK_4: - return Qt::Key_4; - case SDLK_5: - return Qt::Key_5; - case SDLK_6: - return Qt::Key_6; - case SDLK_7: - return Qt::Key_7; - case SDLK_8: - return Qt::Key_8; - case SDLK_9: - return Qt::Key_9; - case SDLK_SPACE: - return Qt::Key_Space; - case SDLK_RETURN: - return Qt::Key_Return; - case SDLK_ESCAPE: - return Qt::Key_Escape; - case SDLK_TAB: - return Qt::Key_Tab; - case SDLK_BACKSPACE: - return Qt::Key_Backspace; - case SDLK_DELETE: - return Qt::Key_Delete; - case SDLK_INSERT: - return Qt::Key_Insert; - case SDLK_HOME: - return Qt::Key_Home; - case SDLK_END: - return Qt::Key_End; - case SDLK_PAGEUP: - return Qt::Key_PageUp; - case SDLK_PAGEDOWN: - return Qt::Key_PageDown; - case SDLK_LEFT: - return Qt::Key_Left; - case SDLK_RIGHT: - return Qt::Key_Right; - case SDLK_UP: - return Qt::Key_Up; - case SDLK_DOWN: - return Qt::Key_Down; - case SDLK_CAPSLOCK: - return Qt::Key_CapsLock; - case SDLK_NUMLOCKCLEAR: - return Qt::Key_NumLock; - case SDLK_SCROLLLOCK: - return Qt::Key_ScrollLock; - case SDLK_F1: - return Qt::Key_F1; - case SDLK_F2: - return Qt::Key_F2; - case SDLK_F3: - return Qt::Key_F3; - case SDLK_F4: - return Qt::Key_F4; - case SDLK_F5: - return Qt::Key_F5; - case SDLK_F6: - return Qt::Key_F6; - case SDLK_F7: - return Qt::Key_F7; - case SDLK_F8: - return Qt::Key_F8; - case SDLK_F9: - return Qt::Key_F9; - case SDLK_F10: - return Qt::Key_F10; - case SDLK_F11: - return Qt::Key_F11; - case SDLK_F12: - return Qt::Key_F12; - case SDLK_LSHIFT: - return Qt::Key_Shift; - case SDLK_LCTRL: - return Qt::Key_Control; - case SDLK_LALT: - return Qt::Key_Alt; - case SDLK_LGUI: - return Qt::Key_Meta; - default: - return Qt::Key_unknown; - } -} - -SDL_Keycode KeyboardControlsWindow::convertQtKeyToSDL(Qt::Key qtKey) { - switch (qtKey) { - case Qt::Key_A: - return SDLK_A; - case Qt::Key_B: - return SDLK_B; - case Qt::Key_C: - return SDLK_C; - case Qt::Key_D: - return SDLK_D; - case Qt::Key_E: - return SDLK_E; - case Qt::Key_F: - return SDLK_F; - case Qt::Key_G: - return SDLK_G; - case Qt::Key_H: - return SDLK_H; - case Qt::Key_I: - return SDLK_I; - case Qt::Key_J: - return SDLK_J; - case Qt::Key_K: - return SDLK_K; - case Qt::Key_L: - return SDLK_L; - case Qt::Key_M: - return SDLK_M; - case Qt::Key_N: - return SDLK_N; - case Qt::Key_O: - return SDLK_O; - case Qt::Key_P: - return SDLK_P; - case Qt::Key_Q: - return SDLK_Q; - case Qt::Key_R: - return SDLK_R; - case Qt::Key_S: - return SDLK_S; - case Qt::Key_T: - return SDLK_T; - case Qt::Key_U: - return SDLK_U; - case Qt::Key_V: - return SDLK_V; - case Qt::Key_W: - return SDLK_W; - case Qt::Key_X: - return SDLK_X; - case Qt::Key_Y: - return SDLK_Y; - case Qt::Key_Z: - return SDLK_Z; - case Qt::Key_0: - return SDLK_0; - case Qt::Key_1: - return SDLK_1; - case Qt::Key_2: - return SDLK_2; - case Qt::Key_3: - return SDLK_3; - case Qt::Key_4: - return SDLK_4; - case Qt::Key_5: - return SDLK_5; - case Qt::Key_6: - return SDLK_6; - case Qt::Key_7: - return SDLK_7; - case Qt::Key_8: - return SDLK_8; - case Qt::Key_9: - return SDLK_9; - case Qt::Key_Space: - return SDLK_SPACE; - case Qt::Key_Enter: - return SDLK_RETURN; - case Qt::Key_Return: - return SDLK_RETURN; - case Qt::Key_Escape: - return SDLK_ESCAPE; - case Qt::Key_Tab: - return SDLK_TAB; - case Qt::Key_Backspace: - return SDLK_BACKSPACE; - case Qt::Key_Delete: - return SDLK_DELETE; - case Qt::Key_Insert: - return SDLK_INSERT; - case Qt::Key_Home: - return SDLK_HOME; - case Qt::Key_End: - return SDLK_END; - case Qt::Key_PageUp: - return SDLK_PAGEUP; - case Qt::Key_PageDown: - return SDLK_PAGEDOWN; - case Qt::Key_Left: - return SDLK_LEFT; - case Qt::Key_Right: - return SDLK_RIGHT; - case Qt::Key_Up: - return SDLK_UP; - case Qt::Key_Down: - return SDLK_DOWN; - case Qt::Key_CapsLock: - return SDLK_CAPSLOCK; - case Qt::Key_NumLock: - return SDLK_NUMLOCKCLEAR; - case Qt::Key_ScrollLock: - return SDLK_SCROLLLOCK; - case Qt::Key_F1: - return SDLK_F1; - case Qt::Key_F2: - return SDLK_F2; - case Qt::Key_F3: - return SDLK_F3; - case Qt::Key_F4: - return SDLK_F4; - case Qt::Key_F5: - return SDLK_F5; - case Qt::Key_F6: - return SDLK_F6; - case Qt::Key_F7: - return SDLK_F7; - case Qt::Key_F8: - return SDLK_F8; - case Qt::Key_F9: - return SDLK_F9; - case Qt::Key_F10: - return SDLK_F10; - case Qt::Key_F11: - return SDLK_F11; - case Qt::Key_F12: - return SDLK_F12; - case Qt::Key_Shift: - return SDLK_LSHIFT; - case Qt::Key_Control: - return SDLK_LCTRL; - case Qt::Key_Alt: - return SDLK_LALT; - case Qt::Key_Meta: - return SDLK_LGUI; - default: - return SDLK_UNKNOWN; - } -} - -void KeyboardControlsWindow::onEditingFinished() { - auto sender = qobject_cast(QObject::sender()); - auto new_keySequence = sender->keySequence(); - - // If new key sequence is empty (i.e. there is no key assigned to it) - skip 'duplicate' checks - // Two checks are needed for the sake of robustness (when we click on a widget but don't type - // anything it might no longer be "empty") - if (new_keySequence.isEmpty() || new_keySequence.toString().isEmpty()) { - return; - } - - // Check if sequance is not already used (i.e. making sure there are not duplicates) - for (auto& keyEdit : m_listOfKeySequenceEdits) { - if (keyEdit != sender && new_keySequence == keyEdit->keySequence()) { - sender->clear(); - sender->setStyleSheet("background-color: red; qproperty-alignment: AlignCenter;"); - QTimer::singleShot(inputErrorTimerTimeout, sender, [sender]() { - sender->setStyleSheet( - "QLineEdit { qproperty-alignment: AlignCenter; }"); // Reset to default - }); - - keyEdit->setStyleSheet("background-color: red; qproperty-alignment: AlignCenter;"); - QTimer::singleShot(inputErrorTimerTimeout, keyEdit, [keyEdit]() { - keyEdit->setStyleSheet( - "QLineEdit { qproperty-alignment: AlignCenter; }"); // Reset to default - }); - } - } -} diff --git a/src/qt_gui/keyboardcontrolswindow.h b/src/qt_gui/keyboardcontrolswindow.h deleted file mode 100644 index 3649917e2..000000000 --- a/src/qt_gui/keyboardcontrolswindow.h +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include - -#include -#include "input/keys_constants.h" - -QT_BEGIN_NAMESPACE -namespace Ui { -class KeyboardControlsWindow; -} -QT_END_NAMESPACE - -class KeyboardControlsWindow : public QDialog { - Q_OBJECT - -public: - KeyboardControlsWindow(QWidget* parent = nullptr); - ~KeyboardControlsWindow(); - - const std::map& getKeysMapping() const; - -private slots: - void onEditingFinished(); - -private: - void validateAndSaveKeyBindings(); - SDL_Keycode convertQtKeyToSDL(Qt::Key qtKey); - Qt::Key convertSDLKeyToQt(SDL_Keycode qtKey); - - Ui::KeyboardControlsWindow* ui; - QSet m_listOfKeySequenceEdits; - std::map m_keysMap; - std::map m_reverseKeysMap; -}; diff --git a/src/qt_gui/keyboardcontrolswindow.ui b/src/qt_gui/keyboardcontrolswindow.ui deleted file mode 100644 index 7973e0c5a..000000000 --- a/src/qt_gui/keyboardcontrolswindow.ui +++ /dev/null @@ -1,439 +0,0 @@ - - - - KeyboardControlsWindow - - - - 0 - 0 - 1155 - 790 - - - - - 0 - 0 - - - - - 1148 - 731 - - - - - 1155 - 790 - - - - Configure Controller Bindings - - - true - - - - - 10 - 10 - 1131 - 711 - - - - 0 - - - - Port 1 - - - - - -10 - 20 - 1131 - 621 - - - - - - 170 - 50 - 870 - 522 - - - - false - - - QWidget { background-image: url(:images/PS4_controller_scheme.png); - background-repeat: no-repeat; - background-position: center; } - - - - - - 550 - 0 - 71 - 40 - - - - 1 - - - - - - 260 - 0 - 71 - 40 - - - - 1 - - - - - - 280 - 480 - 71 - 40 - - - - 1 - - - - - - 240 - 440 - 71 - 40 - - - - 1 - - - - - - 280 - 400 - 71 - 40 - - - - 1 - - - - - - 320 - 440 - 71 - 40 - - - - 1 - - - - - - 400 - 400 - 71 - 40 - - - - 1 - - - - - - 520 - 480 - 71 - 40 - - - - 1 - - - - - - 480 - 440 - 71 - 40 - - - - 1 - - - - - - 520 - 400 - 71 - 40 - - - - 1 - - - - - - 560 - 440 - 71 - 40 - - - - 1 - - - - - - - 10 - 230 - 71 - 40 - - - - 1 - - - - - - 90 - 230 - 71 - 40 - - - - 1 - - - - - - 50 - 190 - 71 - 40 - - - - 1 - - - - - - 50 - 270 - 71 - 40 - - - - 1 - - - - - - 90 - 40 - 71 - 40 - - - - 1 - - - - - - 90 - 110 - 71 - 40 - - - - 1 - - - - - true - - - - 1050 - 380 - 71 - 40 - - - - 1 - - - - - true - - - - 1050 - 30 - 71 - 40 - - - - 1 - - - - - true - - - - 1050 - 240 - 71 - 40 - - - - 1 - - - - - true - - - - 1050 - 100 - 71 - 40 - - - - 1 - - - - - true - - - - 1050 - 310 - 71 - 40 - - - - 1 - - - - - true - - - - 1050 - 170 - 71 - 40 - - - - 1 - - - - - - - Port 2 - - - - - - - 1030 - 740 - 100 - 32 - - - - Apply - - - - - - 890 - 740 - 100 - 32 - - - - Cancel - - - - - - diff --git a/src/qt_gui/main_window.cpp b/src/qt_gui/main_window.cpp index 59387a1a9..e5b502c58 100644 --- a/src/qt_gui/main_window.cpp +++ b/src/qt_gui/main_window.cpp @@ -50,7 +50,6 @@ bool MainWindow::Init() { auto end = std::chrono::steady_clock::now(); auto duration = std::chrono::duration_cast(end - start); statusBar.reset(new QStatusBar); - m_controllerControlsDialog.reset(new KeyboardControlsWindow()); this->setStatusBar(statusBar.data()); // Update status bar int numGames = m_game_info->m_games.size(); @@ -91,9 +90,6 @@ void MainWindow::AddUiWidgets() { ui->toolBar->addWidget(ui->stopButton); ui->toolBar->addWidget(ui->refreshButton); ui->toolBar->addWidget(ui->settingsButton); - auto connection = QObject::connect(ui->controllerButton, &QPushButton::clicked, this, - &MainWindow::ControllerConfigurationButtonPressed); - ui->toolBar->addWidget(ui->controllerButton); QFrame* line = new QFrame(this); line->setFrameShape(QFrame::StyledPanel); @@ -103,10 +99,6 @@ void MainWindow::AddUiWidgets() { ui->toolBar->addWidget(ui->mw_searchbar); } -void MainWindow::ControllerConfigurationButtonPressed() { - m_controllerControlsDialog->show(); -} - void MainWindow::CreateDockWindows() { // place holder widget is needed for good health they say :) QWidget* phCentralWidget = new QWidget(this); @@ -789,10 +781,6 @@ void MainWindow::InstallDirectory() { RefreshGameTable(); } -std::map MainWindow::getKeysMapping() { - return m_controllerControlsDialog->getKeysMapping(); -} - void MainWindow::SetLastUsedTheme() { Theme lastTheme = static_cast(Config::getMainWindowTheme()); m_window_themes.SetWindowTheme(lastTheme, ui->mw_searchbar); diff --git a/src/qt_gui/main_window.h b/src/qt_gui/main_window.h index 8ffb760b0..d3b83e619 100644 --- a/src/qt_gui/main_window.h +++ b/src/qt_gui/main_window.h @@ -17,7 +17,6 @@ #include "game_info.h" #include "game_list_frame.h" #include "game_list_utils.h" -#include "keyboardcontrolswindow.h" #include "main_window_themes.h" #include "main_window_ui.h" #include "pkg_viewer.h" @@ -38,8 +37,6 @@ public: void InstallDirectory(); void StartGame(); - std::map getKeysMapping(); - private Q_SLOTS: void ConfigureGuiFromSettings(); void SaveWindowState() const; @@ -48,7 +45,6 @@ private Q_SLOTS: void RefreshGameTable(); void HandleResize(QResizeEvent* event); void OnLanguageChanged(const std::string& locale); - void ControllerConfigurationButtonPressed(); private: Ui_MainWindow* ui; @@ -84,7 +80,6 @@ private: QScopedPointer m_elf_viewer; // Status Bar. QScopedPointer statusBar; - QScopedPointer m_controllerControlsDialog; // Available GPU devices std::vector m_physical_devices; diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index 123ccce75..f3418c8f9 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -118,310 +118,193 @@ void WindowSDL::waitEvent() { } } -void WindowSDL::setKeysBindingsMap(const std::map& bindingsMap) { - keysBindingsMap = bindingsMap; -} - void WindowSDL::onResize() { SDL_GetWindowSizeInPixels(window, &width, &height); ImGui::Core::OnResize(); } -using Libraries::Pad::OrbisPadButtonDataOffset; - void WindowSDL::onKeyPress(const SDL_Event* event) { + using Libraries::Pad::OrbisPadButtonDataOffset; + +#ifdef __APPLE__ + // Use keys that are more friendly for keyboards without a keypad. + // Once there are key binding options this won't be necessary. + constexpr SDL_Keycode CrossKey = SDLK_N; + constexpr SDL_Keycode CircleKey = SDLK_B; + constexpr SDL_Keycode SquareKey = SDLK_V; + constexpr SDL_Keycode TriangleKey = SDLK_C; +#else + constexpr SDL_Keycode CrossKey = SDLK_KP_2; + constexpr SDL_Keycode CircleKey = SDLK_KP_6; + constexpr SDL_Keycode SquareKey = SDLK_KP_4; + constexpr SDL_Keycode TriangleKey = SDLK_KP_8; +#endif + u32 button = 0; Input::Axis axis = Input::Axis::AxisMax; int axisvalue = 0; int ax = 0; - - bool keyHandlingPending = true; - if (!keysBindingsMap.empty()) { - - std::optional ps4KeyOpt; - auto foundIt = keysBindingsMap.find(event->key.key); - if (foundIt != keysBindingsMap.end()) { - ps4KeyOpt = foundIt->second; + switch (event->key.key) { + case SDLK_UP: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_UP; + break; + case SDLK_DOWN: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_DOWN; + break; + case SDLK_LEFT: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_LEFT; + break; + case SDLK_RIGHT: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_RIGHT; + break; + case TriangleKey: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TRIANGLE; + break; + case CircleKey: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CIRCLE; + break; + case CrossKey: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CROSS; + break; + case SquareKey: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_SQUARE; + break; + case SDLK_RETURN: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_OPTIONS; + break; + case SDLK_A: + axis = Input::Axis::LeftX; + if (event->type == SDL_EVENT_KEY_DOWN) { + axisvalue += -127; + } else { + axisvalue = 0; } - - // No support for modifiers (yet) - if (ps4KeyOpt.has_value() && (event->key.mod == SDL_KMOD_NONE)) { - keyHandlingPending = false; - - auto ps4Key = ps4KeyOpt.value(); - if (ps4Key == KeysMapping::Start_Key) - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_OPTIONS; - if (ps4Key == KeysMapping::Triangle_Key) - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TRIANGLE; - if (ps4Key == KeysMapping::Circle_Key) - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CIRCLE; - if (ps4Key == KeysMapping::Cross_Key) - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CROSS; - if (ps4Key == KeysMapping::Square_Key) - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_SQUARE; - if (ps4Key == KeysMapping::R1_Key) - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R1; - if (ps4Key == KeysMapping::R2_Key) - handleR2Key(event, button, axis, axisvalue, ax); - if (ps4Key == KeysMapping::DPadLeft_Key) - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_LEFT; - if (ps4Key == KeysMapping::DPadRight_Key) - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_RIGHT; - if (ps4Key == KeysMapping::DPadDown_Key) - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_DOWN; - if (ps4Key == KeysMapping::DPadUp_Key) - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_UP; - if (ps4Key == KeysMapping::LAnalogLeft_Key) - handleLAnalogLeftKey(event, button, axis, axisvalue, ax); - if (ps4Key == KeysMapping::LAnalogUp_Key) - handleLAnalogUpKey(event, button, axis, axisvalue, ax); - if (ps4Key == KeysMapping::LAnalogDown_Key) - handleLAnalogDownKey(event, button, axis, axisvalue, ax); - if (ps4Key == KeysMapping::RAnalogLeft_Key) - handleRAnalogLeftKey(event, button, axis, axisvalue, ax); - if (ps4Key == KeysMapping::RAnalogRight_Key) - handleRAnalogRightKey(event, button, axis, axisvalue, ax); - if (ps4Key == KeysMapping::RAnalogUp_Key) - handleRAnalogUpKey(event, button, axis, axisvalue, ax); - if (ps4Key == KeysMapping::RAnalogDown_Key) - handleRAnalogDownKey(event, button, axis, axisvalue, ax); + ax = Input::GetAxis(-0x80, 0x80, axisvalue); + break; + case SDLK_D: + axis = Input::Axis::LeftX; + if (event->type == SDL_EVENT_KEY_DOWN) { + axisvalue += 127; + } else { + axisvalue = 0; } - } - - if (keyHandlingPending) { - switch (event->key.key) { - case SDLK_UP: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_UP; - break; - case SDLK_DOWN: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_DOWN; - break; - case SDLK_LEFT: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_LEFT; - break; - case SDLK_RIGHT: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_RIGHT; - break; - case Triangle_Key: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TRIANGLE; - break; - case Circle_Key: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CIRCLE; - break; - case Cross_Key: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CROSS; - break; - case Square_Key: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_SQUARE; - break; - case SDLK_KP_8: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TRIANGLE; - break; - case SDLK_KP_6: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CIRCLE; - break; - case SDLK_KP_2: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CROSS; - break; - case SDLK_KP_4: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_SQUARE; - break; - case SDLK_RETURN: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_OPTIONS; - break; - case SDLK_A: - handleLAnalogLeftKey(event, button, axis, axisvalue, ax); - break; - case SDLK_D: - handleLAnalogRightKey(event, button, axis, axisvalue, ax); - break; - case SDLK_W: - handleLAnalogUpKey(event, button, axis, axisvalue, ax); - break; - case SDLK_S: - handleLAnalogDownKey(event, button, axis, axisvalue, ax); - if (event->key.mod == SDL_KMOD_LCTRL) { - // Trigger rdoc capture - VideoCore::TriggerCapture(); - } - break; - case SDLK_J: - handleRAnalogLeftKey(event, button, axis, axisvalue, ax); - break; - case SDLK_L: - handleRAnalogRightKey(event, button, axis, axisvalue, ax); - break; - case SDLK_I: - handleRAnalogUpKey(event, button, axis, axisvalue, ax); - break; - case SDLK_K: - handleRAnalogDownKey(event, button, axis, axisvalue, ax); - break; - case SDLK_X: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L3; - break; - case SDLK_M: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R3; - break; - case SDLK_Q: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L1; - break; - case SDLK_U: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R1; - break; - case SDLK_E: - handleL2Key(event, button, axis, axisvalue, ax); - break; - case SDLK_O: - handleR2Key(event, button, axis, axisvalue, ax); - break; - case SDLK_SPACE: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TOUCH_PAD; - break; - case SDLK_F11: - if (event->type == SDL_EVENT_KEY_DOWN) { + ax = Input::GetAxis(-0x80, 0x80, axisvalue); + break; + case SDLK_W: + axis = Input::Axis::LeftY; + if (event->type == SDL_EVENT_KEY_DOWN) { + axisvalue += -127; + } else { + axisvalue = 0; + } + ax = Input::GetAxis(-0x80, 0x80, axisvalue); + break; + case SDLK_S: + axis = Input::Axis::LeftY; + if (event->type == SDL_EVENT_KEY_DOWN) { + axisvalue += 127; + } else { + axisvalue = 0; + } + ax = Input::GetAxis(-0x80, 0x80, axisvalue); + break; + case SDLK_J: + axis = Input::Axis::RightX; + if (event->type == SDL_EVENT_KEY_DOWN) { + axisvalue += -127; + } else { + axisvalue = 0; + } + ax = Input::GetAxis(-0x80, 0x80, axisvalue); + break; + case SDLK_L: + axis = Input::Axis::RightX; + if (event->type == SDL_EVENT_KEY_DOWN) { + axisvalue += 127; + } else { + axisvalue = 0; + } + ax = Input::GetAxis(-0x80, 0x80, axisvalue); + break; + case SDLK_I: + axis = Input::Axis::RightY; + if (event->type == SDL_EVENT_KEY_DOWN) { + axisvalue += -127; + } else { + axisvalue = 0; + } + ax = Input::GetAxis(-0x80, 0x80, axisvalue); + break; + case SDLK_K: + axis = Input::Axis::RightY; + if (event->type == SDL_EVENT_KEY_DOWN) { + axisvalue += 127; + } else { + axisvalue = 0; + } + ax = Input::GetAxis(-0x80, 0x80, axisvalue); + break; + case SDLK_X: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L3; + break; + case SDLK_M: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R3; + break; + case SDLK_Q: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L1; + break; + case SDLK_U: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R1; + break; + case SDLK_E: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L2; + axis = Input::Axis::TriggerLeft; + if (event->type == SDL_EVENT_KEY_DOWN) { + axisvalue += 255; + } else { + axisvalue = 0; + } + ax = Input::GetAxis(0, 0x80, axisvalue); + break; + case SDLK_O: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R2; + axis = Input::Axis::TriggerRight; + if (event->type == SDL_EVENT_KEY_DOWN) { + axisvalue += 255; + } else { + axisvalue = 0; + } + ax = Input::GetAxis(0, 0x80, axisvalue); + break; + case SDLK_SPACE: + button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TOUCH_PAD; + break; + case SDLK_F11: + if (event->type == SDL_EVENT_KEY_DOWN) { + { SDL_WindowFlags flag = SDL_GetWindowFlags(window); bool is_fullscreen = flag & SDL_WINDOW_FULLSCREEN; SDL_SetWindowFullscreen(window, !is_fullscreen); } - break; - case SDLK_F12: - if (event->type == SDL_EVENT_KEY_DOWN) { - // Trigger rdoc capture - VideoCore::TriggerCapture(); - } - break; - default: - break; } + break; + case SDLK_F12: + if (event->type == SDL_EVENT_KEY_DOWN) { + // Trigger rdoc capture + VideoCore::TriggerCapture(); + } + break; + default: + break; } - if (button != 0) { controller->CheckButton(0, button, event->type == SDL_EVENT_KEY_DOWN); } if (axis != Input::Axis::AxisMax) { - if (event->gaxis.axis == SDL_GAMEPAD_AXIS_LEFT_TRIGGER || - event->gaxis.axis == SDL_GAMEPAD_AXIS_RIGHT_TRIGGER) { - controller->Axis(0, axis, Input::GetAxis(0, 0x8000, event->gaxis.value)); - - } else { - controller->Axis(0, axis, Input::GetAxis(-0x8000, 0x8000, event->gaxis.value)); - } + controller->Axis(0, axis, ax); } } -void WindowSDL::handleR2Key(const SDL_Event* event, u32& button, Input::Axis& axis, int& axisvalue, - int& ax) { - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R2; - axis = Input::Axis::TriggerRight; - if (event->type == SDL_EVENT_KEY_DOWN) { - axisvalue += 255; - } else { - axisvalue = 0; - } - ax = Input::GetAxis(0, 0x80, axisvalue); -} - -void WindowSDL::handleL2Key(const SDL_Event* event, u32& button, Input::Axis& axis, int& axisvalue, - int& ax) { - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L2; - axis = Input::Axis::TriggerLeft; - if (event->type == SDL_EVENT_KEY_DOWN) { - axisvalue += 255; - } else { - axisvalue = 0; - } - ax = Input::GetAxis(0, 0x80, axisvalue); -} - -void WindowSDL::handleLAnalogRightKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax) { - axis = Input::Axis::LeftX; - if (event->type == SDL_EVENT_KEY_DOWN) { - axisvalue += 127; - } else { - axisvalue = 0; - } - ax = Input::GetAxis(-0x80, 0x80, axisvalue); -} - -void WindowSDL::handleLAnalogLeftKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax) { - axis = Input::Axis::LeftX; - if (event->type == SDL_EVENT_KEY_DOWN) { - axisvalue += -127; - } else { - axisvalue = 0; - } - ax = Input::GetAxis(-0x80, 0x80, axisvalue); -} - -void WindowSDL::handleLAnalogUpKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax) { - axis = Input::Axis::LeftY; - if (event->type == SDL_EVENT_KEY_DOWN) { - axisvalue += -127; - } else { - axisvalue = 0; - } - ax = Input::GetAxis(-0x80, 0x80, axisvalue); -} - -void WindowSDL::handleLAnalogDownKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax) { - axis = Input::Axis::LeftY; - if (event->type == SDL_EVENT_KEY_DOWN) { - axisvalue += 127; - } else { - axisvalue = 0; - } - ax = Input::GetAxis(-0x80, 0x80, axisvalue); -} - -void WindowSDL::handleRAnalogRightKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax) { - axis = Input::Axis::RightX; - if (event->type == SDL_EVENT_KEY_DOWN) { - axisvalue += 127; - } else { - axisvalue = 0; - } - ax = Input::GetAxis(-0x80, 0x80, axisvalue); -} - -void WindowSDL::handleRAnalogLeftKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax) { - axis = Input::Axis::RightX; - if (event->type == SDL_EVENT_KEY_DOWN) { - axisvalue += -127; - } else { - axisvalue = 0; - } - ax = Input::GetAxis(-0x80, 0x80, axisvalue); -} - -void WindowSDL::handleRAnalogUpKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax) { - axis = Input::Axis::RightY; - if (event->type == SDL_EVENT_KEY_DOWN) { - axisvalue += -127; - } else { - axisvalue = 0; - } - ax = Input::GetAxis(-0x80, 0x80, axisvalue); -} - -void WindowSDL::handleRAnalogDownKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax) { - axis = Input::Axis::RightY; - if (event->type == SDL_EVENT_KEY_DOWN) { - axisvalue += 127; - } else { - axisvalue = 0; - } - ax = Input::GetAxis(-0x80, 0x80, axisvalue); -} - void WindowSDL::onGamepadEvent(const SDL_Event* event) { using Libraries::Pad::OrbisPadButtonDataOffset; @@ -506,4 +389,4 @@ int WindowSDL::sdlGamepadToOrbisButton(u8 button) { } } -} // namespace Frontend \ No newline at end of file +} // namespace Frontend diff --git a/src/sdl_window.h b/src/sdl_window.h index 10ecd081c..2a5aeb38c 100644 --- a/src/sdl_window.h +++ b/src/sdl_window.h @@ -3,10 +3,8 @@ #pragma once -#include #include #include "common/types.h" -#include "input/keys_constants.h" struct SDL_Window; struct SDL_Gamepad; @@ -14,8 +12,7 @@ union SDL_Event; namespace Input { class GameController; -enum class Axis; -} // namespace Input +} namespace Frontend { @@ -71,8 +68,6 @@ public: void waitEvent(); - void setKeysBindingsMap(const std::map& bindingsMap); - private: void onResize(); void onKeyPress(const SDL_Event* event); @@ -80,34 +75,12 @@ private: int sdlGamepadToOrbisButton(u8 button); - void handleR2Key(const SDL_Event* event, u32& button, Input::Axis& axis, int& axisvalue, - int& ax); - void handleL2Key(const SDL_Event* event, u32& button, Input::Axis& axis, int& axisvalue, - int& ax); - void handleLAnalogRightKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax); - void handleLAnalogLeftKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax); - void handleLAnalogUpKey(const SDL_Event* event, u32& button, Input::Axis& axis, int& axisvalue, - int& ax); - void handleLAnalogDownKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax); - void handleRAnalogRightKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax); - void handleRAnalogLeftKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax); - void handleRAnalogUpKey(const SDL_Event* event, u32& button, Input::Axis& axis, int& axisvalue, - int& ax); - void handleRAnalogDownKey(const SDL_Event* event, u32& button, Input::Axis& axis, - int& axisvalue, int& ax); - private: s32 width; s32 height; Input::GameController* controller; WindowSystemInfo window_info{}; SDL_Window* window{}; - std::map keysBindingsMap; bool is_shown{}; bool is_open{true}; }; diff --git a/src/shadps4.qrc b/src/shadps4.qrc index 00f51bc6f..c22b837bd 100644 --- a/src/shadps4.qrc +++ b/src/shadps4.qrc @@ -14,7 +14,6 @@ images/exit_icon.png images/settings_icon.png images/controller_icon.png - images/PS4_controller_scheme.png images/refresh_icon.png images/list_mode_icon.png images/flag_jp.png