From 226a87d92c8c881e0a17404a7c7aa3547b42c27c Mon Sep 17 00:00:00 2001 From: Sour Date: Sat, 6 Jul 2024 10:25:26 +0900 Subject: [PATCH] Input: Allow "pause" shortcut and gamepad shortcuts to work when a keyboard device is plugged in --- Core/Shared/Interfaces/IKeyManager.h | 3 +++ Core/Shared/ShortcutKeyHandler.cpp | 32 +++++++++++++++++----------- Core/Shared/ShortcutKeyHandler.h | 12 ++++++----- Linux/LinuxKeyManager.h | 3 --- MacOS/MacOSKeyManager.h | 3 --- Windows/WindowsKeyManager.cpp | 10 ++++----- Windows/WindowsKeyManager.h | 2 -- 7 files changed, 35 insertions(+), 30 deletions(-) diff --git a/Core/Shared/Interfaces/IKeyManager.h b/Core/Shared/Interfaces/IKeyManager.h index bc0f72f16..b6a9e019d 100644 --- a/Core/Shared/Interfaces/IKeyManager.h +++ b/Core/Shared/Interfaces/IKeyManager.h @@ -27,6 +27,9 @@ struct MouseMovement class IKeyManager { public: + static constexpr int BaseMouseButtonIndex = 0x200; + static constexpr int BaseGamepadIndex = 0x1000; + virtual ~IKeyManager() {} virtual void RefreshState() = 0; diff --git a/Core/Shared/ShortcutKeyHandler.cpp b/Core/Shared/ShortcutKeyHandler.cpp index e91b26e7d..601ab4828 100644 --- a/Core/Shared/ShortcutKeyHandler.cpp +++ b/Core/Shared/ShortcutKeyHandler.cpp @@ -20,6 +20,7 @@ ShortcutKeyHandler::ShortcutKeyHandler(Emulator* emu) _keySetIndex = 0; _isKeyUp = false; + _isKeyboardConnected = false; _repeatStarted = false; _needRepeat = false; @@ -40,20 +41,25 @@ ShortcutKeyHandler::~ShortcutKeyHandler() bool ShortcutKeyHandler::IsKeyPressed(EmulatorShortcut shortcut) { + //When running while a keyboard is plugged into the console, disable all keyboard + //shortcut keys. The pause shortcut is always enabled, allowing it to be used to + //pause normally, which allows other shortcuts to be used (while paused) + bool blockKeyboardKeys = shortcut != EmulatorShortcut::Pause && _isKeyboardConnected && !_isPaused; + KeyCombination keyComb = _emu->GetSettings()->GetShortcutKey(shortcut, _keySetIndex); vector supersets = _emu->GetSettings()->GetShortcutSupersets(shortcut, _keySetIndex); for(KeyCombination &superset : supersets) { - if(IsKeyPressed(superset)) { + if(IsKeyPressed(superset, blockKeyboardKeys)) { //A superset is pressed, ignore this subset return false; } } //No supersets are pressed, check if all matching keys are pressed - return IsKeyPressed(keyComb); + return IsKeyPressed(keyComb, blockKeyboardKeys); } -bool ShortcutKeyHandler::IsKeyPressed(KeyCombination comb) +bool ShortcutKeyHandler::IsKeyPressed(KeyCombination comb, bool blockKeyboardKeys) { int keyCount = (comb.Key1 ? 1 : 0) + (comb.Key2 ? 1 : 0) + (comb.Key3 ? 1 : 0); @@ -63,13 +69,17 @@ bool ShortcutKeyHandler::IsKeyPressed(KeyCombination comb) bool mergeCtrlAltShift = keyCount > 1; - return IsKeyPressed(comb.Key1, mergeCtrlAltShift) && - (comb.Key2 == 0 || IsKeyPressed(comb.Key2, mergeCtrlAltShift)) && - (comb.Key3 == 0 || IsKeyPressed(comb.Key3, mergeCtrlAltShift)); + return IsKeyPressed(comb.Key1, mergeCtrlAltShift, blockKeyboardKeys) && + (comb.Key2 == 0 || IsKeyPressed(comb.Key2, mergeCtrlAltShift, blockKeyboardKeys)) && + (comb.Key3 == 0 || IsKeyPressed(comb.Key3, mergeCtrlAltShift, blockKeyboardKeys)); } -bool ShortcutKeyHandler::IsKeyPressed(uint16_t keyCode, bool mergeCtrlAltShift) +bool ShortcutKeyHandler::IsKeyPressed(uint16_t keyCode, bool mergeCtrlAltShift, bool blockKeyboardKeys) { + if(blockKeyboardKeys && keyCode < IKeyManager::BaseMouseButtonIndex) { + return false; + } + if(keyCode >= 116 && keyCode <= 121 && mergeCtrlAltShift) { //Left/right ctrl/alt/shift //Return true if either the left or right key is pressed @@ -301,11 +311,6 @@ void ShortcutKeyHandler::ProcessShortcutReleased(EmulatorShortcut shortcut, uint void ShortcutKeyHandler::CheckMappedKeys() { - if(_emu->IsKeyboardConnected()) { - //Disable all shortcut keys if a keyboard is connected to the console - return; - } - for(uint64_t i = 0; i < (uint64_t)EmulatorShortcut::ShortcutCount; i++) { EmulatorShortcut shortcut = (EmulatorShortcut)i; if(DetectKeyPress(shortcut)) { @@ -333,6 +338,9 @@ void ShortcutKeyHandler::ProcessKeys() auto lock = _lock.AcquireSafe(); KeyManager::RefreshKeyState(); + _isKeyboardConnected = _emu->IsKeyboardConnected(); + _isPaused = _emu->IsPaused(); + _pressedKeys = KeyManager::GetPressedKeys(); _isKeyUp = _pressedKeys.size() < _lastPressedKeys.size(); diff --git a/Core/Shared/ShortcutKeyHandler.h b/Core/Shared/ShortcutKeyHandler.h index 0f4bff3a0..3a753fcad 100644 --- a/Core/Shared/ShortcutKeyHandler.h +++ b/Core/Shared/ShortcutKeyHandler.h @@ -10,16 +10,18 @@ class Emulator; class ShortcutKeyHandler final : public INotificationListener, public std::enable_shared_from_this { private: - Emulator* _emu; + Emulator* _emu = nullptr; thread _thread; atomic _stopThread; SimpleLock _lock; - int _keySetIndex; + int _keySetIndex = 0; vector _pressedKeys; vector _lastPressedKeys; - bool _isKeyUp; + bool _isKeyUp = false; + bool _isKeyboardConnected = false; + bool _isPaused = false; Timer _runSingleFrameRepeatTimer; atomic _repeatStarted; @@ -31,8 +33,8 @@ class ShortcutKeyHandler final : public INotificationListener, public std::enabl void CheckMappedKeys(); bool IsKeyPressed(EmulatorShortcut key); - bool IsKeyPressed(KeyCombination comb); - bool IsKeyPressed(uint16_t keyCode, bool mergeCtrlAltShift); + bool IsKeyPressed(KeyCombination comb, bool blockKeyboardKeys); + bool IsKeyPressed(uint16_t keyCode, bool mergeCtrlAltShift, bool blockKeyboardKeys); bool DetectKeyPress(EmulatorShortcut key); bool DetectKeyRelease(EmulatorShortcut key); diff --git a/Linux/LinuxKeyManager.h b/Linux/LinuxKeyManager.h index 753dd422e..cd80430dd 100644 --- a/Linux/LinuxKeyManager.h +++ b/Linux/LinuxKeyManager.h @@ -12,9 +12,6 @@ class Emulator; class LinuxKeyManager : public IKeyManager { private: - static constexpr int BaseMouseButtonIndex = 0x200; - static constexpr int BaseGamepadIndex = 0x1000; - Emulator* _emu; std::vector> _controllers; diff --git a/MacOS/MacOSKeyManager.h b/MacOS/MacOSKeyManager.h index 0dfc31f3e..9486d045d 100644 --- a/MacOS/MacOSKeyManager.h +++ b/MacOS/MacOSKeyManager.h @@ -9,9 +9,6 @@ class Emulator; class MacOSKeyManager : public IKeyManager { private: - static constexpr int BaseMouseButtonIndex = 0x200; - static constexpr int BaseGamepadIndex = 0x1000; - Emulator* _emu; vector _keyDefinitions; diff --git a/Windows/WindowsKeyManager.cpp b/Windows/WindowsKeyManager.cpp index f3b3be9c9..1099365bf 100644 --- a/Windows/WindowsKeyManager.cpp +++ b/Windows/WindowsKeyManager.cpp @@ -15,7 +15,7 @@ WindowsKeyManager::WindowsKeyManager(Emulator* emu, HWND hWnd) vector buttonNames = { "Up", "Down", "Left", "Right", "Start", "Back", "L3", "R3", "L1", "R1", "?", "?", "A", "B", "X", "Y", "L2", "R2", "RT Up", "RT Down", "RT Left", "RT Right", "LT Up", "LT Down", "LT Left", "LT Right" }; for(int i = 0; i < 4; i++) { for(int j = 0; j < (int)buttonNames.size(); j++) { - _keyDefinitions.push_back({ "Pad" + std::to_string(i + 1) + " " + buttonNames[j], (uint32_t)(WindowsKeyManager::BaseXInputIndex + i * 0x100 + j + 1) }); + _keyDefinitions.push_back({ "Pad" + std::to_string(i + 1) + " " + buttonNames[j], (uint32_t)(WindowsKeyManager::BaseGamepadIndex + i * 0x100 + j + 1) }); } } @@ -79,7 +79,7 @@ bool WindowsKeyManager::IsKeyPressed(uint16_t key) return false; } - if(key >= WindowsKeyManager::BaseXInputIndex) { + if(key >= WindowsKeyManager::BaseGamepadIndex) { if(!_xInput || !_directInput) { return false; } @@ -91,8 +91,8 @@ bool WindowsKeyManager::IsKeyPressed(uint16_t key) return _directInput->IsPressed(gamepadPort, gamepadButton); } else { //XInput key - uint8_t gamepadPort = (key - WindowsKeyManager::BaseXInputIndex) / 0x100; - uint8_t gamepadButton = (key - WindowsKeyManager::BaseXInputIndex) % 0x100; + uint8_t gamepadPort = (key - WindowsKeyManager::BaseGamepadIndex) / 0x100; + uint8_t gamepadButton = (key - WindowsKeyManager::BaseGamepadIndex) % 0x100; return _xInput->IsPressed(gamepadPort, gamepadButton); } } else if(key < 0x205) { @@ -117,7 +117,7 @@ vector WindowsKeyManager::GetPressedKeys() for(int i = 0; i < XUSER_MAX_COUNT; i++) { for(int j = 1; j <= 26; j++) { if(_xInput->IsPressed(i, j)) { - result.push_back(WindowsKeyManager::BaseXInputIndex + i * 0x100 + j); + result.push_back(WindowsKeyManager::BaseGamepadIndex + i * 0x100 + j); } } } diff --git a/Windows/WindowsKeyManager.h b/Windows/WindowsKeyManager.h index 79ab982d2..b891f570e 100644 --- a/Windows/WindowsKeyManager.h +++ b/Windows/WindowsKeyManager.h @@ -13,8 +13,6 @@ class Emulator; class WindowsKeyManager : public IKeyManager { private: - static constexpr int BaseMouseButtonIndex = 0x200; - static constexpr int BaseXInputIndex = 0x1000; static constexpr int BaseDirectInputIndex = 0x2000; HWND _hWnd;