# F1 — measured: ~12 frames initial delay, ~4 frames steady interval, by giving the driver the repeat it lacked **Status:** ✅ measured (⟨capture⟩), via a purpose-built instrument, not the game's own emulated hardware path. This is the direct follow-through on [`f1-held-down-measured-no-repeat-via-file-driver.md`](f1-held-down-measured-no-repeat-via-file-driver.md)'s named next step. 2026-09-12, same session. ## What changed The prior page's conclusion: the file driver cannot show menu repeat because its `GetKeystroke()` never emits a `REPEAT`-flagged event, by design, and the menu's repeat is very likely driven by that flag rather than by polling raw held state. That is a testable claim, so it was tested: patched `/canary/src/xenia/hid/file/file_input_driver.h` to add opt-in repeat, gated behind a new `--pad_file_repeat` cvar (off by default — every existing scripted script keeps its one-event-per-press behaviour unchanged), using the **exact same constants** as the SDL driver (`HID_SDL_REPEAT_DELAY`/`_RATE` = 400/100, guest-time milliseconds via `Clock::QueryGuestUptimeMillis()`) rather than re-deriving them. Rebuilt Canary (`build-canary Release`, incremental, ~1 minute — only `xenia_main.cc` and the header needed recompiling). Full patch in `/canary`; not yet upstreamed into this repo's own tooling copy, since it's Canary source, not `sylpheed-formats`. **Control:** the driver's own log confirms the mechanism fires as designed — a held ⬇ produced repeated `[file-pad] keystroke vk=5811 repeat` lines at the driver level, and zero crashes. ## The result — the game DOES react to REPEAT, decisively Re-ran the exact same capture as the null result (boot to menu, hold ⬇ for 2.5 s wall-clock, draw-log per frame), this time with `--pad_file_repeat=true`. Tracking the same focus-highlight quad (page `B5B1C73032BA3FA3`) that showed exactly one move and then nothing in the prior run: **19 distinct positions across the capture, spanning nearly the full NDC range** — the cursor visibly cycled through the whole 5-item list multiple times, wrapping, for as long as the button was held. The null result was real *for that driver path*; giving the driver the one thing it lacked reverses it completely. Reference data: [`data/f1-repeat-cursor-transitions.tsv`](data/f1-repeat-cursor-transitions.tsv) — every transition's frame, guest tick and Y position, derived from the draw log (log itself not committed, per the corpus's game-content rule). ## The numbers, in frames at this run's achieved guest rate Achieved: **29.87 fps** (432 frames / 14.46 s guest time) — reported before the numbers below, per `TEMPORAL-VERIFICATION.md`. | | frame | since previous | |---|---|---| | initial position | 1 | — | | **press-triggered step** (not a repeat — the ordinary `KEYDOWN` edge) | 3 | 2 frames | | **first repeat-driven step** | 15 | **12 frames** (402 ms) | | every step after, ×15 | 19, 23, 27, 31, 35, 39, 43, 50, 54, 58, 62, 66, 70, 73, 77 | **4 frames** ×13, **3 frames** ×2 | **Initial delay: 12 frames (~402 ms guest) from the press-triggered step to the first repeat.** Strikingly close to the SDL driver's own 400 ms constant — expected, since that constant is what armed the timer, and the closeness is a sanity check on the measurement more than a new fact. **Steady-state interval: predominantly 4 frames (~133 ms), with 2 of 16 gaps at 3 frames (~100 ms).** This is *not* the same as the 100 ms constant that drives the underlying `REPEAT` emission — it is measurably slower and shows the frame-vs-100ms aliasing pattern you'd expect if the game consumes repeat events at its own per-frame pace rather than reacting to every one instantly (100 ms ÷ 33.5 ms/frame = 2.99, not 4). **The 4-frame figure is the one that matters for the port**: it is what the cursor visibly does, regardless of how the underlying keystroke stream is paced. The mismatch against the raw driver constant is noted, not resolved — tracing exactly where the extra ~30 ms per step goes (game-side frame batching of drained keystrokes, most likely, given `sub_82457038` drains up to three `XamInputGetKeystrokeEx` calls per poll) is future work, not needed to answer what's asked here. ## What this is not **Not proof this is what a real controller produces.** It is proof of what the game does when *fed* `REPEAT` events at the same rate and shape the SDL driver would produce — the closest thing to that oracle this container can exercise, since no physical controller exists here. If a future session can compare against an actual SDL-driver capture, this is the number to check it against. Classified `measured`, not `decoded`, for exactly that reason: nothing about this rate is decoded from the disc, and the delay/interval constants were chosen by us (borrowed from Canary's own upstream driver, not the game). ## Reach One run. The corpus's own two-run minimum for reproducibility is not met — flagging rather than overclaiming. The steady-state interval's 3-vs-4-frame split (14:2 across 16 gaps) is itself worth a second run to see if that ratio holds or was a one-off aliasing artefact of this particular boot's exact frame phase. The initial-delay figure rests on a single transition and would benefit from the same repeat.