diff --git a/core/keypad.c b/core/keypad.c index c63c605fe..260e79d29 100644 --- a/core/keypad.c +++ b/core/keypad.c @@ -20,10 +20,15 @@ keypad_state_t keypad; typedef struct keypad_atomics { _Atomic(uint16_t) keyMap[KEYPAD_ACTUAL_ROWS]; _Atomic(uint8_t) onKey; + _Atomic(bool) ghosting; } keypad_atomics_t; static keypad_atomics_t keypad_atomics; +void emu_set_keypad_ghosting(int enable) { + keypad_atomics.ghosting = enable; +} + static inline void keypad_intrpt_check() { intrpt_set(INT_KEYPAD, keypad.status & keypad.enable); } @@ -134,7 +139,8 @@ void keypad_any_check(void) { } uint16_t dataMask = keypad_data_mask(); /* if not all rows were queried, ghosting is possible */ - if (unlikely(queryMask != (1 << KEYPAD_ACTUAL_ROWS) - 1)) { + if (unlikely(queryMask != (1 << KEYPAD_ACTUAL_ROWS) - 1) && + atomic_load_explicit(&keypad_atomics.ghosting, memory_order_relaxed)) { /* if at least one key was pressed and not every data bit is filled, ghosting is possible */ if (any != 0 && (any & dataMask) != dataMask) { any = keypad_handle_ghosting(any, queryMask); @@ -229,7 +235,8 @@ static void keypad_scan_event(enum sched_item_id id) { data = keypad_query_keymap(row); uint16_t dataMask = keypad_data_mask(); /* if at least one key was pressed and not every data bit is filled, ghosting is possible */ - if (data != 0 && (data & dataMask) != dataMask) { + if (atomic_load_explicit(&keypad_atomics.ghosting, memory_order_relaxed) && + data != 0 && (data & dataMask) != dataMask) { data = keypad_handle_ghosting(data, 1 << row); } data &= dataMask; diff --git a/core/keypad.h b/core/keypad.h index b610a4b03..b9d678f0f 100644 --- a/core/keypad.h +++ b/core/keypad.h @@ -56,6 +56,7 @@ bool keypad_save(FILE *image); /* api functions */ void emu_keypad_event(unsigned int row, unsigned int col, bool press); +void emu_set_keypad_ghosting(int enable); #ifdef __cplusplus } diff --git a/gui/qt/mainwindow.cpp b/gui/qt/mainwindow.cpp index f03a743eb..a970207fc 100644 --- a/gui/qt/mainwindow.cpp +++ b/gui/qt/mainwindow.cpp @@ -382,6 +382,7 @@ MainWindow::MainWindow(CEmuOpts &cliOpts, QWidget *p) : QMainWindow(p), ui(new U connect(ui->checkSkin, &QCheckBox::stateChanged, this, &MainWindow::setSkinToggle); connect(ui->comboBoxAsicRev, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::setAsicRevision); connect(ui->checkPythonEdition, &QCheckBox::stateChanged, this, &MainWindow::setPythonEdition); + connect(ui->checkKeypadGhosting, &QCheckBox::stateChanged, this, &MainWindow::setKeypadGhosting); connect(ui->checkDma, &QCheckBox::toggled, this, &MainWindow::setLcdDma); connect(ui->checkGamma, &QCheckBox::toggled, this, &MainWindow::setLcdGamma); connect(ui->checkResponse, &QCheckBox::toggled, this, &MainWindow::setLcdResponse); @@ -592,6 +593,7 @@ MainWindow::MainWindow(CEmuOpts &cliOpts, QWidget *p) : QMainWindow(p), ui(new U setLcdGamma(m_config->value(SETTING_SCREEN_GAMMA, true).toBool()); setLcdResponse(m_config->value(SETTING_SCREEN_RESPONSE, true).toBool()); setGuiSkip(m_config->value(SETTING_SCREEN_FRAMESKIP, 0).toInt()); + setKeypadGhosting(m_config->value(SETTING_KEYPAD_GHOSTING, true).toBool()); setKeypadHolding(m_config->value(SETTING_KEYPAD_HOLDING, true).toBool()); setEmuSpeed(m_config->value(SETTING_EMUSPEED, 100).toInt()); ui->checkSaveRestore->setChecked(m_config->value(SETTING_SAVE_ON_CLOSE, true).toBool()); diff --git a/gui/qt/mainwindow.h b/gui/qt/mainwindow.h index 9b6794968..92e07b94c 100644 --- a/gui/qt/mainwindow.h +++ b/gui/qt/mainwindow.h @@ -401,6 +401,7 @@ class MainWindow : public QMainWindow { void keypadChanged(); void setKeymap(const QString &value); void setKeypadColor(unsigned int color); + void setKeypadGhosting(bool enabled); void setKeypadHolding(bool enabled); void setCalcSkinTopFromType(bool python); @@ -750,6 +751,7 @@ class MainWindow : public QMainWindow { static const QString SETTING_SCREEN_RESPONSE; static const QString SETTING_KEYPAD_KEYMAP; static const QString SETTING_KEYPAD_COLOR; + static const QString SETTING_KEYPAD_GHOSTING; static const QString SETTING_KEYPAD_HOLDING; static const QString SETTING_WINDOW_FULLSCREEN; static const QString SETTING_WINDOW_GROUP_DRAG; diff --git a/gui/qt/mainwindow.ui b/gui/qt/mainwindow.ui index 643064106..3ab73f312 100644 --- a/gui/qt/mainwindow.ui +++ b/gui/qt/mainwindow.ui @@ -9607,14 +9607,38 @@ QPushButton:pressed { - - - Emulate Python Edition - - - true - - + + + + + Emulate Python Edition + + + true + + + + + + + Emulate keypad ghosting + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + diff --git a/gui/qt/settings.cpp b/gui/qt/settings.cpp index 646a33b06..76786600b 100644 --- a/gui/qt/settings.cpp +++ b/gui/qt/settings.cpp @@ -7,6 +7,7 @@ #include "../../core/cpu.h" #include "../../core/emu.h" +#include "../../core/keypad.h" #include "../../core/debug/debug.h" #include @@ -65,6 +66,7 @@ const QString MainWindow::SETTING_SCREEN_RESPONSE = QStringLiteral("Sc const QString MainWindow::SETTING_KEYPAD_KEYMAP = QStringLiteral("Keypad/map"); const QString MainWindow::SETTING_KEYPAD_COLOR = QStringLiteral("Keypad/color"); const QString MainWindow::SETTING_KEYPAD_CUSTOM_PATH = QStringLiteral("Keypad/custom_path"); +const QString MainWindow::SETTING_KEYPAD_GHOSTING = QStringLiteral("Keypad/ghosting"); const QString MainWindow::SETTING_KEYPAD_HOLDING = QStringLiteral("Keypad/holding"); const QString MainWindow::SETTING_WINDOW_GROUP_DRAG = QStringLiteral("Window/group_dock_drag"); const QString MainWindow::SETTING_WINDOW_FULLSCREEN = QStringLiteral("Window/fullscreen"); @@ -495,6 +497,12 @@ void MainWindow::setKeypadColor(unsigned int color) { m_config->setValue(SETTING_KEYPAD_COLOR, color); } +void MainWindow::setKeypadGhosting(bool state) { + ui->checkKeypadGhosting->setChecked(state); + emu_set_keypad_ghosting(state); + m_config->setValue(SETTING_KEYPAD_GHOSTING, state); +} + void MainWindow::setKeypadHolding(bool enabled) { ui->keypadWidget->setHolding(enabled); m_config->setValue(SETTING_KEYPAD_HOLDING, enabled);