diff --git a/crates/sylpheed-formats/src/ui_layout.rs b/crates/sylpheed-formats/src/ui_layout.rs index 2d25c97e..d5ef2dc3 100644 --- a/crates/sylpheed-formats/src/ui_layout.rs +++ b/crates/sylpheed-formats/src/ui_layout.rs @@ -728,6 +728,22 @@ fn measured_paint_order(build: &UiBuild) -> Option> { // the full-screen .prm, then all three glows, then the three logos. return Some(vec![0, 2, 4, 6, 1, 3, 5]); } + // GP_TITLE.pak ratc-index 8 — the MAIN MENU (NEW GAME / LOAD GAME / + // TUTORIAL / OPTIONS / EXTRAS). Read off the running game 2026-08-19; it is + // the third measured permutation and the first that contains TWO + // primitives, which is why it matters — see `ui-prm-primitives.md`. + const MENU: [&str; 16] = [ + "pteff00.prm", "ptbase.t32", "pteff05.t32", "ptloop01.rat", + "ptloop02.rat", "pteff02.prm", "ptframe1.t32", "ptframe2.t32", + "pteff10.t32", "pteff12.t32", "ptbtn01.rat", "ptbtn02.rat", + "ptbtn03.rat", "ptbtn04.rat", "ptbtn05.rat", "ptmsg.t32", + ]; + if names == MENU { + // background, the two loops, the full-screen effect, the DIM quad, + // the glows, the frames, the message, the five buttons, and the + // screen-transition FADE quad last. + return Some(vec![1, 3, 4, 2, 5, 8, 9, 6, 7, 15, 10, 11, 12, 13, 14, 0]); + } None } diff --git a/docs/re/captures/main-menu-oracle.png b/docs/re/captures/main-menu-oracle.png new file mode 100644 index 00000000..64ae86f9 Binary files /dev/null and b/docs/re/captures/main-menu-oracle.png differ diff --git a/docs/re/captures/ui-layout/main-menu-composited.png b/docs/re/captures/ui-layout/main-menu-composited.png new file mode 100644 index 00000000..bfc15e93 Binary files /dev/null and b/docs/re/captures/ui-layout/main-menu-composited.png differ diff --git a/docs/re/structures/ui-paint-order-key.md b/docs/re/structures/ui-paint-order-key.md index bec2c8ee..5169cd1e 100644 --- a/docs/re/structures/ui-paint-order-key.md +++ b/docs/re/structures/ui-paint-order-key.md @@ -133,3 +133,62 @@ measured screens would be the entire evidence base; instead a third of the disc' screens now composite in an order no capture has checked. The test asserts the share stays above a quarter, so a future change that quietly collapses the rule back to declaration order fails here instead of passing silently. + + +## A third measured permutation — the main menu (2026-08-19) + +Read off the running game with `tools/re-capture/screen_children.py`, and +identified in the file by its pivot signature: **`GP_TITLE.pak` ratc-index 8**, +the NEW GAME / LOAD GAME / TUTORIAL / OPTIONS / EXTRAS screen, 16 elements. + +``` +paint order (child slots): 1 3 4 2 5 8 9 6 7 15 10 11 12 13 14 0 +``` + +| slot | element | | slot | element | +|---|---|---|---|---| +| 0 | 1 `ptbase.t32` | | 8 | 7 `ptframe2` | +| 1 | 3 `ptloop01` | | 9 | 15 `ptmsg` | +| 2 | 4 `ptloop02` | | 10–14 | 10–14 `ptbtn01`…`ptbtn05` | +| 3 | 2 `pteff05` | | 15 | **0 `pteff00.prm`** | +| 4 | **5 `pteff02.prm`** | | | | +| 5–7 | 8 `pteff10`, 9 `pteff12`, 6 `ptframe1` | | | | + +**This is the first measured screen with TWO primitives**, and they land in +different places — which is the point. `pteff02.prm` (the 25 % black dim) paints +4th, beneath the whole UI; `pteff00.prm` (the screen-transition fade, resting +transparent) paints **last**. Both match their positions on the title screen +exactly, where `pteff02.prm` is also slot 4 and `pteff00.prm` is also last. + +So a primitive's place is **per-element and stable by role** across screens: + +| primitive | role | measured position | +|---|---|---| +| `palogo_eff0.prm` | opaque black backdrop | **first** (splash) | +| `pteff02.prm` | 25 % dim under the UI | **slot 4** (title *and* menu) | +| `pteff00.prm` | screen-transition fade | **last** (title *and* menu) | + +It is still not *derived* — a primitive has no `T8aD` header and so no layer key +— but there are now three permutations to test a candidate against instead of +two, and the candidate has to live in the 60-byte declaration entry. + +### Verified against the live capture + +The order is wired into `measured_paint_order` (keyed by element names, so both +language builds get it). Composited with `--primitives` and edge-correlated +against a framebuffer capture taken in the same session +([capture](../captures/main-menu-oracle.png), +[composite](../captures/ui-layout/main-menu-composited.png)): + +> **0.9591 at shift (0, 0)** + +That is a *third* screen confirming the whole stack at once — paint order, +resting pose, `fade` alpha and primitives — on a capture this project had not +seen before. + +### Not settled + +* ❔ `ptframe1`/`ptframe2` rest at `0x00ffffff` (alpha 0) and are therefore not + drawn, but the capture shows the menu frame plainly. Either the resting rule + picks the wrong plateau for them or the frame is drawn by something else. +* ❔ The derivation for primitives. Three permutations now, still no rule.