re: F1 measured -- held DOWN moves the cursor once and no more, via the file driver
Fifth boot attempt this session, first clean one, using the harness debugged last iteration (env-safe input, wide capture window, signed-in profile, blanked X root). Reached the menu, held DOWN 2.5s wall-clock, armed the F10 draw capture, released, killed -- zero crashes. Achieved vs requested: 433 of 600 requested frames, spanning 14.43s of GUEST time against ~4.5s wall-clock for the hold+tail window -- this run went at ~3.2x real time (a cheap static menu, nothing pacing it to a display refresh). The 2.5s wall-clock hold covers roughly 8s of that guest time. Method: track one quad shape's position per frame via read_draws.py, not a screen diff -- the approach f1-menu-repeat-harness-built-not-answered.md already named as correct. Exactly one shape-group moves at all: one jump of ~0.21-0.225 NDC units (matching the known one-menu-item pitch), complete within 4 frames / 133ms guest time of arming, then flat (a ~0.0125 pulse wobble only) for the remaining 427 frames / 14.3s of guest time. Broadening the match threshold finds no other moving element. This is a STRONGER negative than the 2026-08-30 result it agrees with (that one sampled a screen diff at ~4-5fps for 2.0s; this reads every quad every frame for ~8s of guest-time held) -- it survives, rather than confirms, last iteration's "coarse sampling hid a fast repeat" alternative, which does not survive a per-frame instrument over a much longer window. Refutation attempt against my own prior lean, recorded: it does not survive. Reconciled, not left in conflict: the human's play-test and pad.py's "auto-repeats" warning almost certainly went through a REAL controller (Canary's SDL driver), which auto-repeats keystrokes at a documented upstream 400ms/100ms (guest time) via the REPEAT keystroke flag. The file driver deliberately never emits that flag, by design -- so it cannot show repeat regardless of how carefully or how long it's held, which is exactly the negative measured here. Still no F1 number; now a specific, well- evidenced reason the file driver alone will never produce one, and a named next step (add opt-in REPEAT-flag support to the file driver, matching the SDL driver's constants, then re-run this exact capture) -- not attempted this iteration, a second unit on an already-complete one. Reference data: docs/re/data/f1-cursor-quad-y-per-frame.tsv -- the derived per-frame Y position and guest tick, not the raw draw log itself (a capture artifact, kept uncommitted per the corpus's game-content rule).
This commit is contained in:
@@ -6607,3 +6607,28 @@ read). Ran out of iteration budget before a clean end-to-end run. **Still no
|
||||
number for you** — keep `-1.0`. The harness should work next attempt;
|
||||
flagging for whoever's container hits the same profile-crash first, since
|
||||
every fresh container starts with none.
|
||||
|
||||
## 🔴 F1 — clean run landed. Still keep `-1.0`, but now for a sharper reason
|
||||
|
||||
[`docs/re/f1-held-down-measured-no-repeat-via-file-driver.md`](../re/f1-held-down-measured-no-repeat-via-file-driver.md).
|
||||
Fifth boot attempt, all four bugs fixed: reached the menu, armed the draw
|
||||
capture cleanly, held ⬇ for 2.5 s wall-clock (≈8 s of *guest* time — this
|
||||
run went at ~3.2× real time, a cheap static menu with nothing pacing it to a
|
||||
display refresh). **Measured, not inferred:** one cursor step, caught within
|
||||
133 ms of the press; then zero further moves for the remaining ~14 s of
|
||||
guest time the capture covers, tracked per-frame off the draw log, not a
|
||||
screen diff. This is a *stronger* negative than the 2026-08-30 one, not a
|
||||
different one — it survives the "coarse sampling hid a fast repeat" theory
|
||||
that seemed to be winning after the previous iteration's static trace.
|
||||
|
||||
**Read together with the earlier source finding**, the picture now holds
|
||||
together instead of conflicting: the human's play-test and `pad.py`'s
|
||||
"auto-repeats" warning were almost certainly observed through a **real
|
||||
controller** (Canary's SDL driver), which auto-repeats keystrokes at a
|
||||
documented 400 ms delay / 100 ms interval (guest time) — upstream Xenia, not
|
||||
this game's own code. Our **scripted** input goes through the `file` driver,
|
||||
which deliberately never emits that repeat flag. So: **still no number, and
|
||||
now a clear reason no amount of re-testing through the file driver will ever
|
||||
produce one.** The next thing that could is patching repeat support into the
|
||||
file driver (proposed twice, not yet built) and re-running this exact
|
||||
capture. `-1.0` stays authored, not guessed, either way.
|
||||
|
||||
@@ -1094,6 +1094,20 @@ attached to a right direction; only the reason is refuted here.
|
||||
emulator needed — or re-run with a repeat-capable file driver and read
|
||||
cursor position off the draw log per frame, not a coarse screen-diff.
|
||||
[`f1-no-repeat-was-the-harness.md`](f1-no-repeat-was-the-harness.md) ⟨harness⟩
|
||||
🔴 **Half of "to settle" done 2026-09-12, and it points back the other
|
||||
way.** Re-ran with the *existing* file driver, tracking one quad shape's
|
||||
position per frame (not a screen diff): one real move, caught cleanly at
|
||||
133 ms guest resolution, then **nothing for the remaining ~8 s of guest
|
||||
time the button was held** — a stronger negative than the original, not a
|
||||
reversal of it. This also refutes my own leading alternative from the
|
||||
`C_PAD_RINGBUF` trace (that a coarse screen-diff was hiding a fast
|
||||
polled-state repeat): a per-frame instrument over a much longer held
|
||||
window still finds nothing. Reading now favours Keystroke-`REPEAT`-driven
|
||||
menu navigation after all — which the file driver cannot produce by
|
||||
design, regardless of how carefully it's held — over the polled-state theory.
|
||||
Still 🟡, not ❌: only the file-driver path is tested; the SDL-driver path
|
||||
(what a real controller and the human's play-test went through) is not.
|
||||
[`f1-held-down-measured-no-repeat-via-file-driver.md`](f1-held-down-measured-no-repeat-via-file-driver.md) ⟨capture⟩
|
||||
* "F10-arming a UI draw capture is safe on any settled screen" — **implicit
|
||||
in every prior use of it, and false in a fresh container.** A `run-canary`
|
||||
launch with no signed-in profile (every container right after a restart —
|
||||
|
||||
131
docs/re/data/f1-cursor-quad-y-per-frame.tsv
Normal file
131
docs/re/data/f1-cursor-quad-y-per-frame.tsv
Normal file
@@ -0,0 +1,131 @@
|
||||
# frame gtick gfreq_hz cursor_quad_y_ndc
|
||||
# source: xenia_re_ui_draws_01.log, 2026-09-12, f1_hold_capture.py run 5 (f1g)
|
||||
# quad: page B5B1C73032BA3FA3, ~0.09x0.16 NDC (focus highlight)
|
||||
# held DOWN written at wall t~=161.6s (script HOLD start), released ~164.1s
|
||||
1 8077295605 50000000 0.0525
|
||||
2 8078950338 50000000 0.055
|
||||
5 8083967064 50000000 -0.16
|
||||
6 8085646790 50000000 -0.16
|
||||
7 8087365907 50000000 -0.16
|
||||
10 8092344928 50000000 -0.1625
|
||||
11 8094014388 50000000 -0.1625
|
||||
12 8095718136 50000000 -0.16
|
||||
13 8097430051 50000000 -0.1625
|
||||
21 8110812183 50000000 -0.1675
|
||||
22 8112478213 50000000 -0.17
|
||||
23 8114208650 50000000 -0.1675
|
||||
27 8120905050 50000000 -0.17
|
||||
28 8122530583 50000000 -0.17
|
||||
29 8124213619 50000000 -0.17
|
||||
36 8135946976 50000000 -0.17
|
||||
37 8137620430 50000000 -0.17
|
||||
57 8171043909 50000000 -0.16
|
||||
58 8172689798 50000000 -0.16
|
||||
65 8184394745 50000000 -0.16
|
||||
66 8186106441 50000000 -0.16
|
||||
67 8187771244 50000000 -0.16
|
||||
70 8192768181 50000000 -0.1625
|
||||
71 8194492771 50000000 -0.1625
|
||||
72 8196154016 50000000 -0.16
|
||||
73 8197801248 50000000 -0.1625
|
||||
81 8211207297 50000000 -0.1675
|
||||
82 8212855981 50000000 -0.17
|
||||
83 8214569003 50000000 -0.1675
|
||||
87 8221264934 50000000 -0.17
|
||||
88 8222911320 50000000 -0.17
|
||||
89 8224614159 50000000 -0.17
|
||||
96 8236285728 50000000 -0.17
|
||||
97 8237986083 50000000 -0.17
|
||||
117 8271508635 50000000 -0.16
|
||||
118 8273209128 50000000 -0.16
|
||||
125 8284925117 50000000 -0.16
|
||||
126 8286599612 50000000 -0.16
|
||||
127 8288306224 50000000 -0.16
|
||||
130 8293338269 50000000 -0.1625
|
||||
131 8295030562 50000000 -0.1625
|
||||
132 8296723652 50000000 -0.16
|
||||
133 8298377150 50000000 -0.1625
|
||||
141 8311734503 50000000 -0.1675
|
||||
142 8313414801 50000000 -0.17
|
||||
143 8315067618 50000000 -0.1675
|
||||
147 8321746008 50000000 -0.17
|
||||
148 8323415335 50000000 -0.17
|
||||
149 8325134926 50000000 -0.17
|
||||
156 8336880646 50000000 -0.17
|
||||
157 8338715074 50000000 -0.17
|
||||
177 8372226351 50000000 -0.16
|
||||
178 8373910878 50000000 -0.16
|
||||
185 8385596519 50000000 -0.16
|
||||
186 8387262693 50000000 -0.16
|
||||
187 8388929103 50000000 -0.16
|
||||
190 8393937806 50000000 -0.1625
|
||||
191 8395639462 50000000 -0.1625
|
||||
192 8397278358 50000000 -0.16
|
||||
193 8398933992 50000000 -0.1625
|
||||
201 8412260793 50000000 -0.1675
|
||||
202 8414004734 50000000 -0.17
|
||||
203 8415667167 50000000 -0.1675
|
||||
207 8422367364 50000000 -0.17
|
||||
208 8424030952 50000000 -0.17
|
||||
209 8425700045 50000000 -0.17
|
||||
216 8437382342 50000000 -0.17
|
||||
217 8439068602 50000000 -0.17
|
||||
237 8472406179 50000000 -0.16
|
||||
238 8474085108 50000000 -0.16
|
||||
245 8485743903 50000000 -0.16
|
||||
246 8487413304 50000000 -0.16
|
||||
247 8489067654 50000000 -0.16
|
||||
250 8494081252 50000000 -0.1625
|
||||
251 8495818763 50000000 -0.1625
|
||||
252 8497475603 50000000 -0.16
|
||||
253 8499145711 50000000 -0.1625
|
||||
261 8512509389 50000000 -0.1675
|
||||
262 8514145895 50000000 -0.17
|
||||
263 8515853531 50000000 -0.1675
|
||||
267 8522549986 50000000 -0.17
|
||||
268 8524228499 50000000 -0.17
|
||||
269 8525932669 50000000 -0.17
|
||||
276 8537663413 50000000 -0.17
|
||||
277 8539354084 50000000 -0.17
|
||||
297 8572827882 50000000 -0.16
|
||||
298 8574531771 50000000 -0.16
|
||||
305 8586256367 50000000 -0.16
|
||||
306 8587913956 50000000 -0.16
|
||||
307 8589566049 50000000 -0.16
|
||||
310 8594594709 50000000 -0.1625
|
||||
311 8596292779 50000000 -0.1625
|
||||
312 8597936103 50000000 -0.16
|
||||
313 8599628814 50000000 -0.1625
|
||||
321 8613009386 50000000 -0.1675
|
||||
322 8614648734 50000000 -0.17
|
||||
323 8616321818 50000000 -0.1675
|
||||
327 8622991187 50000000 -0.17
|
||||
328 8624688470 50000000 -0.1725
|
||||
329 8626338823 50000000 -0.17
|
||||
336 8638111132 50000000 -0.17
|
||||
337 8639823382 50000000 -0.17
|
||||
357 8673272643 50000000 -0.16
|
||||
358 8674946981 50000000 -0.16
|
||||
365 8686603708 50000000 -0.16
|
||||
366 8688279571 50000000 -0.16
|
||||
367 8689942913 50000000 -0.16
|
||||
370 8694996359 50000000 -0.1625
|
||||
371 8696658822 50000000 -0.1625
|
||||
372 8698321977 50000000 -0.16
|
||||
373 8699983034 50000000 -0.1625
|
||||
381 8713361239 50000000 -0.1675
|
||||
382 8715049029 50000000 -0.17
|
||||
383 8716689919 50000000 -0.1675
|
||||
387 8723381237 50000000 -0.17
|
||||
388 8725066870 50000000 -0.1725
|
||||
389 8726756040 50000000 -0.17
|
||||
396 8738454519 50000000 -0.17
|
||||
397 8740146250 50000000 -0.17
|
||||
417 8773614167 50000000 -0.16
|
||||
418 8775249863 50000000 -0.16
|
||||
425 8787042967 50000000 -0.16
|
||||
426 8788724033 50000000 -0.16
|
||||
427 8790309865 50000000 -0.16
|
||||
430 8795410469 50000000 -0.1625
|
||||
431 8797094266 50000000 -0.1625
|
||||
432 8798815247 50000000 -0.16
|
||||
|
132
docs/re/f1-held-down-measured-no-repeat-via-file-driver.md
Normal file
132
docs/re/f1-held-down-measured-no-repeat-via-file-driver.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# F1 — measured: held ⬇ moves the cursor once and no more, over ~8 s of guest time, through the file driver
|
||||
|
||||
**Status:** ✅ measured (⟨capture⟩), for the path this container can actually
|
||||
drive. ❔ still not F1's requested initial-delay/interval numbers — this
|
||||
result explains why they cannot come from this instrument, and names the one
|
||||
that could. Instrument:
|
||||
[`tools/re-capture/f1_hold_capture.py`](../../tools/re-capture/f1_hold_capture.py),
|
||||
after the four fixes in
|
||||
[`f1-hold-capture-harness-debugged.md`](f1-hold-capture-harness-debugged.md).
|
||||
2026-09-12, fifth boot attempt, first clean one.
|
||||
|
||||
## The run
|
||||
|
||||
Reached the settled main menu at 159.3 s (title at 154.3 s, matching the last
|
||||
clean run's timing), armed the F10 draw capture, held ⬇ for 2.5 s wall-clock,
|
||||
released, waited 2 s, killed. Zero crashes. 433 of the requested 600 frames
|
||||
captured before the kill (`ui_draw_capture_frames=600`, bumped from the
|
||||
default 3 last iteration).
|
||||
|
||||
⚠️ **Achieved vs. requested, per `TEMPORAL-VERIFICATION.md`:** the 433 frames
|
||||
span **14.43 s of *guest* time** (`gtick`/`gfreq` on each frame header, `50 000 000` Hz)
|
||||
against **~4.5 s of wall-clock** for the hold + tail — this window ran at
|
||||
roughly **3.2× real time**, not 1:1. A static 2D menu is cheap to render, and
|
||||
nothing here was pacing the emulation to a display refresh. The 2.5 s
|
||||
wall-clock hold itself therefore covers **roughly 8 s of guest time** (the
|
||||
hold is 2.5 of the 4.5 wall-clock seconds captured), not 2.5. Achieved guest
|
||||
frame rate: **29.87 fps** — close to a 30 Hz internal tick, for what it's
|
||||
worth, but this is a rate, not a claim about which clock the menu itself
|
||||
runs on.
|
||||
|
||||
## Method — track one quad shape's position, not a screen diff
|
||||
|
||||
Read every draw with `read_draws.py`, grouped quads by `(texture page,
|
||||
width, height)` — the *"track one quad shape's position over time"* approach
|
||||
`f1-menu-repeat-harness-built-not-answered.md` already named as the correct
|
||||
one. Exactly one shape-group moves at all across the whole capture: page
|
||||
`B5B1C73032BA3FA3`, a small (`0.09 × ~0.16` NDC) element — the focus
|
||||
highlight, by elimination and by the size of its move (below).
|
||||
|
||||
## What it shows
|
||||
|
||||
| frame | guest ms since frame 1 | Y (NDC) |
|
||||
|---|---|---|
|
||||
| 1 | 0 | **+0.0525** |
|
||||
| 5 | 133 | **−0.16** |
|
||||
| 6…432 | up to 14 297 ms later | **−0.1725 … −0.16** (wobble only) |
|
||||
|
||||
**One jump, size 0.21–0.225 NDC units, complete within 4 frames (133 ms
|
||||
guest) of arming** — close to the one-item pitch computed from
|
||||
`menu_focus.py`'s known button rows (`(390−315)/720×2 = 0.208`), i.e. this
|
||||
reads as one menu step. **Then nothing.** The −0.16-ish value that follows
|
||||
oscillates by ≤0.0125 on a ~60-frame cycle for the remaining **427 frames /
|
||||
14.3 s of guest time** — a pulsing highlight glow, the same shape of
|
||||
animation this corpus has measured elsewhere, not a second discrete move.
|
||||
Broadening the shape-match threshold from ≥50 to ≥5 frames-present finds
|
||||
only one other group, at the same page and a rounding-adjacent height
|
||||
(`0.17` vs `0.16`, same element split by sub-pixel quantisation), showing
|
||||
the identical pattern. **Nothing else in the capture moves at all.**
|
||||
|
||||
This is a stronger negative than the 2026-08-30 result it agrees with:
|
||||
`nav_repeat_and_b.py` sampled a screen diff at ~4–5 fps for 2.0 s wall-clock;
|
||||
this reads *every submitted quad, every frame*, for a window covering **~8 s
|
||||
of guest time** the button was actually held. A coarse-sampling explanation
|
||||
for "no repeat" — the leading alternative hypothesis after last iteration's
|
||||
`C_PAD_RINGBUF` trace — cannot survive a per-frame instrument that still
|
||||
finds nothing.
|
||||
|
||||
## Reconciling with the standing conflict, not hand-waving past it
|
||||
|
||||
Three facts now sit together and are not actually in tension once separated
|
||||
by **instrument**, not by hand:
|
||||
|
||||
1. The human's play-test, and `pad.py`'s own docstring, both describe a real
|
||||
repeat — almost certainly observed through a **real controller**, i.e.
|
||||
Canary's **SDL** input driver.
|
||||
2. That driver's `GetKeystroke()` (`f1-no-repeat-was-the-harness.md`)
|
||||
auto-repeats keystrokes at a *documented, upstream* 400 ms initial delay
|
||||
then 100 ms interval, guest time (`HID_SDL_REPEAT_DELAY`/`_RATE`).
|
||||
3. This measurement went through the **file** driver, whose `GetKeystroke()`
|
||||
is *deliberately* built to emit exactly one event per press and never a
|
||||
`REPEAT`-flagged one — and now, measured rather than argued, holding the
|
||||
button via that driver's continuously-reporting `GetState()` for ~8
|
||||
guest-seconds produces no second move either.
|
||||
|
||||
**The straightforward reading:** menu repeat is driven by `REPEAT`-flagged
|
||||
keystrokes, not by polling raw held state every frame. The file driver
|
||||
cannot produce that flag by design, so it cannot show repeat, however long
|
||||
or precisely you hold the button through it — which is exactly the negative
|
||||
result above. Last iteration's `C_PAD_RINGBUF` trace (analog-axis-shaped
|
||||
fields, favouring a polled-state reading) likely belongs to a different
|
||||
consumer — plausibly raw stick deflection for something else entirely — not
|
||||
to whatever specifically steps the menu cursor. That inference is not
|
||||
re-verified here; flagging it as probably-superseded rather than silently
|
||||
dropping it.
|
||||
|
||||
## What would actually answer F1
|
||||
|
||||
Give the file driver the same `REPEAT`-flag capability the SDL driver has,
|
||||
gated behind a new flag so every other scripted script keeps today's
|
||||
one-event-per-press behaviour (this was proposed, not built, twice already —
|
||||
`f1-no-repeat-was-the-harness.md`'s original "what would close it" and the
|
||||
harness-debugging page's "what's left"). Then re-run this exact capture.
|
||||
Two outcomes, both answers:
|
||||
|
||||
* it now shows a genuine repeat, at some interval derived from the SDL
|
||||
driver's constants or the game's own consumption of them — measure the
|
||||
interval in frames at the achieved guest rate, not a millisecond guess;
|
||||
* it still shows nothing, which would mean the menu's repeat is driven by
|
||||
something other than the Keystroke `REPEAT` flag after all, and the
|
||||
question reopens from a different angle.
|
||||
|
||||
Not attempted this iteration — patching the driver and re-running is a
|
||||
second, larger unit on top of an already-complete one.
|
||||
|
||||
## Reference data
|
||||
|
||||
[`data/f1-cursor-quad-y-per-frame.tsv`](data/f1-cursor-quad-y-per-frame.tsv) —
|
||||
the focus-highlight quad's Y (NDC) per frame it appears in, with the guest
|
||||
tick/frequency for each, derived from the run's draw log (not the log
|
||||
itself, which is a capture artifact and stays uncommitted per the corpus's
|
||||
rule on game content — this is measurement output, numbers only).
|
||||
|
||||
## Reach
|
||||
|
||||
⟨capture⟩ for the "no repeat via the file driver" result — direct, per-frame,
|
||||
quantified in guest time, with the instrument's own capability shown by the
|
||||
one real move it caught. Everything about *why* (Keystroke vs. polled state)
|
||||
is ⟨canary-source⟩ reasoning connecting this result to the prior static
|
||||
trace, not itself re-measured. One run only — the corpus's own two-run
|
||||
minimum for a reproducibility claim is not met, though this run's own
|
||||
positive control (catching the initial move at 133 ms resolution) is
|
||||
evidence the null isn't an instrument artifact of *this specific* run.
|
||||
Reference in New Issue
Block a user