this container kills long runs Three results, and the middle one is deliberately not upgraded. First: NEW GAME -> DIFFICULTY -> NORMAL -> SELECT DATA -> pick a slot -> a movie plays, with no crash. The previous run's throw at 0x82307128 is therefore not inherent to the menu path -- the same six presses got through it -- which fits the incomplete-cache trigger the corpus already names. n=1 either way, and the note says so. Worth recording because one observation had already hardened once into "A on NEW GAME hangs", and it would have hardened again into "the new-game path crashes". Second: with the path open, the manifest's MS00A -> S00A.wmv finally got a runtime test, and it did NOT reproduce the quality of the attract-movie identification. The first four samples give a clean monotonic S00A playhead of 2, 6, 9, 13 s and the strongest frame matches at 0.916, but the run as a whole is not one advancing timeline, most frames sit at contrast 23-37 where this page's own rule says discrimination is poor, and one high-contrast frame prefers ADV. So it stays amber: consistent with S00A, corroborating the manifest decode, not confirming it. A clean answer needs the 30fps x11grab route rather than 5-second screenshots. Third, and it bounds the rest: the emulator vanished at ~145 s with no crash line in its own log, last entries routine MEM-WATCH at 1.15 GB RSS. Second time this session -- the other was ~50 s into a boot. That is an external kill on a box with ~1 GB free and swap exhausted, not a guest fault. METHOD and the handoff's residue table both now say dynamic experiments here have to fit in about two minutes of guest time, which is why the DELTASABER plates went unseen again: they need a mission load and the run never got there.
7.4 KiB
The title menu — how it moves, and where each button goes
Status: ✅ CONFIRMED (measured, by driving the running game) for the
movement rules and for four of the five main-menu destinations. 🟡 the GamePart
id behind each destination is a name match onto the decoded id table, not a
measurement. ❔ NEW GAME deliberately untested.
Answers MISSION Q5 and most of Q4. Nothing here is on the disc in any form found so far — the port is authoring these rules from this page, not transcribing a field.
Q5 — movement
Two boots via tools/re-capture/boot_menu.sh, cursor read off the focus ring
with tools/re-capture/menu_focus.py.
| behaviour | evidence | |
|---|---|---|
| initial focus, main menu | TUTORIAL — the middle item, not the top |
2/2 boots, the first frame after the menu appears |
initial focus, EXTRAS |
MISSION SELECT — the top item |
extras-wrap.png |
| up / down | one item per press, no auto-repeat at the durations tried | |
| wrap at the top | ⬆ from the first item goes to the last | wrap-montage.png, panels 1→2 |
| wrap at the bottom | ⬇ from the last item goes to the first | same, panels 3→4, and 4 presses from EXTRAS landing on OPTIONS — i.e. wrapping — is what makes the count come out |
| left / right | nothing, on the main menu | cursor unmoved across one ⬅ and one ➡ |
| Ⓑ on a submenu | returns to the parent with focus restored to the item you entered from — LOAD GAME→LOAD GAME, TUTORIAL→TUTORIAL, OPTIONS→OPTIONS, EXTRAS→EXTRAS |
4/4 |
| Ⓑ on the main menu | goes to the title, which re-draws PRESS Ⓐ BUTTON after a beat |
|
| Ⓑ on the title | nothing |
Wrap holds on both screens tested — the 5-item main menu and the 3-item EXTRAS
submenu — so it is a menu rule, not a per-screen table.
🟡 Initial focus is reproducible but not established as invariant. Both of my
boots opened on TUTORIAL, and both used boot_menu.sh. The run recorded in
menu-state-in-memory.md reached EXTRAS with four
downs from the main menu, which only works from NEW GAME. Either the harness
path matters or something persists. Do not hardcode TUTORIAL without
re-testing it; what is solid is that the menu does not open on the top item
in this harness.
Q4 — where each button goes
Measured by driving: focus the item, press Ⓐ, read the screen's own title.
| button | screen it opens | evidence | GamePart id |
|---|---|---|---|
NEW GAME |
❔ not tested | — | — |
LOAD GAME |
the save-slot list, LOAD GAME / Current Storage |
q4-destinations.png left |
🟡 3 GP_LOAD |
TUTORIAL |
the lesson list, TUTORIAL, Level 1 / Level 2 |
same, middle | 🟡 25 GP_TUTORIAL |
OPTIONS |
OPTIONS — GAME / CONTROL / SOUND / SCREEN SETTINGS / BACK |
same, right | 🟡 8 GP_OPTIONS |
EXTRAS |
GP_TITLE.pak build 6 — MISSION SELECT / MOVIE THEATER / BACK |
ui-title-build-map.md |
🟡 5 GP_EXTRAS |
EXTRAS ▸ MISSION SELECT |
the stage list + Wide Area Space Map | 🟡 7 GP_MISSION_SELECT |
|
EXTRAS ▸ MOVIE THEATER |
❔ not tested | 🟡 6 GP_MOVIE_THEATER |
Say which, as the gate asks. The screen each button opens is measured —
I pressed the button and read the title off the framebuffer. The GamePart id is
not measured: it is the entry of the decoded 29-id table at .rdata 0x820A1630
(challenge-mission-gate.md §3) whose name matches
the screen I saw. The table is decoded; the binding of a button to an entry in
it is a name match I made by eye. The port should treat these ids as authored.
Worth noting that the ids and the paks are not one-to-one: GP_EXTRAS is id 5
with no pak of its own — its artwork is a build inside GP_TITLE.pak.
❔ NEW GAME was deliberately not pressed. Ⓐ on it leads to a standing
black-screen hang that ends the run
(ui-paint-order-third-permutation.md),
and this iteration needed the session. It is the one destination still unmeasured.
The cheap way to finish this, and to make it a measurement
0x828A690C holds a live screen id — 1 title, 3 main menu, 4 extras —
and 0x828F38AC the cursor (menu-state-in-memory.md).
Reading those while pressing Ⓐ turns "the screen said OPTIONS" into a measured
transition, and works under --gpu=null with no screenshots at all. ⚠️ Note that
those values are not GamePart ids — GP_TITLE is GamePart 0 and GP_EXTRAS
is 5, but the word reads 1 and 4 — so it is a third enumeration and mapping it to
the id table is itself unfinished work.
✅ NEW GAME — measured 2026-08-28, and it is not a hang
The one destination this page could not test has been driven. Ⓐ on NEW GAME
does not hang. It opens two more menus first:
NEW GAME -> DIFFICULTY -> SELECT DATA -> guest crash
DIFFICULTY—EASY/NORMAL/HARD/BACK, footerⒶ : OK Ⓑ : Back, opening focused onNORMAL(capture). It sat unchanged for 90 s with the emulator healthy — a menu waiting for input, which is exactly what "a standing hang" looks like to a screenshot loop that never presses anything.- Ⓐ on
NORMAL→SELECT DATA, a save-slot picker headedCurrent Storage: Dummy HDD, prompting to pick a file for the auto-save. - Then the guest throws, and Xenia pauses with
PC: 0x82307128(capture).
That crash is already in the corpus and is not new: 0x82307128 is inside
sub_823070B0, the cache-manager STL erase documented in
title-crash-stl-tree.md, whose trigger is an
incomplete on-disc shader/code cache — not the menu path. The corpus also already
holds captures/select-data-crash.png.
So Q4's last row closes as measured:
| button | screen it opens |
|---|---|
NEW GAME |
DIFFICULTY (then SELECT DATA) |
🟡 The GamePart ids for these two are unmeasured, like the rest — 24 GP_DIALOG
and 3 GP_LOAD / 2 GP_SELECT_STORAGE are name-match candidates and nothing
more.
Initial focus — a fourth data point, and it still varies
This boot opened the main menu on NEW GAME. Running tally across four
boots of the same harness: TUTORIAL, TUTORIAL, NEW GAME, NEW GAME.
Unchanged conclusion: do not hardcode it.
The NEW GAME path completes — the SELECT DATA crash is state, not path
A second run of the same path, 2026-08-28, did not crash:
NEW GAME → DIFFICULTY → (Ⓐ on NORMAL) → SELECT DATA → (Ⓐ on a slot) → a movie plays
The previous run's throw at PC 0x82307128 is therefore not inherent to this
menu path — the same six presses got through it. That is consistent with the
trigger title-crash-stl-tree.md already names (an incomplete on-disc cache) and
with nothing about NEW GAME. 🟡 n = 1 either way; do not read it as "fixed".
Worth recording because the first observation could easily have hardened into "the new-game path crashes", which is what "A on NEW GAME hangs" had already become once.