Phase 1a: per-slot poll viz + input-path diagnostics

Surfaced by a game (Life is Strange: Before the Storm) that ignores
controller input when it lacks true OS focus even though it still polls
XInput. To find the focus-gated detection path, instrument the hook.

Protocol v3 status back-channel now reports:
- per-slot XInputGetState and XInputGetCapabilities counters (replacing the
  single aggregate), so the overlay shows exactly which slots the game polls
  and how fast;
- focus-API call counts (GetForegroundWindow/GetActiveWindow/GetFocus) to see
  whether the game consults the APIs we spoof;
- input-path diagnostics: whether the process registered Raw Input for a
  gamepad usage and whether it set RIDEV_INPUTSINK (background delivery), and
  whether a DirectInput dll is loaded.

Host overlay gains a per-slot poll table and an "Input path" section. The DLL
refreshes input diagnostics each worker tick via GetRegisteredRawInputDevices.
hook_selftest updated for per-slot counters; passes.

This is diagnostic-only: once a real run shows which path LiS uses, the
targeted focus fix (e.g. forcing RIDEV_INPUTSINK or DI background coop) follows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-19 00:38:07 +02:00
parent df4325d21b
commit a0a12d69fe
11 changed files with 210 additions and 36 deletions

View File

@@ -41,10 +41,10 @@ private:
bool test_input_ = false;
// Sampled to turn the hook's cumulative query counter into a poll rate.
unsigned long long last_query_count_ = 0;
// Sampled to turn the hook's cumulative per-slot counters into poll rates.
unsigned long long last_state_count_[kMaxPads] = {};
double state_rate_[kMaxPads] = {};
double last_sample_time_ = 0.0;
double query_rate_ = 0.0;
};
} // namespace coop