docs/re: my own flag hypothesis fails its test, and the input path is mapped

With the capture cvar gone from the launch line entirely, a fresh run reached the
boot title and (A) still did nothing. The flag is therefore not necessary for the
failure, and 0-of-7-with vs 4-of-6-without does not survive as an explanation.

The conclusion is the plain one: (A) at the title succeeds about half the time
and nothing measurable from outside predicts which. Five candidates are now
eliminated — Xenia UI swallowing the keystroke, the driver filter, a sign-in or
content call on the press, the age of the title, and the capture cvar.

So the guest side was traced instead. XamInputGetKeystrokeEx has exactly one
caller in the title, and that has one caller: entry_point -> main loop
(sub_8216EA68) -> per-frame input update (sub_822F1AA8) -> the pad poll
(sub_82457038). The poller's layout is readable and matches the runtime trace
(keystroke queue at +68/+72 drained with flags=3; current state at +36 compared
field-by-field against the previous at +52), and nothing in it is state-gated.
Whatever ignores (A) is a consumer further up — a real RE job, and that is where
the thread now stands, stated rather than guessed at again.
This commit is contained in:
Sylpheed RE agent
2026-08-19 00:47:53 +00:00
parent 6b26087bea
commit 2483b7c3c9
2 changed files with 55 additions and 3 deletions

View File

@@ -176,9 +176,14 @@ main menu has been reached (screenshot in
successes without `--log_ui_draws`, 0 of 7 with it. An interleaved series
**refuted the boot-time confound** (the latest title of all, 268 s, accepted Ⓐ;
a 232 s title refused), and no mechanism exists for the flag — it is read only
when F10 arms a capture, and F10 was never pressed. The variable has been removed
rather than believed: F10 now arms the capture unconditionally, so navigation
runs need no flag. Until that
when F10 arms a capture, and F10 was never pressed. The variable was removed rather than
believed F10 now arms the capture unconditionally — and with it gone a fresh
run **still** failed, so the flag is not the cause either. Net: Ⓐ succeeds about
half the time and nothing measurable predicts which; five explanations are
eliminated. The input path is now mapped statically (`entry_point`
`sub_8216EA68` main loop → `sub_822F1AA8` per-frame input → `sub_82457038` pad
poll → `XamInputGetKeystrokeEx`), and the poll itself is not state-gated, so the
gate is in a consumer further up. Until that
is separated, capturing a screen *and* navigating to it in the same run is not
dependable. The earlier claim, kept: the title that ends the boot sequence
accepts a single Ⓐ (2 of 2 at the time); the title the attract loop returns to

View File

@@ -252,3 +252,50 @@ content call on the press, and the age of the title — and the fifth (the captu
flag) has a strong correlation and no possible mechanism. The next honest step is
not another guess from outside: it is the guest's own state machine, and that
means reading the title code in `sylpheed.db`.
### 2026-08-19 (later) — the flag hypothesis loses its own test
With the capture cvar **removed from the launch line entirely** (F10 arms
unconditionally now), a fresh navigation run reached the boot title and Ⓐ **did
nothing**. So the flag is not necessary for the failure, and the correlation —
0 of 7 with it, 4 of 6 without it — does not survive as an explanation.
What is left is the plain reading, and it is worth stating as the conclusion
rather than as a stepping stone: **Ⓐ at the title succeeds about half the time,
and nothing measurable from outside predicts which.** Eliminated so far: Xenia UI
swallowing the keystroke (diagnostic never fires), the driver filter (flags 3 vs
`Controller = 1`), a sign-in or content call on the press (none is made), the age
of the title (the latest title of all accepted; an earlier one refused), and now
the capture cvar.
## The input path, mapped statically
Since the outside is exhausted, the guest side was traced in `sylpheed.db`:
```
entry_point 824AB748
└ sub_8216EA68 (968 B) main loop
└ sub_822F1AA8 (996 B) per-frame input update
└ sub_82457038 (628 B) THE PAD POLL
└ sub_824AA870 → XamInputGetKeystrokeEx (flags = 3)
```
`XamInputGetKeystrokeEx` has exactly **one** caller in the whole title
(`sub_824AA870`, a wrapper that maps user index `0xFF` to 0 and ORs in
`0x4000_0000` = ANY_USER), and that has exactly one caller, the poller. The
poller's shape is readable and matches the runtime trace:
* `+0` flags word — bit 31 "disabled", bit 30 "copy current→previous", bit 3
"also poll device state";
* a **keystroke queue** at `+68` with a count at `+72`: it drains
`GetKeystrokeEx` with `flags = 3` into 8-byte slots (the same `flags = 3` the
phase-A trace recorded, so this is the code the trace was watching);
* the current pad state at `+36`, the previous at `+52`, compared field by field
at the end (buttons `+40/+56`, triggers `+42/+43`, sticks `+44…+50`) to return
"changed" (3) or "unchanged" (0), and 2 if the device vanished.
**Nothing in that path is state-gated** — it polls unconditionally and reports
changes. Whatever ignores Ⓐ at an attract title is a *consumer* further up, and
finding it means identifying the object the poller fills (passed in as `r3` from
the per-frame update) and then its readers. That is a real RE job, not a
one-iteration probe, and it is where this thread now stands.