# 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](../port/MISSION.md) 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`](../../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`](captures/menu-nav/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`](captures/menu-nav/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`](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`](captures/menu-nav/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`](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`](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`](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`](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.