Direct follow-through on this session's own named next step. The prior
result (f1-held-down-measured-no-repeat-via-file-driver.md) concluded the
file driver cannot show menu repeat because its GetKeystroke() never emits
a REPEAT-flagged event, and that the menu's repeat is very likely driven by
that flag rather than raw polled state. Testable, so tested: patched
/canary/src/xenia/hid/file/file_input_driver.h to add opt-in repeat behind
a new --pad_file_repeat cvar (off by default, every other scripted script
unaffected), using the SDL driver's own constants verbatim
(HID_SDL_REPEAT_DELAY/_RATE = 400/100, guest-time ms via
Clock::QueryGuestUptimeMillis) rather than re-deriving them. Incremental
rebuild, ~1 minute (only xenia_main.cc needed recompiling).
Control: the driver's own log confirms repeated keystroke events fire as
designed, zero crashes.
Result: re-ran the identical held-DOWN capture. The cursor that moved once
and stopped in the null result now cycles continuously through the whole
5-item menu, wrapping, for as long as the button is held -- the null result
was real for that driver path, and giving the driver the one thing it
lacked reverses it completely.
Measured at this run's achieved 29.87 fps guest rate: 12 frames (~402ms)
initial delay from the press-triggered step to the first repeat step; 4
frames (~133ms) steady-state interval for 13 of 15 gaps, 3 frames (~100ms)
for the other 2 -- slower than the raw 100ms constant driving it, which
this page flags but does not trace further (most likely the game batches
drained keystrokes per its own frame tick rather than reacting to each one
instantly). The 4-frame figure is what matters for the port: it's what the
cursor visibly does.
Honestly scoped: this measures what the game does when FED repeat events
shaped like the SDL driver's, not a capture through an actual physical
controller (none exists in this container) -- classified measured, not
decoded, for exactly that reason. One run only; the corpus's two-run
minimum isn't met, flagged rather than overclaimed.
f1_hold_capture.py gains an optional `repeat` argument. The Canary source
patch itself lives in /canary, outside this repo (Canary source, not
sylpheed-formats) -- fully described inline in the finding doc so it can be
reapplied if that tree doesn't persist across a container reset.
Reference data: docs/re/data/f1-repeat-cursor-transitions.tsv -- every
transition's frame, guest tick and Y position, not the raw draw log.
Tried to close out issue #1 with an actual draw-log measurement this
iteration: built f1_hold_capture.py to boot to the settled main menu via the
proven glyph-gated route, arm the F10 UI-draw capture, hold a direction, and
read cursor position per frame -- the instrument f1-menu-repeat-harness-
built-not-answered.md already validated but never got to run against a
reachable menu.
Four bugs found across four boot attempts:
1. tap() shelled out to pad.py without this script's own env, so the press
went to /tmp/xenia_pad.txt while Canary watched OUT/pad.txt -- an
unobserved press indistinguishable from a dead pad. Fixed with an
in-process tap() using the same pad() the hold uses; confirmed working
the next run (title 154.5s, menu 163.0s).
2. ui_draw_capture_frames/max were persisted at 3/20000 from a prior
session in xenia-canary.config.toml -- log_ui_draws is now a documented
no-op (F10 arms unconditionally) and these two cvars didn't visibly
respond to command-line overrides. Bumped to 600/400000 directly in the
config.
3. The real blocker: this container has no signed-in profile (no content/
directory at all -- a fresh container after a restart, which every
container is right after one). Without a profile the title's sign-in
dialog sets IsUIActive() true, which reproduces
structures/title-a-press-fault.md's already-diagnosed unbounded-
keystroke-queue crash -- verified byte-for-byte against that page's own
addresses (PC 0x868 past sub_82457038, 0x828F3xxx registers, identical
host/guest address arithmetic), looping continuously from before F10 was
ever pressed. Fixed by creating a profile (--create_profile_if_none) and
signing in (--logged_profile_slot_0_xuid), matching boot_menu.sh, which
already did this and so never hit it. Confirmed: zero crashes with the
fix, dozens per run without it.
4. Found but not re-verified: no xsetroot blank before launch, so a stale
X-root frame from a killed prior run gave a false "TITLE" read at 2.6s,
before any real window existed -- skip_intro.sh already blanks the root
for exactly this reason. Fixed in the script.
Ran out of budget before a clean end-to-end run landed. Still no number for
issue #1 -- the Port keeps -1.0. Flagged prominently (HANDOFF, REFUTED.md)
because bug 3 will hit any bare run-canary invocation in any fresh
container, not just this script.