[RE] Say so when a guest keystroke is swallowed by IsUIActive
XamInputGetKeystrokeEx returns X_ERROR_SUCCESS with a zeroed keystroke whenever any Xenia dialog is up, before consulting a driver. That is correct behaviour and an invisible one: from outside, scripted input simply stops working, the pad driver logs nothing because it is never asked, and the guest keeps polling. It is easy to enter that state by accident — F10 is both the RE capture hotkey and the toolkit's menu-bar key, and a dialog closed by its own [x] rather than by the menu toggle leaves the counter incremented. So log it, rate-limited to one line per 600 swallowed calls, with the dialog counters. On the runs this was written to diagnose it stays silent, which is what ruled the theory out — a diagnostic that is useful when it does not fire.
This commit is contained in:
@@ -193,6 +193,21 @@ dword_result_t XamInputGetKeystrokeEx_entry(
|
||||
keystroke.Zero();
|
||||
|
||||
if (kernel_state()->xam_state()->IsUIActive()) {
|
||||
// RE aid: this early return hands the guest a SUCCESS with an empty
|
||||
// keystroke without ever asking a driver, so scripted input goes silently
|
||||
// dead for as long as any Xenia UI is up — including a dialog that was
|
||||
// closed by its own [x] rather than by the menu toggle that decrements the
|
||||
// counter. An invisible input blackout is expensive to diagnose from the
|
||||
// outside; say so, rarely enough not to spam.
|
||||
static std::atomic<uint32_t> swallowed{0};
|
||||
const uint32_t n = swallowed.fetch_add(1, std::memory_order_relaxed);
|
||||
if ((n % 600) == 0) {
|
||||
XELOGW(
|
||||
"[RE-INPUT] XamInputGetKeystrokeEx swallowed by IsUIActive "
|
||||
"(dialogs={} nui={}, {} so far)",
|
||||
kernel_state()->xam_state()->xam_dialogs_shown_.load(),
|
||||
kernel_state()->xam_state()->xam_nui_dialogs_shown_.load(), n + 1);
|
||||
}
|
||||
return X_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user