From d26417b83f3b2604b6f944a32445c80688033d80 Mon Sep 17 00:00:00 2001 From: iris Date: Wed, 10 Jun 2026 15:26:59 +0200 Subject: [PATCH] remappable inputs in progress --- CMakeLists.txt | 2 + src/frontend/KaizenGui.cpp | 26 +++- src/frontend/KaizenGui.hpp | 7 +- src/frontend/Settings/GeneralSettings.cpp | 4 +- src/frontend/Settings/GeneralSettings.hpp | 4 +- src/frontend/Settings/InputSettings.cpp | 138 ++++++++++++++++++++++ src/frontend/Settings/InputSettings.hpp | 42 +++++++ src/frontend/SettingsWindow.cpp | 2 + src/frontend/SettingsWindow.hpp | 2 + 9 files changed, 213 insertions(+), 14 deletions(-) create mode 100644 src/frontend/Settings/InputSettings.cpp create mode 100644 src/frontend/Settings/InputSettings.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e7adf4..43844a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,6 +168,8 @@ qt_add_executable(kaizen src/frontend/Settings/CPUSettings.cpp src/frontend/Settings/AudioSettings.hpp src/frontend/Settings/AudioSettings.cpp + src/frontend/Settings/InputSettings.hpp + src/frontend/Settings/InputSettings.cpp src/utils/Options.cpp src/utils/File.cpp) diff --git a/src/frontend/KaizenGui.cpp b/src/frontend/KaizenGui.cpp index 79fcacb..22263b1 100644 --- a/src/frontend/KaizenGui.cpp +++ b/src/frontend/KaizenGui.cpp @@ -15,6 +15,8 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User hide(); + installEventFilter(this); + restoreGeometry(settings.value("geometry").toByteArray()); restoreState(settings.value("windowState").toByteArray()); @@ -238,15 +240,31 @@ void KaizenGui::dragEnterEvent(QDragEnterEvent *event) { } void KaizenGui::keyPressEvent(QKeyEvent *event) { - for (int i = 0; i < mapping.size(); i++) { - if (mapping[i] == event->key()) + for (int i = 0; i < settingsWindow->input->mapping.size(); i++) { + if (settingsWindow->input->mapping[i] == event->key()) pressedKeys.set(i); } } void KaizenGui::keyReleaseEvent(QKeyEvent *event) { - for (int i = 0; i < mapping.size(); i++) { - if (mapping[i] == event->key()) + for (int i = 0; i < settingsWindow->input->mapping.size(); i++) { + if (settingsWindow->input->mapping[i] == event->key()) pressedKeys.reset(i); } } + +bool KaizenGui::eventFilter(QObject *obj, QEvent *event) { + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (!settingsWindow->hasFocus()) + return keyPressEvent(keyEvent), true; + } + + if (event->type() == QEvent::KeyRelease) { + QKeyEvent *keyEvent = static_cast(event); + if (!settingsWindow->hasFocus()) + return keyReleaseEvent(keyEvent), true; + } + + return QMainWindow::eventFilter(obj, event); +} diff --git a/src/frontend/KaizenGui.hpp b/src/frontend/KaizenGui.hpp index d581495..022ee68 100644 --- a/src/frontend/KaizenGui.hpp +++ b/src/frontend/KaizenGui.hpp @@ -8,7 +8,6 @@ #include #include #include -#include class EmuThread; @@ -16,6 +15,7 @@ class KaizenGui final : QMainWindow { Q_OBJECT void updateKeys(); void updateAxis(); + bool eventFilter(QObject *, QEvent *) override; public: explicit KaizenGui() noexcept; @@ -53,9 +53,4 @@ class KaizenGui final : QMainWindow { float elapsed = 0.f; n64::Core &core = n64::Core::GetInstance(); std::bitset<18> pressedKeys{}; - std::array mapping = { - Qt::Key_Z, Qt::Key_X, Qt::Key_C, Qt::Key_A, Qt::Key_S, Qt::Key_Return, - Qt::Key_I, Qt::Key_K, Qt::Key_J, Qt::Key_L, Qt::Key_T, Qt::Key_G, - Qt::Key_F, Qt::Key_H, Qt::Key_Up, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right, - }; }; diff --git a/src/frontend/Settings/GeneralSettings.cpp b/src/frontend/Settings/GeneralSettings.cpp index 046c9c3..facfffd 100644 --- a/src/frontend/Settings/GeneralSettings.cpp +++ b/src/frontend/Settings/GeneralSettings.cpp @@ -9,9 +9,9 @@ GeneralSettings::GeneralSettings() : settings(QSettings::UserScope) { description->setToolTip("Path where game saves are stored."); selectedFolderLabel = new QLabel(Options::GetSavesPath().c_str()); selectedFolderLabel->setDisabled(true); - folderSelectButton = new QPushButton("Choose..."); + folderSelectButton = new QToolButton(); - connect(folderSelectButton, &QPushButton::clicked, this, [&] { + connect(folderSelectButton, &QToolButton::clicked, this, [&] { auto dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), QCoreApplication::applicationDirPath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); selectedFolderLabel->setText(dir); diff --git a/src/frontend/Settings/GeneralSettings.hpp b/src/frontend/Settings/GeneralSettings.hpp index 5a22727..ac08550 100644 --- a/src/frontend/Settings/GeneralSettings.hpp +++ b/src/frontend/Settings/GeneralSettings.hpp @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include #include @@ -8,7 +8,7 @@ class GeneralSettings final : public QWidget { Q_OBJECT QLabel *description; - QPushButton *folderSelectButton; + QToolButton *folderSelectButton; QLabel *selectedFolderLabel; QVBoxLayout *v; QHBoxLayout *h; diff --git a/src/frontend/Settings/InputSettings.cpp b/src/frontend/Settings/InputSettings.cpp new file mode 100644 index 0000000..223b40c --- /dev/null +++ b/src/frontend/Settings/InputSettings.cpp @@ -0,0 +1,138 @@ +#include + +InputSettings::InputSettings() : settings(QSettings::UserScope) { + mapping[0] = settings.value("input/mapping/Z", Qt::Key_Z).value(); + mapping[1] = settings.value("input/mapping/A", Qt::Key_X).value(); + mapping[2] = settings.value("input/mapping/B", Qt::Key_C).value(); + mapping[3] = settings.value("input/mapping/L", Qt::Key_A).value(); + mapping[4] = settings.value("input/mapping/R", Qt::Key_S).value(); + mapping[5] = settings.value("input/mapping/S", Qt::Key_Return).value(); + mapping[6] = settings.value("input/mapping/DU", Qt::Key_I).value(); + mapping[7] = settings.value("input/mapping/DD", Qt::Key_K).value(); + mapping[8] = settings.value("input/mapping/DL", Qt::Key_J).value(); + mapping[9] = settings.value("input/mapping/DR", Qt::Key_L).value(); + mapping[10] = settings.value("input/mapping/CU", Qt::Key_T).value(); + mapping[11] = settings.value("input/mapping/CD", Qt::Key_G).value(); + mapping[12] = settings.value("input/mapping/CL", Qt::Key_F).value(); + mapping[13] = settings.value("input/mapping/CR", Qt::Key_H).value(); + mapping[14] = settings.value("input/mapping/AU", Qt::Key_Up).value(); + mapping[15] = settings.value("input/mapping/AD", Qt::Key_Down).value(); + mapping[16] = settings.value("input/mapping/AL", Qt::Key_Left).value(); + mapping[17] = settings.value("input/mapping/AR", Qt::Key_Right).value(); + + form = new QFormLayout(); + + form->addRow("Z:", btnZ); + form->addRow("A:", btnA); + form->addRow("B:", btnB); + form->addRow("L:", btnL); + form->addRow("R:", btnR); + form->addRow("Start:", btnS); + form->addRow("D-pad Up:", btnDU); + form->addRow("D-pad Down:", btnDD); + form->addRow("D-pad Left:", btnDL); + form->addRow("D-pad Right:", btnDR); + form->addRow("C-up:", btnCU); + form->addRow("C-down:", btnCD); + form->addRow("C-left:", btnCL); + form->addRow("C-right:", btnCR); + form->addRow("Up:", btnAU); + form->addRow("Down:", btnAD); + form->addRow("Left:", btnAL); + form->addRow("Right:", btnAR); + + connect(btnZ, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[0] = btnZ->keySequence(); + settings.setValue("input/mapping/Z", mapping[0]); + settings.sync(); + }); + connect(btnA, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[1] = btnA->keySequence(); + settings.setValue("input/mapping/A", mapping[1]); + settings.sync(); + }); + connect(btnB, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[2] = btnB->keySequence(); + settings.setValue("input/mapping/B", mapping[2]); + settings.sync(); + }); + connect(btnL, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[3] = btnL->keySequence(); + settings.setValue("input/mapping/L", mapping[3]); + settings.sync(); + }); + connect(btnR, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[4] = btnR->keySequence(); + settings.setValue("input/mapping/R", mapping[4]); + settings.sync(); + }); + connect(btnS, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[5] = btnS->keySequence(); + settings.setValue("input/mapping/S", mapping[5]); + settings.sync(); + }); + connect(btnDU, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[6] = btnDU->keySequence(); + settings.setValue("input/mapping/DU", mapping[6]); + settings.sync(); + }); + connect(btnDD, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[7] = btnDD->keySequence(); + settings.setValue("input/mapping/DD", mapping[7]); + settings.sync(); + }); + connect(btnDL, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[8] = btnDL->keySequence(); + settings.setValue("input/mapping/DL", mapping[8]); + settings.sync(); + }); + connect(btnDR, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[9] = btnDR->keySequence(); + settings.setValue("input/mapping/DR", mapping[9]); + settings.sync(); + }); + connect(btnCU, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[10] = btnCU->keySequence(); + settings.setValue("input/mapping/CU", mapping[10]); + settings.sync(); + }); + connect(btnCD, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[11] = btnCD->keySequence(); + settings.setValue("input/mapping/CD", mapping[11]); + settings.sync(); + }); + connect(btnCL, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[12] = btnCL->keySequence(); + settings.setValue("input/mapping/CL", mapping[12]); + settings.sync(); + }); + connect(btnCR, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[13] = btnCR->keySequence(); + settings.setValue("input/mapping/CR", mapping[13]); + settings.sync(); + }); + connect(btnAU, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[14] = btnAU->keySequence(); + settings.setValue("input/mapping/AU", mapping[14]); + settings.sync(); + }); + connect(btnAD, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[15] = btnAD->keySequence(); + settings.setValue("input/mapping/AD", mapping[15]); + settings.sync(); + }); + connect(btnAL, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[16] = btnAL->keySequence(); + settings.setValue("input/mapping/AL", mapping[16]); + settings.sync(); + }); + connect(btnAR, &QKeySequenceEdit::keySequenceChanged, this, [&] { + mapping[17] = btnAR->keySequence(); + settings.setValue("input/mapping/AR", mapping[17]); + settings.sync(); + }); + + v = new QVBoxLayout(this); + v->addLayout(form); + setLayout(v); +} diff --git a/src/frontend/Settings/InputSettings.hpp b/src/frontend/Settings/InputSettings.hpp new file mode 100644 index 0000000..b63482b --- /dev/null +++ b/src/frontend/Settings/InputSettings.hpp @@ -0,0 +1,42 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +class InputSettings final : public QWidget { + Q_OBJECT + QSettings settings; + QVBoxLayout *v; + QFormLayout *form; + QKeySequenceEdit *btnZ = new QKeySequenceEdit(Qt::Key_Z); + QKeySequenceEdit *btnA = new QKeySequenceEdit(Qt::Key_X); + QKeySequenceEdit *btnB = new QKeySequenceEdit(Qt::Key_C); + QKeySequenceEdit *btnL = new QKeySequenceEdit(Qt::Key_A); + QKeySequenceEdit *btnR = new QKeySequenceEdit(Qt::Key_S); + QKeySequenceEdit *btnS = new QKeySequenceEdit(Qt::Key_Return); + QKeySequenceEdit *btnDU = new QKeySequenceEdit(Qt::Key_T); + QKeySequenceEdit *btnDD = new QKeySequenceEdit(Qt::Key_G); + QKeySequenceEdit *btnDL = new QKeySequenceEdit(Qt::Key_F); + QKeySequenceEdit *btnDR = new QKeySequenceEdit(Qt::Key_H); + QKeySequenceEdit *btnCU = new QKeySequenceEdit(Qt::Key_I); + QKeySequenceEdit *btnCD = new QKeySequenceEdit(Qt::Key_K); + QKeySequenceEdit *btnCL = new QKeySequenceEdit(Qt::Key_J); + QKeySequenceEdit *btnCR = new QKeySequenceEdit(Qt::Key_L); + QKeySequenceEdit *btnAU = new QKeySequenceEdit(Qt::Key_Up); + QKeySequenceEdit *btnAD = new QKeySequenceEdit(Qt::Key_Down); + QKeySequenceEdit *btnAL = new QKeySequenceEdit(Qt::Key_Left); + QKeySequenceEdit *btnAR = new QKeySequenceEdit(Qt::Key_Right); + + public: + QList mapping = { + Qt::Key_Z, Qt::Key_X, Qt::Key_C, Qt::Key_A, Qt::Key_S, Qt::Key_Return, + Qt::Key_I, Qt::Key_K, Qt::Key_J, Qt::Key_L, Qt::Key_T, Qt::Key_G, + Qt::Key_F, Qt::Key_H, Qt::Key_Up, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right, + }; + explicit InputSettings(); +}; diff --git a/src/frontend/SettingsWindow.cpp b/src/frontend/SettingsWindow.cpp index e37bcf4..dbeef00 100644 --- a/src/frontend/SettingsWindow.cpp +++ b/src/frontend/SettingsWindow.cpp @@ -8,10 +8,12 @@ SettingsWindow::SettingsWindow() { general = new GeneralSettings(); cpu = new CPUSettings(); audio = new AudioSettings(); + input = new InputSettings(); categories = new QTabWidget(this); categories->addTab(general, "General"); categories->addTab(cpu, "MIPS VR4300i"); categories->addTab(audio, "Audio"); + categories->addTab(input, "Input"); v = new QVBoxLayout(this); v->addWidget(categories); diff --git a/src/frontend/SettingsWindow.hpp b/src/frontend/SettingsWindow.hpp index a26c52d..b0571a5 100644 --- a/src/frontend/SettingsWindow.hpp +++ b/src/frontend/SettingsWindow.hpp @@ -6,6 +6,7 @@ #include #include #include +#include class SettingsWindow final : public QWidget { Q_OBJECT @@ -13,6 +14,7 @@ class SettingsWindow final : public QWidget { GeneralSettings *general; AudioSettings *audio; CPUSettings *cpu; + InputSettings *input; QVBoxLayout *v; public: