From c760cdc5096719e7532f8185f356270aa4209fd0 Mon Sep 17 00:00:00 2001 From: Sylpheed RE agent Date: Fri, 28 Aug 2026 18:53:14 +0000 Subject: [PATCH] re: the boot sequence is not data-driven -- closing Q6 with the negative rather than leaving it amber Q6's second half asked what the game READS to decide the boot order. The answer is nothing, and the value here is the reach rather than a find. Four places checked, the order in none of them: config.ini's [SYSTEM] is empty and it is the disc's only config; the movie manifest carries the boot-side assets but no transitions; the requested GamePart id was already shown to exist only as a stack argument in flight, with no persistent field and no literal store; and the string GP_ADVERTISE_DEMO has zero xrefs of any kind, so nothing in the code reads the attract entry of the id table. A transition is a call with an id argument. Traced as far as it goes cheaply: the RegisterToFactory<0, GamePart_Title> string is referenced from exactly one site, sub_8280E148, which also takes the address of sub_821C7D98 -- where a factory template puts its creator. Marked amber, because that is position and convention rather than proof, and sub_821C7D98 has zero .rdata references, which fits a new+ctor thunk and not a state machine. The substantial function in that neighbourhood is sub_821C6458 and I did not read it. So Q6 closes as answered with the driver classified as code rather than data, which means the port AUTHORS the sequence -- and that is fine, because the sequence itself is measured end to end and the handoff now carries it in one line. --- docs/port/HANDOFF.md | 11 +++++- docs/re/REFUTED.md | 3 ++ docs/re/boot-config-and-gamepart-registry.md | 41 ++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/docs/port/HANDOFF.md b/docs/port/HANDOFF.md index d1c2c03..9889016 100644 --- a/docs/port/HANDOFF.md +++ b/docs/port/HANDOFF.md @@ -32,7 +32,7 @@ authored version can be deleted. | Q3 | paint order for the six screens | ✅ answered | **decoded**: a `u16` layer key at `+0x0A` of each `T8aD` sprite header, stable-sorted with declaration index; unkeyed elements get an implied key. Confirmed on 5 measured orders + `EXTRAS` vs a capture. One residual: the **tie-break** is unknown and bites on one element of the title — [`structures/ui-paint-order-key.md`](../re/structures/ui-paint-order-key.md) | | Q4 | button → GamePart | ✅ answered | **measured** which screen all **5** buttons open — `NEW GAME` → `DIFFICULTY` → `SELECT DATA`, not a hang. The **GamePart id is still a name match**, not a measurement — [`menu-navigation-semantics.md`](../re/menu-navigation-semantics.md) | | Q5 | navigation semantics | ✅ answered | **measured**: initial focus varies boot to boot (2× `TUTORIAL`, 1× `NEW GAME`); ⬆⬇ one step, **wraps both ends**; ⬅➡ do nothing; Ⓑ returns to the parent **with focus restored**; Ⓑ on the main menu → title; Ⓑ on the title → nothing — [`menu-navigation-semantics.md`](../re/menu-navigation-semantics.md) | -| Q6 | boot sequence + what drives it | 🟡 partial | order observed and timed; the **manifest** gives the boot-side assets, **`config.ini`** the language, the **registration strings** which parts exist — but the *transitions* are in `GamePart_Title`'s code and are not decoded — [`boot-config-and-gamepart-registry.md`](../re/boot-config-and-gamepart-registry.md) | +| Q6 | boot sequence + what drives it | ✅ answered | sequence **measured** end to end; the driver is **code, not data** — four search spaces closed, so the port **authors** the sequence — [`boot-config-and-gamepart-registry.md`](../re/boot-config-and-gamepart-registry.md) | | Q7 | transitions | ✅ answered | a **fade through black**, drawn by the screen's own last-painting `.prm` quad. Fade-in ramp is **decoded** from its keyframes; the ~0.4 s fade-out is **measured** (not in the file) — [`screen-transitions.md`](../re/screen-transitions.md) | | Q8 | menu audio bindings | 🟡 mostly answered | the **UI cue vocabulary is decoded** (`SE_UI_CURSOR`/`DECIDE`/`CANSEL`/`IMPOSI`, all in `Static.slb` per `BANK_SE`); the event binding is a **name match**, and the SE audio is **not extractable yet** — [`menu-audio-cues.md`](../re/menu-audio-cues.md) | | Q9 | video binding + playback rules | ✅ answered | **decoded** from the movie manifest: `ADVERTISE_MOVIE`→`ADV.wmv` (boot intro *and* attract are one asset), `MS00A`→`S00A.wmv` is the new-game intro, `STAFF_ROLL`→the credits reel. ✅ **one Ⓐ skips a movie** (title at 57 s vs a 193 s baseline) — [`movie-binding.md`](../re/movie-binding.md) | @@ -161,6 +161,15 @@ authored version can be deleted. for all 7 620 other banks is simply absent, so an individual cue's wave is not locatable. Next step is `Pj_Silph.xgs` (in `sound.pak`, TOC 9454). +* **The boot sequence is not data-driven — the port authors it.** ❔ Four places + were checked and the order is in none: `config.ini`'s `[SYSTEM]` is empty, the + movie manifest carries assets not transitions, the requested GamePart id lives + **only as a stack argument in flight** (no persistent field, no literal store), + and the string `GP_ADVERTISE_DEMO` has **zero xrefs**. A transition is a call + with an id argument, chosen by code. The sequence itself is fully measured: + splash → `ADV.wmv` → title + `PRESS Ⓐ` → (idle ~8–10 s → `ADV.wmv` in full → + title) → Ⓐ → main menu, with Ⓑ from the main menu returning to the title. + * **`config.ini` picks the language, and that is what picks the EN/JP build.** The disc's **only** config file (400 bytes, at the root; one `find` over the whole extract). Its `[LANGUAGE]` section maps the console's `XC_LANGUAGE_*` diff --git a/docs/re/REFUTED.md b/docs/re/REFUTED.md index f932579..88e8097 100644 --- a/docs/re/REFUTED.md +++ b/docs/re/REFUTED.md @@ -35,6 +35,9 @@ neighbourhood, not just the line. ## Screens, classes and RTTI +* "the boot sequence is driven by a table the game reads" → it is **not + data-driven**; four search spaces closed, transitions are calls with an id + argument. [`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md) * "`config.ini` is a GamePart settings table, so the boot order is in it" → its `[SYSTEM]` section is **empty**; the only populated section is `[LANGUAGE]`. [`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md) diff --git a/docs/re/boot-config-and-gamepart-registry.md b/docs/re/boot-config-and-gamepart-registry.md index 36914d8..523e242 100644 --- a/docs/re/boot-config-and-gamepart-registry.md +++ b/docs/re/boot-config-and-gamepart-registry.md @@ -91,3 +91,44 @@ manifest gives the boot-side **assets** in play order the registry gives **which parts exist**. What decides to advance is in `GamePart_Title`'s own code, and reading it is a static PPC job that has not been started. + +## ❔ The transitions are code, not data — the reach of that negative + +Q6's remaining half asked what the game *reads* to decide the boot order. The +answer is: **nothing. It is not data-driven.** Four independent places were +checked, and the sequence is in none of them. + +| looked in | result | +|---|---| +| **disc configuration** | `config.ini` is the only config file on the disc, its `[SYSTEM]` section is empty (above) | +| **the movie manifest** | carries the boot-side *assets* in play order, and no transitions — [`movie-binding.md`](movie-binding.md) | +| **a persistent part-id field** | already refuted: the requested GamePart id exists **only as a stack argument in flight**, with no literal store anywhere — [`challenge-mission-gate.md`](challenge-mission-gate.md) §5 | +| **the id table's attract entry** | the string `GP_ADVERTISE_DEMO` at `0x820a1fe8` has **zero xrefs of any kind**; nothing in the code reads it | + +So a transition is a **call with an id argument**, chosen by code. There is no +table to read and nothing to poke. + +**Where that code is, as far as it was traced.** The `RegisterToFactory<0, class +silph::GamePart_Title>` diagnostic string at `0x820a3d60` is referenced from +exactly one place, `sub_8280E148` — the registration site — which also takes the +address of **`sub_821C7D98`** (`addi`), the position a factory template puts its +creator. 🟡 That identification is by position and convention, not proven; +`sub_821C7D98` itself has **0 `.rdata` references**, consistent with a small +`new`+ctor thunk rather than the state machine. The substantial function in the +same class neighbourhood is `sub_821C6458` (4 460 bytes, has EH, 15 `.rdata` +refs), and **reading it has not been attempted**. + +### What this means for the port + +The boot sequence is **authored**, not transcribed — and that is fine, because the +sequence itself is measured end to end: + +``` +developer splash (a RATC screen, not a video) + → ADV.wmv + → title + PRESS Ⓐ ──idle ~8–10 s──> fade to black → ADV.wmv in full → title + → Ⓐ → main menu +``` + +with the fade-through-black timings in [`screen-transitions.md`](screen-transitions.md) +and Ⓑ from the main menu returning to the title.