Merge pull request #21842 from hrydgard/input-refactoring

Some minor refactoring of input code
This commit is contained in:
Henrik Rydgård
2026-06-16 11:37:56 +02:00
committed by GitHub
12 changed files with 128 additions and 108 deletions
-42
View File
@@ -130,52 +130,10 @@ bool UIScreen::UnsyncKey(const KeyInput &key) {
}
}
// Track modifier keys.
if (key.flags & KeyInputFlags::DOWN) {
switch (key.keyCode) {
case NKCODE_CTRL_LEFT: modifiersPressed_ |= Modifier::LCTRL; break;
case NKCODE_CTRL_RIGHT: modifiersPressed_ |= Modifier::RCTRL; break;
case NKCODE_SHIFT_LEFT: modifiersPressed_ |= Modifier::LSHIFT; break;
case NKCODE_SHIFT_RIGHT: modifiersPressed_ |= Modifier::RSHIFT; break;
case NKCODE_ALT_LEFT: modifiersPressed_ |= Modifier::LALT; break;
case NKCODE_ALT_RIGHT: modifiersPressed_ |= Modifier::RALT; break;
case NKCODE_META_LEFT: modifiersPressed_ |= Modifier::LMETA; break;
case NKCODE_META_RIGHT: modifiersPressed_ |= Modifier::RMETA; break;
default:
break;
}
}
if (key.flags & KeyInputFlags::UP) {
switch (key.keyCode) {
case NKCODE_CTRL_LEFT: modifiersPressed_ &= ~Modifier::LCTRL; break;
case NKCODE_CTRL_RIGHT: modifiersPressed_ &= ~Modifier::RCTRL; break;
case NKCODE_SHIFT_LEFT: modifiersPressed_ &= ~Modifier::LSHIFT; break;
case NKCODE_SHIFT_RIGHT: modifiersPressed_ &= ~Modifier::RSHIFT; break;
case NKCODE_ALT_LEFT: modifiersPressed_ &= ~Modifier::LALT; break;
case NKCODE_ALT_RIGHT: modifiersPressed_ &= ~Modifier::RALT; break;
case NKCODE_META_LEFT: modifiersPressed_ &= ~Modifier::LMETA; break;
case NKCODE_META_RIGHT: modifiersPressed_ &= ~Modifier::RMETA; break;
default:
break;
}
}
QueuedEvent ev{};
ev.type = QueuedEventType::KEY;
ev.key = key;
if (modifiersPressed_ & (Modifier::LCTRL | Modifier::RCTRL)) {
ev.key.flags |= KeyInputFlags::MOD_CTRL;
}
if (modifiersPressed_ & (Modifier::LSHIFT | Modifier::RSHIFT)) {
ev.key.flags |= KeyInputFlags::MOD_SHIFT;
}
if (modifiersPressed_ & (Modifier::LALT | Modifier::RALT)) {
ev.key.flags |= KeyInputFlags::MOD_ALT;
}
if (modifiersPressed_ & (Modifier::LMETA | Modifier::RMETA)) {
ev.key.flags |= KeyInputFlags::MOD_META;
}
std::lock_guard<std::mutex> guard(eventQueueLock_);
eventQueue_.push_back(ev);
return retval;
+2 -16
View File
@@ -32,19 +32,6 @@ struct QueuedEvent {
};
};
enum class Modifier {
NONE = 0,
LCTRL = 1,
RCTRL = 2,
LSHIFT = 4,
RSHIFT = 8,
LALT = 16,
RALT = 32,
LMETA = 64,
RMETA = 128,
};
ENUM_CLASS_BITOPS(Modifier);
class UIScreen : public Screen {
public:
UIScreen();
@@ -76,9 +63,10 @@ public:
virtual void focusChanged(ScreenFocusChange focusChange) override {
Screen::focusChanged(focusChange);
modifiersPressed_ = Modifier::NONE;
}
virtual bool AllowKeyboardNavigation() const { return true; }
protected:
virtual void CreateViews() = 0;
@@ -108,8 +96,6 @@ protected:
private:
std::mutex eventQueueLock_;
std::deque<QueuedEvent> eventQueue_;
Modifier modifiersPressed_{};
};
class UIDialogScreen : public UIScreen {
+3 -3
View File
@@ -303,7 +303,7 @@ void ControlMapper::ReleaseAll() {
Axis(axes.data(), axes.size());;
for (const auto &key : keys) {
Key(key, nullptr);
Key(key);
}
}
@@ -586,7 +586,7 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping, double no
return keyInputUsed;
}
bool ControlMapper::Key(const KeyInput &key, bool *pauseTrigger) {
bool ControlMapper::Key(const KeyInput &key) {
double now = time_now_d();
InputMapping mapping(key.deviceId, key.keyCode);
@@ -607,7 +607,7 @@ bool ControlMapper::Key(const KeyInput &key, bool *pauseTrigger) {
bool mappingFound = KeyMap::InputMappingToPspButton(mapping, nullptr);
DEBUG_LOG(Log::System, "Key: %d DeviceId: %d", key.keyCode, key.deviceId);
if (!mappingFound || key.deviceId == DEVICE_ID_DEFAULT) {
*pauseTrigger = true;
pauseTrigger_ = true;
return true;
}
}
+13 -6
View File
@@ -1,13 +1,14 @@
#pragma once
#include <cstring>
#include <atomic>
#include <functional>
#include <mutex>
#include <vector>
#include "Common/Input/InputState.h"
#include "Core/KeyMap.h"
#include <functional>
#include <cstring>
#include <mutex>
#include <vector>
struct DisplayLayoutConfig;
// Pure interface.
@@ -32,7 +33,7 @@ public:
// Inputs to the table-based mapping
// These functions are free-threaded.
bool Key(const KeyInput &key, bool *pauseTrigger);
bool Key(const KeyInput &key);
void Axis(const AxisInput *axes, size_t count);
// Required callbacks.
@@ -60,6 +61,10 @@ public:
void GetDebugString(StringWriter &w) const;
bool PollPauseTrigger() {
return pauseTrigger_.exchange(false);
}
struct InputSample {
float value;
double timestamp;
@@ -107,6 +112,8 @@ private:
bool autoRotatingAnalogCW_ = false;
bool autoRotatingAnalogCCW_ = false;
std::atomic<bool> pauseTrigger_{};
bool swapAxes_ = false;
int iInternalScreenRotationCached_ = 0;
+1 -1
View File
@@ -1784,7 +1784,7 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle
getLocalMac(&localmac);
// Clear Memory
memset(context, 0, sizeof(SceNetAdhocMatchingContext));
context = {};
// Allocate Receive Buffer
context->rxbuf = (uint8_t*)malloc(rxbuflen);
+3
View File
@@ -1448,6 +1448,9 @@ int main(int argc, char *argv[]) {
#endif
putenv((char*)"SDL_VIDEO_CENTERED=1");
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
#ifdef SDL_HINT_ENABLE_SCREEN_KEYBOARD
SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "0");
#endif
#ifdef SDL_HINT_TOUCH_MOUSE_EVENTS
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
+1 -2
View File
@@ -518,8 +518,7 @@ bool AnalogCalibrationScreen::key(const KeyInput &key) {
bool retval = UIScreen::key(key);
// Allow testing auto-rotation. If it collides with UI keys, too bad.
bool pauseTrigger = false;
g_controlMapper.Key(key, &pauseTrigger);
g_controlMapper.Key(key);
if (UI::IsEscapeKey(key)) {
TriggerFinish(DR_BACK);
+32 -31
View File
@@ -730,31 +730,6 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) {
}
}
bool EmuScreen::UnsyncTouch(const TouchInput &touch) {
System_Notify(SystemNotification::ACTIVITY);
bool ignoreGamepad = false;
if (chatMenu_ && chatMenu_->GetVisibility() == UI::V_VISIBLE) {
// Avoid pressing touch button behind the chat
if (chatMenu_->Contains(touch.x, touch.y)) {
ignoreGamepad = true;
}
}
if (touch.flags & TouchInputFlags::DOWN) {
if (!(g_Config.bShowImDebugger && imguiInited_) && !ignoreGamepad) {
// This just prevents the gamepad from timing out.
GamepadTouch();
}
}
if (root_) {
UIScreen::UnsyncTouch(touch);
}
return true;
}
// TODO: We should replace the "fpsLimit" system with a speed factor.
static void ShowFpsLimitNotice() {
int fpsLimit = 60;
@@ -1159,6 +1134,10 @@ void EmuScreen::OnVKeyAnalog(VirtKey virtualKeyCode, float value) {
limitMode = PSP_CoreParameter().analogFpsLimit == 60 ? FPSLimit::NORMAL : FPSLimit::ANALOG;
}
bool EmuScreen::AllowKeyboardNavigation() const {
return true;
}
bool EmuScreen::UnsyncKey(const KeyInput &key) {
System_Notify(SystemNotification::ACTIVITY);
@@ -1189,7 +1168,7 @@ bool EmuScreen::UnsyncKey(const KeyInput &key) {
if (mappingFound) {
for (auto b : pspButtons) {
if (b == VIRTKEY_TOGGLE_DEBUGGER || b == VIRTKEY_PAUSE) {
return g_controlMapper.Key(key, &pauseTrigger_);
return g_controlMapper.Key(key);
}
}
}
@@ -1199,28 +1178,28 @@ bool EmuScreen::UnsyncKey(const KeyInput &key) {
switch (key.deviceId) {
case DEVICE_ID_KEYBOARD:
if (!ImGui::GetIO().WantCaptureKeyboard) {
g_controlMapper.Key(key, &pauseTrigger_);
g_controlMapper.Key(key);
}
break;
case DEVICE_ID_MOUSE:
if (!ImGui::GetIO().WantCaptureMouse) {
g_controlMapper.Key(key, &pauseTrigger_);
g_controlMapper.Key(key);
}
break;
default:
g_controlMapper.Key(key, &pauseTrigger_);
g_controlMapper.Key(key);
break;
}
} else {
// Let up-events through to the controlMapper_ so input doesn't get stuck.
if (key.flags & KeyInputFlags::UP) {
g_controlMapper.Key(key, &pauseTrigger_);
g_controlMapper.Key(key);
}
}
return UIScreen::UnsyncKey(key);
}
return g_controlMapper.Key(key, &pauseTrigger_);
return g_controlMapper.Key(key);
}
void EmuScreen::UnsyncAxis(const AxisInput *axes, size_t count) {
@@ -1253,6 +1232,24 @@ bool EmuScreen::key(const KeyInput &key) {
}
void EmuScreen::touch(const TouchInput &touch) {
System_Notify(SystemNotification::ACTIVITY);
bool ignoreGamepad = false;
if (chatMenu_ && chatMenu_->GetVisibility() == UI::V_VISIBLE) {
// Avoid pressing touch button behind the chat
if (chatMenu_->Contains(touch.x, touch.y)) {
ignoreGamepad = true;
}
}
if (touch.flags & TouchInputFlags::DOWN) {
if (!(g_Config.bShowImDebugger && imguiInited_) && !ignoreGamepad) {
// This just prevents the gamepad from timing out.
GamepadTouch();
}
}
if (g_Config.bShowImDebugger && imguiInited_) {
ImGui_ImplPlatform_TouchEvent(touch);
if (!ImGui::GetIO().WantCaptureMouse) {
@@ -1525,6 +1522,10 @@ void EmuScreen::update() {
return;
}
if (g_controlMapper.PollPauseTrigger()) {
pauseTrigger_ = true;
}
if (pauseTrigger_) {
pauseTrigger_ = false;
screenManager()->push(new GamePauseScreen(gamePath_, bootPending_));
+3 -1
View File
@@ -54,7 +54,6 @@ public:
// Note: Unlike your average boring UIScreen, here we override the Unsync* functions
// to get minimal latency and full control. We forward to UIScreen when needed.
bool UnsyncTouch(const TouchInput &touch) override;
bool UnsyncKey(const KeyInput &key) override;
void UnsyncAxis(const AxisInput *axes, size_t count) override;
@@ -70,6 +69,8 @@ public:
}
protected:
bool AllowKeyboardNavigation() const override;
void darken();
void focusChanged(ScreenFocusChange focusChange) override;
ScreenRenderFlags PreRender(ScreenRenderMode mode) override;
@@ -114,6 +115,7 @@ private:
std::string errorMessage_;
// If set, pauses at the end of the frame.
// We also poll the pause trigger from the ControlMapper. That needs refactoring.
bool pauseTrigger_ = false;
// The last read chat message count, and how many new ones there are.
+66 -1
View File
@@ -1369,6 +1369,20 @@ static void ProcessWheelRelease(InputKeyCode keyCode, double now, bool keyPress)
}
}
enum class Modifier {
NONE = 0,
LCTRL = 1,
RCTRL = 2,
LSHIFT = 4,
RSHIFT = 8,
LALT = 16,
RALT = 32,
LMETA = 64,
RMETA = 128,
};
ENUM_CLASS_BITOPS(Modifier);
static Modifier g_modifiersPressed{};
bool NativeKey(const KeyInput &key) {
double now = time_now_d();
@@ -1429,8 +1443,59 @@ bool NativeKey(const KeyInput &key) {
}
HLEPlugins::SetKey(key.keyCode, (key.flags & KeyInputFlags::DOWN) ? 1 : 0);
// Track and update modifiers.
// Track modifier keys.
if (key.flags & KeyInputFlags::DOWN) {
switch (key.keyCode) {
case NKCODE_CTRL_LEFT: g_modifiersPressed |= Modifier::LCTRL; break;
case NKCODE_CTRL_RIGHT: g_modifiersPressed |= Modifier::RCTRL; break;
case NKCODE_SHIFT_LEFT: g_modifiersPressed |= Modifier::LSHIFT; break;
case NKCODE_SHIFT_RIGHT: g_modifiersPressed |= Modifier::RSHIFT; break;
case NKCODE_ALT_LEFT: g_modifiersPressed |= Modifier::LALT; break;
case NKCODE_ALT_RIGHT: g_modifiersPressed |= Modifier::RALT; break;
case NKCODE_META_LEFT: g_modifiersPressed |= Modifier::LMETA; break;
case NKCODE_META_RIGHT: g_modifiersPressed |= Modifier::RMETA; break;
default:
break;
}
}
if (key.flags & KeyInputFlags::UP) {
switch (key.keyCode) {
case NKCODE_CTRL_LEFT: g_modifiersPressed &= ~Modifier::LCTRL; break;
case NKCODE_CTRL_RIGHT: g_modifiersPressed &= ~Modifier::RCTRL; break;
case NKCODE_SHIFT_LEFT: g_modifiersPressed &= ~Modifier::LSHIFT; break;
case NKCODE_SHIFT_RIGHT: g_modifiersPressed &= ~Modifier::RSHIFT; break;
case NKCODE_ALT_LEFT: g_modifiersPressed &= ~Modifier::LALT; break;
case NKCODE_ALT_RIGHT: g_modifiersPressed &= ~Modifier::RALT; break;
case NKCODE_META_LEFT: g_modifiersPressed &= ~Modifier::LMETA; break;
case NKCODE_META_RIGHT: g_modifiersPressed &= ~Modifier::RMETA; break;
default:
break;
}
}
KeyInputFlags modifierFlags{};
if (g_modifiersPressed & (Modifier::LCTRL | Modifier::RCTRL)) {
modifierFlags |= KeyInputFlags::MOD_CTRL;
}
if (g_modifiersPressed & (Modifier::LSHIFT | Modifier::RSHIFT)) {
modifierFlags |= KeyInputFlags::MOD_SHIFT;
}
if (g_modifiersPressed & (Modifier::LALT | Modifier::RALT)) {
modifierFlags |= KeyInputFlags::MOD_ALT;
}
if (g_modifiersPressed & (Modifier::LMETA | Modifier::RMETA)) {
modifierFlags |= KeyInputFlags::MOD_META;
}
KeyInput modKey = key;
modKey.flags |= modifierFlags;
// Dispatch the key event.
bool retval = g_screenManager->key(key);
bool retval = g_screenManager->key(modKey);
// The Mode key can have weird consequences on some devices, see #17245.
if (key.keyCode == NKCODE_BUTTON_MODE) {
+2 -3
View File
@@ -378,9 +378,8 @@ GamePauseScreen::~GamePauseScreen() {
bool GamePauseScreen::UnsyncKey(const KeyInput &key) {
bool retval = UIScreen::UnsyncKey(key);
bool pauseTrigger = false;
retval = g_controlMapper.Key(key, &pauseTrigger) || retval;
if (pauseTrigger) {
retval = g_controlMapper.Key(key) || retval;
if (g_controlMapper.PollPauseTrigger()) {
TriggerFinish(DR_BACK);
}
return retval;
+2 -2
View File
@@ -38,7 +38,7 @@ bool TestLoongArch64Emitter(){
cpu_info.LOONGARCH_LBT_MIPS = true;
cpu_info.LOONGARCH_PTW = true;
u32 code[1024];
u32 code[1024]{};
LoongArch64Emitter emitter((u8 *)code, (u8 *)code);
emitter.ADD_W(R12, R13, R14); // t0, t1, t2
@@ -77,4 +77,4 @@ bool TestLoongArch64Emitter(){
}
return true;
}
}