re: what the game actually reads at boot -- config.ini, and which

GameParts exist at all

Q6's second half, advanced but not closed, and the negative is the point.

config.ini is the disc's ONLY config file -- one find over the whole
extract -- and its own Shift-JIS header calls it the "Application /
GamePart initial settings table". Its [SYSTEM] section, which that same
comment says holds what the game and every game part share, is EMPTY. So
the boot order is not in disc-side configuration at all, and that search
space is now closed rather than merely unexplored.

What the file DOES carry is the language: XC_LANGUAGE_* -> eng/jpn/deu/
fra/esp/ita, defaulting to eng. That is the mechanism behind the EN/JP
build pairs in GP_TITLE and the <lang>.pak families -- a question the
corpus had described but never traced to its input.

Then the registry. Pulling every RegisterToFactory diagnostic string
binds 24 of the 29 GamePart ids to a C++ class, and five ids have no
registration site: 1, 2, 16, 18, 28. Id 1 is GP_ADVERTISE_DEMO, which
agrees with what I measured two iterations ago -- the attract loop is the
TITLE replaying ADV.wmv, not a transition into an advertise part. Marked
amber, not green: it is an argument from an error message, not from code.

Two things fall out for Q4: ids 3 and 4 are the same class
(GamePart_SaveLoad, one part with two ids), and the menu buttons' ids now
match the executable's own class names rather than a list of table names.
Still a name match, one level closer to the code.

What is still missing is the transitions themselves, and I say so: the
manifest gives the boot-side assets, config.ini the language, the
registry which parts exist. What decides to advance is in
GamePart_Title's code and that dig has not been started.
This commit is contained in:
Sylpheed RE agent
2026-08-28 18:49:19 +00:00
parent 935f7ecab8
commit c8e8dc0427
5 changed files with 151 additions and 1 deletions

View File

@@ -153,6 +153,7 @@ files, which is how the same ground got covered twice.
| [`menu-navigation-semantics.md`](menu-navigation-semantics.md) | The title menu — how it moves, and where each button goes | ✅ measured: wraps both ends, Ⓑ restores focus, ⬅➡ inert; 4 of 5 destinations driven. 🟡 GamePart id is a name match, ❔ `NEW GAME` untested |
| [`screen-transitions.md`](screen-transitions.md) | Between two screens — a fade through black, and where its timing lives | ✅ the fade quad's keyframe group is decoded (disc-wide: per-pak all-or-nothing; `GP_TITLE` = the 6 screens, not the 6 overlays); the ~0.4 s fade-OUT is measured, not on the disc |
| [`menu-audio-cues.md`](menu-audio-cues.md) | Menu audio — the event vocabulary is on the disc, the binding is not | ✅ `SE_UI_*` cue names/ids decoded and `BANK_SE``Static.slb` (0/322 in FILES); 🟡 event binding is a name match; ❔ `Static.slb` has no wave boundaries, so SE audio is not extractable |
| [`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md) | What the game reads at boot — `config.ini`, and which GameParts exist | ✅ `config.ini` selects the language (the disc's only config); ❔ its `[SYSTEM]` is empty so the boot order is not in config; 🟡 24/29 ids bind to a class, `GP_ADVERTISE_DEMO` is never registered |
| [`movie-binding.md`](movie-binding.md) | Which movie plays where — boot intro, attract loop, new-game intro | ✅ decoded from the movie manifest (`ADVERTISE_MOVIE``ADV.wmv`, `MS00A``S00A.wmv`); attract identity confirmed independently by frame matching; 🟡 skippability unsettled |
| [`ready-room-probe.md`](ready-room-probe.md) | S1 — the Ready Room probe: no-go, and not for the reason expected | ✅ it is 2D and enumerates (60 builds), but the pak is briefing/tactical-map content; and `kind == 0x3002` finds 0 buttons there |
| [`ui-title-build-map.md`](ui-title-build-map.md) | Which `GP_TITLE` build is which screen state | ✅ CONFIRMED for title / `PRESS Ⓐ` / main menu / `EXTRAS` against live captures; the archive is 8 screens × EN/JP, and "6/8/9 are submenus" is withdrawn |

View File

@@ -35,6 +35,14 @@ neighbourhood, not just the line.
## Screens, classes and RTTI
* "`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)
* "the attract loop is `GP_ADVERTISE_DEMO` (GamePart 1)" → 🟡 id 1 has **no
registration site** in the shipped build; the attract is the title replaying
`ADV.wmv`.
* "the 29 id-table names are 29 distinct GameParts" → 24 register, and `3`/`4`
are the **same class** (`GamePart_SaveLoad`).
* "Ⓐ on `NEW GAME` leads to a standing black-screen hang" → it opens
**`DIFFICULTY`**, then **`SELECT DATA`**. What looked like a hang was a menu
waiting for input that nobody pressed; the crash that follows is the already

View File

@@ -0,0 +1,93 @@
# What the game reads at boot — `config.ini`, and which GameParts actually exist
**Status:**`CONFIRMED` and **decoded** for the language selection. ❔ a bounded
**negative** for the boot *order*. 🟡 for what the registration strings imply
about the attract loop.
Contributes to [MISSION Q6](../port/MISSION.md), and firms up Q4's ids.
## ✅ `config.ini` — the disc's only config, and it selects the language
`config.ini` sits at the **disc root**, is 400 bytes, and is the **only** `.ini`,
`.cfg` or `.txt` anywhere on the disc. Its own header comment (Shift-JIS) names
it:
> `アプリケーション/ゲームパート初期設定テーブル`
> — *"Application / GamePart initial settings table"*
>
> `SYSTEM セクションには、ゲーム及び各ゲームパートで共通にアクセスする情報を記述する`
> — *"the SYSTEM section describes information accessed in common by the game and
> each game part"*
```ini
[SYSTEM]
[LANGUAGE]
= eng ; default
#0x01 = eng ; XC_LANGUAGE_ENGLISH
#0x02 = jpn ; XC_LANGUAGE_JAPANESE
#0x03 = deu ; XC_LANGUAGE_GERMAN
#0x04 = fra ; XC_LANGUAGE_FRENCH
#0x05 = esp ; XC_LANGUAGE_SPANISH
#0x06 = ita ; XC_LANGUAGE_ITALIAN
```
**This is the mechanism behind the EN/JP screen pairs.** The console's
`XC_LANGUAGE_*` setting selects a three-letter code, and that code is what picks
`GP_TITLE`'s English or Japanese build ([`ui-title-build-map.md`](ui-title-build-map.md))
and the `<lang>.pak` families. Default is `eng`, keyed by the empty line — an
unlisted language falls back to English. ✅ decoded. The executable does read the
file: the string `config.ini` is at `.rdata 0x82062b44`.
## ❔ But the boot ORDER is not in it — and this is the whole search space
`[SYSTEM]` — the section the file's own comment says holds what the game and every
game part share — is **empty**. So the file the game itself calls the *GamePart
initial settings table* says nothing about which part runs first or what follows
what.
**Reach of the negative:** this is the only config file on the disc (one `find`
over the whole extract). The boot order is therefore not in disc-side
configuration at all; it is in code, or in a table inside the executable that has
not been located.
## 🟡 `GP_ADVERTISE_DEMO` is never registered — the attract loop is not its own part
The executable carries one diagnostic string per GamePart registration site
(`silph::GamePartTask::RegisterToFactory<N, class silph::GamePart_X>::RegisterToFactory is failed!`)
— the same evidence the corpus used to pin the id table
([`challenge-mission-gate.md`](challenge-mission-gate.md) §3). Extracting all of
them gives **24 of the 29 ids bound to a C++ class**; full list in
[`data/gamepart-class-ids.txt`](data/gamepart-class-ids.txt).
**The five ids with no registration site are `1`, `2`, `16`, `18`, `28`** — in the
id table's naming, `GP_ADVERTISE_DEMO`, `GP_SELECT_STORAGE`, `GP_DEMO`,
`GP_SELECTOR`, `GP_TEST`.
That `GP_ADVERTISE_DEMO` (1) is among them matters for Q6, and it agrees with
what was measured: the attract loop is **the title screen replaying `ADV.wmv`**
([`movie-binding.md`](movie-binding.md)), not a transition into a separate
advertise part. The id table names a part the shipped build never registers.
🟡 **not ✅**, because this is an argument from a *diagnostic string*: no error
message for id 1 implies no registration site for id 1. That is how the corpus
already reads these strings, and it is sound, but it is not the code.
### Two bonuses for Q4
* **`3` and `4` are the same class** — `GamePart_SaveLoad` is registered twice.
The id table's separate `GP_LOAD` / `GP_SAVE` names are two ids on one part.
* The ids behind the menu buttons now match the executable's own **class** names,
not just a list of table names: `GamePart_Options` = 8, `GamePart_Tutorial` =
25, `GamePart_Extras` = 5, `GamePart_MissionSelect` = 7,
`GamePart_MovieTheater` = 6, `GamePart_Title` = 0. Still a **name match**
screen title ↔ class name — but anchored one level closer to the code.
## What is still missing for Q6
The *transitions*. Nothing found so far says "title, then movie, then title" — the
manifest gives the boot-side **assets** in play order
([`movie-binding.md`](movie-binding.md)), `config.ini` gives the **language**, and
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.

View File

@@ -0,0 +1,29 @@
GamePart ids bound to a C++ class by the executable's own registration strings
(24 strings, 24 distinct ids)
0 GamePart_Title
3 GamePart_SaveLoad
4 GamePart_SaveLoad
5 GamePart_Extras
6 GamePart_MovieTheater
7 GamePart_MissionSelect
8 GamePart_Options
9 GamePart_Movie
10 GamePart_Bunk
11 GamePart_ReadyRoom
12 GamePart_Hangar
13 GamePart_Arsenal
14 GamePart_PilotLog
15 GamePart_System
17 GamePart_MainGame
19 GamePart_PauseMenu
20 GamePart_StageClear
21 GamePart_MissionLog
22 GamePart_GameOver
23 GamePart_Debriefing
24 GamePart_Dialog
25 GamePart_Tutorial
26 GamePart_ChallengeMission
27 GamePart_Leaderboard
ids 0..28 with NO registration string: [1, 2, 16, 18, 28]