re: there is no XACT container on this disc -- retracting my own lead and
closing Q8 Last iteration I named Pj_Silph.xgs as the route to the SE cue index, on the reasoning that XACT keeps cue->wave there. That route is dead, and the negative is properly bounded: its 533-byte entry is high entropy with no XGSF magic, +/-8 KB around it has none either, all 1.08 GB of sound.pak contains zero XGSF, SDBK and WBND, and the executable has no XACT or .xgs string anywhere. Control run first -- the same scan finds RIFF in BGM_001 exactly where the bank structure says it should be, so the scan works and the magic genuinely is not there. So the .xgs and .slb extensions came from the authoring tool and survived into shipped data that is not XACT at all. That goes in METHOD as a general trap: check for the magic before committing to a parser for the format an extension advertises. Writing an XACT parser would have been wasted work. What that leaves for the SE audio is undecodable-with-reach rather than pending: Static.slb has no wave boundaries, there is no project file, and none of the sound table's five records carries an offset. The bank is certainly the right one -- 8 353 472 bytes over 322 cues is 0.84 to 1.01 seconds each at the bitrates the disc uses elsewhere, exactly the shape of a bank of short effects. Only the index into it is missing, and it exists only at runtime. Q8 closes: vocabulary and bank decoded, the event binding a name match on the authors' own event names, and the audio explicitly something the port must source or author rather than extract. With this every MISSION row is answered.
This commit is contained in:
@@ -34,7 +34,7 @@ authored version can be deleted.
|
|||||||
| 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) |
|
| 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 | ✅ 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) |
|
| 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) |
|
| 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) |
|
| Q8 | menu audio bindings | ✅ answered | cue vocabulary + bank **decoded**; event binding is a **name match** (the authors' own event names); SE audio is **undecodable from the disc** — no XACT container exists anywhere — [`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) |
|
| 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) |
|
||||||
| Q10 | music-bank sub-wave roles (intro+loop?) | ✅ answered | **two stems of one performance, played together** — sample-synchronous, equal duration, 32/32 banks. **Concatenating is wrong.** Not a seamless loop either — [`structures/bgm-two-stems.md`](../re/structures/bgm-two-stems.md) |
|
| Q10 | music-bank sub-wave roles (intro+loop?) | ✅ answered | **two stems of one performance, played together** — sample-synchronous, equal duration, 32/32 banks. **Concatenating is wrong.** Not a seamless loop either — [`structures/bgm-two-stems.md`](../re/structures/bgm-two-stems.md) |
|
||||||
| S1 | Ready Room go/no-go | ✅ **no-go** | it is 2D and enumerates fine (60 builds), but `GP_READY_ROOM.pak` holds **briefing/tactical-map** content, not the six-button Ready Room menu — [`ready-room-probe.md`](../re/ready-room-probe.md) |
|
| S1 | Ready Room go/no-go | ✅ **no-go** | it is 2D and enumerates fine (60 builds), but `GP_READY_ROOM.pak` holds **briefing/tactical-map** content, not the six-button Ready Room menu — [`ready-room-probe.md`](../re/ready-room-probe.md) |
|
||||||
@@ -156,10 +156,15 @@ authored version can be deleted.
|
|||||||
🟡 **Which event fires which cue is a name match**, not a measurement — strong,
|
🟡 **Which event fires which cue is a name match**, not a measurement — strong,
|
||||||
because these are the authors' own event names, but nobody has watched the game
|
because these are the authors' own event names, but nobody has watched the game
|
||||||
emit cue 2 on a d-pad press. The port is authoring it.
|
emit cue 2 on a d-pad press. The port is authoring it.
|
||||||
❔ **The SE audio cannot be exported yet.** `Static.slb`'s 8 353 472 readable
|
❔ **The SE audio cannot be exported at all from the disc.** `Static.slb`'s
|
||||||
bytes contain **0 `RIFF`, 0 `seek`, 0 `WAVE`** — the boundary marker that works
|
8 353 472 readable bytes contain **0 `RIFF`, 0 `seek`, 0 `WAVE`** — the boundary
|
||||||
for all 7 620 other banks is simply absent, so an individual cue's wave is not
|
marker that works for all 7 620 other banks is absent — and there is **no XACT
|
||||||
locatable. Next step is `Pj_Silph.xgs` (in `sound.pak`, TOC 9454).
|
container anywhere**: 0 × `XGSF`/`SDBK`/`WBND` across all 1.08 GB of
|
||||||
|
`sound.pak`, and no `XACT`/`.xgs` string in the executable. The `.xgs`/`.slb`
|
||||||
|
names come from the authoring tool, not the shipped format. The bank is
|
||||||
|
certainly the right one — 8 353 472 B over 322 cues is 0.84–1.01 s each at the
|
||||||
|
disc's own bitrates — but the index into it exists only at runtime. **The UI
|
||||||
|
sound effects must be sourced or authored; they cannot be extracted.**
|
||||||
|
|
||||||
* **The boot sequence is not data-driven — the port authors it.** ❔ Four places
|
* **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
|
were checked and the order is in none: `config.ini`'s `[SYSTEM]` is empty, the
|
||||||
|
|||||||
@@ -178,3 +178,9 @@ agent's loop prompt, i.e. nowhere durable. See [`README.md`](README.md) for the
|
|||||||
processes carries the whole loop prompt as its argv, so the listing is tens of
|
processes carries the whole loop prompt as its argv, so the listing is tens of
|
||||||
kilobytes of the prompt you already have. Use `pgrep -x <name>` or
|
kilobytes of the prompt you already have. Use `pgrep -x <name>` or
|
||||||
`ps -o pid=,stat= -C <name>`.
|
`ps -o pid=,stat= -C <name>`.
|
||||||
|
* **A file extension is not a format.** `sound.pak` is full of `.slb` banks and
|
||||||
|
names a `.xgs` project, and neither is an XACT container: the whole 1.08 GB
|
||||||
|
archive contains zero `XGSF`, `SDBK` or `WBND` magic, and the executable has no
|
||||||
|
XACT string at all. The names came from the authoring tool and survived into the
|
||||||
|
shipped data. Check for the magic before committing to a parser for the format
|
||||||
|
the extension advertises.
|
||||||
|
|||||||
@@ -158,6 +158,11 @@ neighbourhood, not just the line.
|
|||||||
|
|
||||||
## Audio
|
## Audio
|
||||||
|
|
||||||
|
* "`Pj_Silph.xgs` holds the cue→wave index, so parse XACT" → **no XACT container
|
||||||
|
exists on this disc**: 0 × `XGSF`/`SDBK`/`WBND` in all 1.08 GB of `sound.pak`,
|
||||||
|
and no `XACT`/`.xgs` string in the executable. The extensions are the authoring
|
||||||
|
tool's, not the format's. [`menu-audio-cues.md`](menu-audio-cues.md)
|
||||||
|
|
||||||
* "every sound cue resolves to its own `.slb` bank" → the 322 `SE_*` cues do not;
|
* "every sound cue resolves to its own `.slb` bank" → the 322 `SE_*` cues do not;
|
||||||
**0 of 322** are in `FILES`, and `BANK_SE` puts them all in `Static.slb`.
|
**0 of 322** are in `FILES`, and `BANK_SE` puts them all in `Static.slb`.
|
||||||
* "`Static.slb` can be split into waves like any other bank" → it holds **0
|
* "`Static.slb` can be split into waves like any other bank" → it holds **0
|
||||||
|
|||||||
@@ -98,3 +98,47 @@ parsing XACT.
|
|||||||
* which BGM plays on which screen is **authored** — nothing on the disc says;
|
* which BGM plays on which screen is **authored** — nothing on the disc says;
|
||||||
* and the UI **sound effects cannot be exported yet**. That is a gap in the
|
* and the UI **sound effects cannot be exported yet**. That is a gap in the
|
||||||
assets, not in the naming.
|
assets, not in the naming.
|
||||||
|
|
||||||
|
## ❔ `Pj_Silph.xgs` is a dead end — retracting the lead, with the reach
|
||||||
|
|
||||||
|
The section above named `Pj_Silph.xgs` as "the named next step", on the reasoning
|
||||||
|
that in XACT the cue→wave index lives in the project file. **That route is dead.**
|
||||||
|
|
||||||
|
| check | result |
|
||||||
|
|---|---|
|
||||||
|
| the entry's own bytes | 533 bytes, high entropy, **no `XGSF` magic** |
|
||||||
|
| ±8 KB around the entry in the flat concatenation | no `XGSF`, `SDBK`, `WBND`, `RIFF` or `seek` |
|
||||||
|
| **all of `sound.pak` — 1.08 GB across `.p00`–`.p04`** | **0 × `XGSF`, 0 × `SDBK`, 0 × `WBND`** |
|
||||||
|
| the executable | **0** occurrences of `XGSF`/`XACT`; no string matching `xact`, `.xgs`, `wavebank` or `soundbank` |
|
||||||
|
|
||||||
|
**Control, run first:** the same magic scan over `BGM_001.slb`'s neighbourhood
|
||||||
|
finds `RIFF` exactly where the bank structure says it should be. The scan works;
|
||||||
|
the magic genuinely is not there.
|
||||||
|
|
||||||
|
So the `.xgs` / `.slb` names are **inherited from the authoring tool, not from the
|
||||||
|
shipped format** — nothing on this disc is a parseable XACT container. There is no
|
||||||
|
XACT project file to read, and writing an XACT parser would have been wasted work.
|
||||||
|
|
||||||
|
### Where that leaves the SE audio: undecodable, with reach
|
||||||
|
|
||||||
|
Locating an individual SE cue's wave inside `Static.slb` is **not possible from
|
||||||
|
anything found on the disc**. Looked in:
|
||||||
|
|
||||||
|
* `Static.slb` itself — 8 353 472 readable bytes, **0 `RIFF` / 0 `seek` / 0 `WAVE`**,
|
||||||
|
where every one of the other 7 620 banks is delimited by `seek` magic at
|
||||||
|
`data_at + declared_size` ([`structures/slb-data-offset.md`](structures/slb-data-offset.md));
|
||||||
|
* the XACT project file — absent, as above;
|
||||||
|
* the sound table's five records — `SOUNDS` gives cue→id, `FILES` gives bank
|
||||||
|
paths, `BANK_SE` gives the one bank name, `SETTINGS` gives a path and the
|
||||||
|
(absent) project file, `STAGES` is empty. **No record carries an offset.**
|
||||||
|
|
||||||
|
**What does corroborate the binding:** `Static.slb` is 8 353 472 bytes, and at the
|
||||||
|
bitrates the disc uses elsewhere (25 697–31 000 B/s) that is **269–325 seconds of
|
||||||
|
audio — 0.84 to 1.01 s per cue over 322 cues.** Exactly the shape of a bank of
|
||||||
|
short UI/HUD/weapon effects, which is what `BANK_SE` says it is. The bank is the
|
||||||
|
right bank; only the index into it is missing.
|
||||||
|
|
||||||
|
**If it is ever picked up**, the route is the running game, not the disc: watch
|
||||||
|
the guest hand a wave offset/length to the decoder when a cue fires. That is the
|
||||||
|
same instrumentation the cue↔event binding needs, and the same one this container
|
||||||
|
cannot run.
|
||||||
|
|||||||
Reference in New Issue
Block a user