diff --git a/docs/re/canary-scripted-input-traps.md b/docs/re/canary-scripted-input-traps.md index 256663ac..96d75455 100644 --- a/docs/re/canary-scripted-input-traps.md +++ b/docs/re/canary-scripted-input-traps.md @@ -132,19 +132,29 @@ useless, it **breaks the run** — 88 presses left a black screen that never cam back (no crash, no throw, the emulator healthy). The script no longer taps during boot; the intro takes ~3.5 minutes and gets to the title by itself. -**So the difference is not the number of presses or the button.** The one -success came on a title that appeared ~83 s into a warm boot; the failures came -on titles that appeared after 292 s and a full attract cycle. The obvious -reading — that the attract-loop title is a non-interactive presentation and the -post-boot title is the interactive one — is a **hypothesis, unconfirmed**, and it -is what to test next. +**So the difference is not the number of presses or the button — it is which +title you are looking at**, and that is now measured rather than guessed: + +* the title that **ends the boot sequence** accepts a single Ⓐ and opens the main + menu — **2 of 2**, in independent runs, one of which never pressed F10; +* the title the **attract loop returns to** accepts nothing — Ⓐ, START, B, BACK, + X, Y, dozens of presses, every one delivered, none swallowed. + +**The recipe, then:** launch, wait for the first `title` classification, tap Ⓐ +once. Do not tap during the boot, and do not wait for a second title. + +The tell is *not* visible in what the game draws — a `log_ui_draws` capture in +each state gives 13 quads at identical rects, `ptbtn00` (the `PRESS Ⓐ BUTTON` +plate) included in both. See +[`ui-title-paint-order-capture.md`](ui-title-paint-order-capture.md). ## Still open -Which title state accepts input, and how to tell them apart from outside. A -`log_ui_draws` capture in each state would say whether the two composite -differently (the interactive one draws `ptbtn00`, the `PRESS Ⓐ BUTTON` plate, -from build 2 — if the attract title omits or replaces it, that is the tell and it -is visible in one capture). Until that is pinned down, reaching the main menu is -a matter of luck, which is not a basis for the second screen's paint-order -capture. +**Why** the attract title stops accepting input, given that it draws exactly the +same thing. Nothing in the composition, the input path or the sign-in state +differs; the difference is in the guest's own state machine, and reading it means +reading that code. + +Not open any more, and worth stating because it was the thing blocking the RE: +reaching the main menu is now routine (first title, one Ⓐ), and the second +screen's paint order has been captured with it. diff --git a/docs/re/captures/main-menu-draw-capture.png b/docs/re/captures/main-menu-draw-capture.png new file mode 100644 index 00000000..796efdfa Binary files /dev/null and b/docs/re/captures/main-menu-draw-capture.png differ diff --git a/docs/re/captures/main-menu-draw-order.log b/docs/re/captures/main-menu-draw-order.log new file mode 100644 index 00000000..869a44ef --- /dev/null +++ b/docs/re/captures/main-menu-draw-order.log @@ -0,0 +1,40 @@ +# every draw in SUBMISSION ORDER, undeduplicated, frames 1..4 +# tex dimensions identify the sprite; base is the guest address + 0 prim=8 indices=3 vs=0x0A6D1DD7767FDF27 ps=0x2E372EA28CC404B7 + vb=0x14F993B8 stride=28 attrs=[57@0 38@12 ] fmt0=57 v: [-0.50,-0.50,z=0.00000] [1279.50,-0.50,z=0.00000] [1279.50,719.50,z=0.00000] + 1 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0C340000 1280x768 fmt=6] + vb=0x14F99410 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000] [1.00,1.00,z=0.00000] [1.00,-1.00,z=0.00000] [-1.00,-1.00,z=0.00000] + 2 prim=13 indices=8 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0C340000 1280x768 fmt=6] + vb=0x14F99470 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [1.84,1.58,z=0.00000] [2.38,1.02,z=0.00000] [1.54,-1.57,z=0.00000] [1.00,-1.02,z=0.00000] [-2.82,1.02,z=0.00000] [-2.38,1.81,z=0.00000] [-0.79,-1.02,z=0.00000] [-1.23,-1.81,z=0.00000] + 3 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0AEF0000 1280x768 fmt=6] + vb=0x14F99530 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000] [1.00,1.00,z=0.00000] [1.00,-1.00,z=0.00000] [-1.00,-1.00,z=0.00000] + 4 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0x5773DC18083C4C20 + vb=0x14F99590 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000] [1.00,1.00,z=0.00000] [1.00,-1.00,z=0.00000] [-1.00,-1.00,z=0.00000] + 5 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0C340000 1280x768 fmt=6] + vb=0x14F995F0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.64,1.00,z=0.00000] [0.64,1.00,z=0.00000] [0.64,-1.00,z=0.00000] [-0.64,-1.00,z=0.00000] + 6 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0BA60000 1280x768 fmt=6] + vb=0x14F99650 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.54,1.00,z=0.00000] [0.54,1.00,z=0.00000] [0.54,-1.00,z=0.00000] [-0.54,-1.00,z=0.00000] + 7 prim=13 indices=8 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0C340000 1280x768 fmt=6] + vb=0x14F996B0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.31,0.70,z=0.00000] [0.07,0.70,z=0.00000] [0.07,-0.08,z=0.00000] [-0.31,-0.08,z=0.00000] [-0.09,0.26,z=0.00000] [0.31,0.26,z=0.00000] [0.31,-0.60,z=0.00000] [-0.09,-0.60,z=0.00000] + 8 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0C340000 1280x768 fmt=6] + vb=0x14F99770 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.18,-0.65,z=0.00000] [0.17,-0.65,z=0.00000] [0.17,-0.76,z=0.00000] [-0.18,-0.76,z=0.00000] + 9 prim=13 indices=24 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x11C30000 1280x768 fmt=6] + vb=0x14F997D0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.16,0.42,z=0.00000] [-0.23,0.44,z=0.00000] [-0.21,0.57,z=0.00000] [-0.15,0.55,z=0.00000] [-0.16,0.57,z=0.00000] [0.17,0.57,z=0.00000] [0.17,0.42,z=0.00000] [-0.16,0.42,z=0.00000] + 10 prim=8 indices=3 vs=0x72CBCAA6A7984111 ps=0xE59B2B3DA4AA9008 tex[base=0x10000000 1x1 fmt=26] + 11 prim=8 indices=3 vs=0x72CBCAA6A7984111 ps=0xE59B2B3DA4AA9008 tex[base=0x10000000 1x1 fmt=26] +--- frame 3 --- + 12 prim=8 indices=3 vs=0x0A6D1DD7767FDF27 ps=0x2E372EA28CC404B7 + vb=0x14FD9B38 stride=28 attrs=[57@0 38@12 ] fmt0=57 v: [-0.50,-0.50,z=0.00000] [1279.50,-0.50,z=0.00000] [1279.50,719.50,z=0.00000] + 13 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0C340000 1280x768 fmt=6] + vb=0x14FD9B90 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000] [1.00,1.00,z=0.00000] [1.00,-1.00,z=0.00000] [-1.00,-1.00,z=0.00000] + 14 prim=13 indices=8 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0C340000 1280x768 fmt=6] + vb=0x14FD9BF0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.49,1.58,z=0.00000] [-0.95,1.02,z=0.00000] [-1.80,-1.57,z=0.00000] [-2.34,-1.02,z=0.00000] [-2.87,1.02,z=0.00000] [-2.43,1.81,z=0.00000] [-0.83,-1.02,z=0.00000] [-1.28,-1.81,z=0.00000] + 15 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0AEF0000 1280x768 fmt=6] + vb=0x14FD9CB0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000] [1.00,1.00,z=0.00000] [1.00,-1.00,z=0.00000] [-1.00,-1.00,z=0.00000] + 16 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0x5773DC18083C4C20 + vb=0x14FD9D10 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-1.00,1.00,z=0.00000] [1.00,1.00,z=0.00000] [1.00,-1.00,z=0.00000] [-1.00,-1.00,z=0.00000] + 17 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0C340000 1280x768 fmt=6] + vb=0x14FD9D70 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.64,1.00,z=0.00000] [0.64,1.00,z=0.00000] [0.64,-1.00,z=0.00000] [-0.64,-1.00,z=0.00000] + 18 prim=13 indices=4 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0BA60000 1280x768 fmt=6] + vb=0x14FD9DD0 stride=24 attrs=[57@0 6@12 37@16 ] fmt0=57 v: [-0.54,1.00,z=0.00000] [0.54,1.00,z=0.00000] [0.54,-1.00,z=0.00000] [-0.54,-1.00,z=0.00000] + 19 prim=13 indices=8 vs=0xE0BAFB4F520FE441 ps=0xE59B2B3DA4AA9008 tex[base=0x0C340000 1280x768 fmt=6] diff --git a/docs/re/captures/main-menu-paint-order.txt b/docs/re/captures/main-menu-paint-order.txt new file mode 100644 index 00000000..2e15e29c --- /dev/null +++ b/docs/re/captures/main-menu-paint-order.txt @@ -0,0 +1,13 @@ +frame 1 draw 0 ( 0, 0) 1280x720 → 8AX 1280x720 +frame 1 draw 1 ( 0, 0) 1280x720 → 8AX 1280x720 +frame 1 draw 2 (1280,-209) 883x1134 ROT → ? +frame 1 draw 2 (-1165,-292) 1299x1303 ROT → ? +frame 1 draw 3 ( 0, 0) 1280x720 → 8AX 1280x720 +frame 1 draw 4 ( 0, 0) 1280x720 → 8AX 1280x720 +frame 1 draw 5 ( 230, 0) 819x720 → ? +frame 1 draw 6 ( 294, 0) 691x720 → ? +frame 1 draw 7 ( 442, 108) 243x281 → ptframe1.t32 247x281 (±4) +frame 1 draw 7 ( 582, 266) 256x310 → ptframe2.t32 257x311 (±1) +frame 1 draw 8 ( 525, 594) 224x40 → ptmsg.t32 223x38 (±2) +frame 1 draw 9 ( 493, 155) 51x54 ROT → ? +frame 1 draw 9 ( 538, 155) 211x54 → ptbtn01f.t32 216x56 (±5) diff --git a/docs/re/ui-title-paint-order-capture.md b/docs/re/ui-title-paint-order-capture.md index 0e7275d1..54a23197 100644 --- a/docs/re/ui-title-paint-order-capture.md +++ b/docs/re/ui-title-paint-order-capture.md @@ -264,3 +264,52 @@ What is established so far is small, and stated so it is not mistaken for more: `sub_821B4498`, turns out to be a **time-string parser** (`MM:SS.mmm` — it splits on `:` and `.` and multiplies by 60, then 100). The guest does not necessarily index that table with a multiply at all. + +--- + +## A second screen, and a second title state (2026-08-18, later still) + +### The main menu's paint order + +Reached and captured. Its sprites are `GP_TITLE.pak` **build 5**'s (the 16-element +menu build), and every identified quad lands within 4 px of its declared resting +placement — another independent check on the placement decode, on a bundle +nothing had touched: + +| draw | quad | sprite | declared rest | +|---|---|---|---| +| 7 | (442,108) 243×281 | `ptframe1.t32` [6] | (445,108) | +| 7 | (582,266) 256×310 | `ptframe2.t32` [7] | (578,267) | +| 8 | (525,594) 224×40 | `ptmsg.t32` | — | +| 9 | (538,155) 211×54 | `ptbtn01f.t32` (focused NEW GAME) [10→focus] | (542,157) | + +preceded by five full-screen layers and the rotated `ptloop` pair. + +**And it does not discriminate**, which is the honest headline. The observed order +is *consistent* with build 5's declaration order — but build 5 lists its +background at indices 1–2, so "declaration order" and "background first" predict +the same thing here. It is exactly the failure mode `BACKLOG.md` recorded for +`GP_READY_ROOM` and `GP_OPTIONS`. What it does establish is that the title's +disagreement is not a decode artefact: same pak, same engine, two builds, and one +of them paints in an order its table does not describe. + +### The two title states: identical to draw, different to press + +The previous entry's hypothesis — that the attract-loop title is a +non-interactive *presentation* that omits the `PRESS Ⓐ BUTTON` plate — is +**half confirmed and half refuted**, and the halves matter: + +* ✅ **The state distinction is real.** A single Ⓐ on the title that ends the boot + sequence opens the main menu — **twice out of two**, in independent runs, one of + which never pressed F10 at all. On a title that the attract loop has come back + to, Ⓐ does nothing — as do START, B, BACK, X and Y — across dozens of presses, + every one delivered and none swallowed. +* ❌ **The tell is not in the drawing.** Capturing `log_ui_draws` in both states + in one run gives **13 quads each, at identical rects**, `ptbtn00` and + `ptbtn00f` included. The two titles are pixel-identical apart from the phase of + the rotating effect. Whatever gates the button is invisible to the renderer. + +So there is now a **reliable route to the main menu** — wait for the first title +after boot, tap Ⓐ once — which is what the second screen's capture needed, and it +is written into `tools/re-capture/`. Why the attract title stops accepting input +is still unexplained.