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.