diff --git a/docs/re/BACKLOG.md b/docs/re/BACKLOG.md index 706d03e7..d1716e35 100644 --- a/docs/re/BACKLOG.md +++ b/docs/re/BACKLOG.md @@ -117,6 +117,18 @@ See [`structures/ui-composable-bundles.md`](structures/ui-composable-bundles.md) screen carrying exactly one primitive — the `GP_DIALOG` DIFFICULTY box, which is reachable from the main menu, would say whether its dim is first or last. This is a runtime child-list read, so it is an emulator item, not a static one. + 🔴 **ATTEMPTED 2026-08-19 and BLOCKED.** The reader + (`tools/re-capture/screen_children.py`) is written and validated — it + reproduces both known permutations character-for-character off the live title. + The screen could not be reached: **Ⓐ does not advance the title screen** at any + hold from 0.10 s to 0.40 s, nor does START, with the pad verified end to end. + Two harness bugs were found and fixed on the way (`--audio` is not a cvar and + broke eight boot scripts; `vgamepad` no longer exists but `skip_intro.sh` + still called it, pressing nothing while exiting 0). Neither unblocks the title. + Next step: boot with the emulator's stdout **kept** and check the + `[RE-INPUT] XamInputGetKeystrokeEx swallowed by IsUIActive` log already in the + canary branch. See + [`ui-paint-order-third-permutation.md`](ui-paint-order-third-permutation.md). * ❔ **Blend mode.** Everything is straight alpha-over. The near-white flash quads (`0xf0ffffff`) and coloured ones (`0x60ff0000`) may be additive. The title capture cannot separate the two — its resting elements are all diff --git a/docs/re/ui-paint-order-third-permutation.md b/docs/re/ui-paint-order-third-permutation.md new file mode 100644 index 00000000..fcf25692 --- /dev/null +++ b/docs/re/ui-paint-order-third-permutation.md @@ -0,0 +1,98 @@ +# A third measured paint order — tool built and validated, screen not reached + +**Status:** ✅ the reader works and is `CONFIRMED` against both previously +measured screens. 🔴 **BLOCKED** on the emulator: Ⓐ does not advance the title +screen, so `GP_DIALOG`'s DIFFICULTY box — the screen that would answer the +question — was never reached. Two harness bugs were found and fixed on the way. + +## Why a third permutation + +Drawing the `.prm` primitives is implemented and measurably right on the title, +but it is off by default because **nothing derives where a primitive paints** +([`structures/ui-prm-primitives.md`](structures/ui-prm-primitives.md)). A +primitive has no `T8aD` header, hence no layer key, and the two screens read off +the running game disagree about the answer: the splash paints its primitive +first, the title paints one at slot 4 and another last. + +`GP_DIALOG`'s DIFFICULTY box carries **exactly one** primitive, `pceff00.prm`, a +50 % black dim. Whether the game paints it first (dimming what is behind the +dialog) or last (dimming the dialog too) is a single bit that would discriminate +between the candidate rules. It is reachable from the main menu: NEW GAME. + +## The reader + +`tools/re-capture/screen_children.py` walks every resident screen object +(vtable `0x820b30b4`), reads the element array at `+0x08` (48-byte records, +declaration order) and the child array at `+0x30` (pointers to those records, +**paint** order), and prints the permutation with each element's pivot — which is +what identifies the build in the file. + +**Validated against both known-good screens in one run, off the live title:** + +``` +== object 0xbcd25288: 7 elements, 7 children + pivots: 0:(640,360) 1:(250,36) 2:(260,46) 3:(120,44) 4:(130,55) 5:(194,68) 6:(204,78) + paint order: [0, 2, 4, 6, 1, 3, 5] + +== object 0xbcd25488: 24 elements, 24 children + paint order: [9, 11, 12, 10, 13, 6, 20, 19, 14, 15, 18, 16, 17, 0, 2, 4, 7, 1, 3, 5, 22, 23, 21, 8] +``` + +Both are **character-for-character** what +[`structures/ui-screen-runtime.md`](structures/ui-screen-runtime.md) recorded +from the hand-driven read. So the next screen this is pointed at can be trusted. + +## Two harness bugs found on the way + +Both fail in ways that look like the *game* misbehaving. + +**`--audio` is not a cvar**, and eight boot scripts passed it. Xenia calls +`ShowSimpleMessageBox` from `ParseLaunchArguments`, *before* logging is +initialised, so the symptom is a 10×10 window, an empty log, no guest memory, and +a dialog blocking on `XIfEvent` forever — which reads as a hang deep in the +emulator. `run-canary`'s own header documents this trap; the scripts predate it. +Fixed in all eight, and the boot now reaches the title. + +**`vgamepad` no longer exists.** The uinput pad was replaced by the `--hid=file` +driver plus `pad.py`, but `skip_intro.sh` still called `vgamepad tap A 250`. The +script runs without `set -e`, so the call failed silently and the title branch +pressed **nothing** while still `exit 0` — reporting "TITLE → A" with the game +sitting on the title. Now presses through `pad.py` and exits 6 if that fails. + +That second bug looked like it would explain the standing "Ⓐ at the title works +about half the time" note. **It does not.** See below. + +## 🔴 The blocker: Ⓐ does not advance the title + +With the pad verified end to end — `pad.py` writes `/tmp/xenia_pad.txt`, the +emulator was launched with `--hid=file --pad_file=/tmp/xenia_pad.txt`, and the +file's mtime updates on every press — the title screen does not advance: + +| press | hold | result | +|---|---|---| +| Ⓐ ×2 | 0.10 s | still title | +| Ⓐ | 0.25 s | still title | +| Ⓐ ×5 | 0.40 s | still title | +| START | 0.30 s | still title | + +The screen is unambiguously the interactive one — PRESS Ⓐ BUTTON is rendered +([capture](captures/title-with-press-a-live.png)). So the input path is wired and +the game is waiting for a press it never sees. + +The most likely suspect is already instrumented but was not captured this run: +the `[RE-INPUT] XamInputGetKeystrokeEx swallowed by IsUIActive` log added to +`xam_input.cc` on the canary branch. `boot_menu.sh` sends the emulator's stdout +to `/dev/null`, so nothing was recorded. **That is the first step next time:** +boot with stdout kept and check whether the keystroke is being swallowed, which +would make this an emulator-side bug rather than a game-side one. + +## What is not settled + +* 🔴 The third permutation itself. The tool is ready; the screen is not reachable. +* ❔ Whether Ⓐ ever worked at this title screen, or whether the "half the time" + note was always the silent `vgamepad` failure plus chance. The `vgamepad` bug + is now excluded, and the title still does not advance, so something else is + wrong. +* ❔ Only **one** screen object was resident at the moment the main menu was + believed to be up (the splash), where the title has seven. Unexplained, and + possibly a symptom of the same thing — the menu may never have loaded.