From 2be5ba79345b8486b333a9af31c91b6d8ec46c48 Mon Sep 17 00:00:00 2001 From: Sylpheed RE agent Date: Fri, 28 Aug 2026 19:42:39 +0000 Subject: [PATCH] re: the title part's states are named in the executable -- TITLE_SCREEN, TITLE_MENU, LOADING Taking the one residual I had ranked as worth doing: sub_821C6458, which the previous note left explicitly unread. It is the title part's screen-state function -- 4460 bytes, has EH, called from exactly one place, sub_821C7850, which sits beside the creator the registration site points at. Its string references are TITLE_SCREEN, TITLE_MENU, LOADING and BASE_INFO. Those are precisely the states measured off the running game, in the game's own words, and BASE_INFO is this corpus's own marker for a screen-config lookup rather than a table read. That sharpens Q6's negative rather than overturning it. The title part DOES ask for configuration keyed by TITLE_SCREEN and TITLE_MENU, and config.ini -- the disc's only config -- has no such sections, only an empty [SYSTEM] and [LANGUAGE]. So the game asks the question, the shipped disc does not answer it, and the defaults live in code. The port can transcribe the state names even though it must author their contents. Marked amber, not green: this is characterisation from string references and call counts, not a read of the control flow. Two self-references inside the function look like jump tables, which is what a state machine compiles to, but I did not confirm that and nothing here shows which state leads to which. One refutation recorded because it looked like a find for several minutes: the {func, func, ptr} triples at 0x820a3b48 read convincingly as a state/handler table and are nothing of the kind -- the bytes before them are the tail of a RegisterToFactory diagnostic string and the data column is zero-filled descriptors. Static-init records, not dispatch. --- docs/port/HANDOFF.md | 9 +++- docs/re/REFUTED.md | 5 ++ docs/re/boot-config-and-gamepart-registry.md | 57 ++++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/docs/port/HANDOFF.md b/docs/port/HANDOFF.md index 30e4401..4366e0c 100644 --- a/docs/port/HANDOFF.md +++ b/docs/port/HANDOFF.md @@ -193,7 +193,12 @@ authored version can be deleted. 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: + with an id argument, chosen by code. + 🟡 **The states do have names, though.** `sub_821C6458`, the title part's state + function, references `TITLE_SCREEN`, `TITLE_MENU` and `LOADING` — the three + states measured off the game, in the game's own words — and asks for screen + config under those keys. `config.ini` has no such sections, so the contents are + code defaults. The port can transcribe the **names**, not the values. 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. @@ -270,7 +275,7 @@ here until 2026-08-28 and is now settled.) | ❔ | **the other ~319 SE cues** (Q8) | located one at a time by triggering them; only the three the menu needs have been done | | 🟡 | **the paint-order tie-break** (Q3) | eight candidates refuted; costs one element's blend on one screen | | 🟡 | **GamePart ids behind the buttons** (Q4) | the *screens* are measured; the ids are a name match onto the executable's class names | -| ❔ | **the boot transitions in code** (Q6) | bounded as code-not-data, not proven. `sub_821C6458` — the substantial function in `GamePart_Title`'s neighbourhood — has **not been read** | +| 🟡 | **the boot transitions in code** (Q6) | `sub_821C6458` is the title's state function and **names its states** — `TITLE_SCREEN`, `TITLE_MENU`, `LOADING`. It asks for config under those keys and `config.ini` has no such sections, so the defaults are in code. Which state leads to which is still unread | | ❔ | **builds 0/1 and 10/11**, the `DELTASABER` plates (Q2) | never seen anywhere in the boot path, the title-side screens or the attract loop. A mission load is the remaining candidate and this container kills runs before one completes | (An earlier version of this table called the audio items blocked on "an emulator diff --git a/docs/re/REFUTED.md b/docs/re/REFUTED.md index 74e44db..2c239bd 100644 --- a/docs/re/REFUTED.md +++ b/docs/re/REFUTED.md @@ -35,6 +35,11 @@ neighbourhood, not just the line. ## Screens, classes and RTTI +* "the `{func, func, ptr}` triples at `0x820a3b48` are a GamePart state table" → + **static-initialiser records trailing the `RegisterToFactory` strings.** The + bytes before them are the tail of a diagnostic string and the data column is + zero-filled descriptors. + [`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md) * "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) diff --git a/docs/re/boot-config-and-gamepart-registry.md b/docs/re/boot-config-and-gamepart-registry.md index 523e242..050d87a 100644 --- a/docs/re/boot-config-and-gamepart-registry.md +++ b/docs/re/boot-config-and-gamepart-registry.md @@ -132,3 +132,60 @@ developer splash (a RATC screen, not a video) with the fade-through-black timings in [`screen-transitions.md`](screen-transitions.md) and Ⓑ from the main menu returning to the title. + + +## 🟡 `sub_821C6458` read — the title's states are NAMED in the executable + +The page above left this function as the named next step: "the substantial +function in `GamePart_Title`'s neighbourhood, and **reading it has not been +attempted**". It has now been looked at — not disassembled line by line, but +characterised, which is enough to sharpen Q6. + +**It is the title part's screen-state function.** 4 460 bytes, has EH, and called +from **exactly one** place — `sub_821C7850`, which sits in the same neighbourhood +as the creator the registration site points at (`sub_821C7D98`). It makes 33 +distinct calls. + +**What it names.** Its `.rdata` string references are: + +| string | at | +|---|---| +| **`TITLE_SCREEN`** | `0x820a3d3c` | +| **`TITLE_MENU`** | `0x820a3d30` | +| **`LOADING`** | `0x820a214c` | +| `BASE_INFO` (×2) | `0x820a20ec` | + +Those are the states measured off the running game, in the game's own words: the +title carrying `PRESS Ⓐ BUTTON`, the five-button menu, and a loading state. And +`BASE_INFO` is this corpus's own marker for a **screen-config lookup** rather than +a table read ([`REFUTED.md`](REFUTED.md), "`BASE_INFO` discriminates +screen-config from table-read, 9/9 vs 10/10"). + +### The sharper negative + +So the title part **does ask for configuration keyed by `TITLE_SCREEN` and +`TITLE_MENU`** — and [`config.ini`](#-configini--the-discs-only-config-and-it-selects-the-language), +the disc's only config file, contains **no such sections**. Its only sections are +an empty `[SYSTEM]` and `[LANGUAGE]`. The lookups find nothing, and the values are +whatever the code defaults to. + +That is a better answer than "the order is not in config": the game *asks the +question*, the shipped disc *does not answer it*, and the defaults live in code. +For the port it means the state **names** are transcribable even though their +contents are not. + +🟡 **Not ✅.** This is a characterisation from string references and call counts, +not a read of the control flow. Two self-references (`0x821c6498`, `0x821c6b7c`) +inside the function look like jump tables — a switch, which is what a state +machine compiles to — but that was **not confirmed**, and nothing here shows which +state leads to which. + +### 🔴 Refuted on the way, because it looked like a find + +The words at `0x820a3b48`… resolve as neat `{func, func, ptr}` triples and read +convincingly as a state/handler table. **They are not.** The bytes immediately +before them are the tail of +`…SaveLoad>::RegisterToFactory is failed!`, and the `0x8210c1xx` targets are +zero-filled descriptors — static-initialiser records trailing the registration +strings, not a dispatch table. A plausible-looking array of function pointers next +to relevant strings is not evidence of anything until its neighbours are read.