This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Syplheed-Reborn/docs/re/menu-navigation-semantics.md
Sylpheed RE agent dfcaac221e re: the new-game path completes, the intro is only weakly identified, and
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.
2026-08-28 19:19:14 +00:00

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 fromLOAD GAMELOAD GAME, TUTORIALTUTORIAL, OPTIONSOPTIONS, EXTRASEXTRAS 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 id1 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
  • DIFFICULTYEASY / NORMAL / HARD / BACK, footer Ⓐ : OK Ⓑ : Back, opening focused on NORMAL (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 NORMALSELECT DATA, a save-slot picker headed Current 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.