re: the menu's sound events are named on the disc; the binding to them is
not Q8. The cheapest thing nobody had tried was to look at the SE cue names, and they are semantic: SE_UI_CURSOR (2), SE_UI_DECIDE (3), SE_UI_CANSEL (4), SE_UI_IMPOSI (5, the error buzz), SE_UI_SUB_WIN_OPN/CLS, and SE_UI_SPLASH_IN/OUT. That is exactly the move/confirm/back/error vocabulary the question asks for, named by the authors after the EVENT rather than the sound. 322 SE cues committed as reference data. They all live in one bank: BANK_SE is a single field reading Static.slb, and the disc-wide check agrees -- 0 of the 322 has an entry in FILES, the 5135-path list that names every voice, briefing and BGM bank. I am calling the binding a NAME MATCH, not a measurement, and the page says so in the same breath as it gives the table. It is a stronger name match than Q4's GamePart ids -- these are the authors' own event names -- but nobody has watched the game emit cue 2 on a d-pad press, and this container is muted against a dummy device so there is no audio path to watch either. One new negative, with its reach. Static.slb's 8 353 472 readable bytes contain zero RIFF, zero seek and zero WAVE, scanned over the whole buffer. The boundary marker that works for all 7 620 other banks is absent, so the cue is named, the bank is named, and the wave inside it is not locatable. The UI sound effects cannot be exported yet, and that is a gap in the assets rather than in the naming. The named next step is Pj_Silph.xgs -- the XACT project SETTINGS points at, which IS in sound.pak at TOC 9454, though its 533 bytes carry no XGSF magic and its region's phase says they are probably the previous bank's tail.
This commit is contained in:
100
docs/re/menu-audio-cues.md
Normal file
100
docs/re/menu-audio-cues.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Menu audio — the event vocabulary is on the disc; the binding is not
|
||||
|
||||
**Status:** ✅ `CONFIRMED` and **decoded** for the cue vocabulary and the bank
|
||||
that holds it. 🟡 the cue↔event binding is a **name match**, not a measurement.
|
||||
❔ two negatives with their reach: no cue names a screen's music, and the audio
|
||||
for an individual SE cue cannot yet be extracted.
|
||||
|
||||
Answers most of [MISSION Q8](../port/MISSION.md).
|
||||
|
||||
## ✅ The UI cue vocabulary — decoded
|
||||
|
||||
`dat/tables.pak`'s sound table has a `SOUNDS` record of 5 798 cues. 322 are `SE_*`
|
||||
and the **low block is the user-interface vocabulary**, named by the game's
|
||||
authors after the *events*, not after the sounds:
|
||||
|
||||
| id | cue | id | cue |
|
||||
|---|---|---|---|
|
||||
| 1 | `SE_UI_START` | 9 | `SE_UI_SUB_WIN_CLS` |
|
||||
| **2** | **`SE_UI_CURSOR`** | 10 | `SE_UI_ALART_WIN` |
|
||||
| **3** | **`SE_UI_DECIDE`** | 11 | `SE_UI_PAUSE` |
|
||||
| **4** | **`SE_UI_CANSEL`** *(sic)* | 12 | `SE_UI_SPLASH_IN` |
|
||||
| **5** | **`SE_UI_IMPOSI`** | 13 | `SE_UI_SPLASH_OUT` |
|
||||
| 6 | `SE_UI_WAIT` | 14 | `SE_UI_LOAD_CMP` |
|
||||
| 7 | `SE_UI_NEXT` | 17/18 | `SE_UI_WEAPON_PLAN` / `_CREATE` |
|
||||
| 8 | `SE_UI_SUB_WIN_OPN` | 81–83 | `SE_UI_MISSION_START` / `_UPDATE` / `_END` |
|
||||
|
||||
Full 322-cue list in [`data/se-ui-cues.txt`](data/se-ui-cues.txt). The remaining
|
||||
blocks are gameplay: `SE_HUD_*` (21–83), `SE_BR_*` briefing (50–72), `SE_SW_*` /
|
||||
`SE_MW_*` weapons, `SE_DS_*` engine, `SE_EXP_*` explosions, `SE_SHIELD_*`.
|
||||
|
||||
## ✅ They all live in one bank — decoded
|
||||
|
||||
The sound table's `BANK_SE` record is a **single field**: `Static.slb`. And the
|
||||
disc-wide check agrees — **0 of the 322 `SE_*` cues has an entry in `FILES`**, the
|
||||
5 135-path list where every voice, briefing and BGM bank is named. SE is the one
|
||||
family that is not one-cue-one-file.
|
||||
|
||||
`SETTINGS` names the XACT project too: `PATH` = `game:\dat\sound.pak+`,
|
||||
`PARAM` = `Pj_Silph.xgs`.
|
||||
|
||||
## 🟡 The binding: a name match, and I am calling it that
|
||||
|
||||
MISSION asks which cue fires on **move / confirm / back / error**. Read off the
|
||||
names:
|
||||
|
||||
| event | cue |
|
||||
|---|---|
|
||||
| cursor moves | `SE_UI_CURSOR` (2) |
|
||||
| Ⓐ confirm | `SE_UI_DECIDE` (3) |
|
||||
| Ⓑ back | `SE_UI_CANSEL` (4) |
|
||||
| invalid / error | `SE_UI_IMPOSI` (5) |
|
||||
| submenu opens / closes | `SE_UI_SUB_WIN_OPN` / `_CLS` (8/9) |
|
||||
| the splash | `SE_UI_SPLASH_IN` / `_OUT` (12/13) |
|
||||
|
||||
**Nobody has watched the game emit cue 2 on a d-pad press.** This is inference
|
||||
from identifiers, and it belongs in the same box as Q4's GamePart ids — with one
|
||||
honest difference worth stating: these are the *authors' own event names*, chosen
|
||||
to describe when the sound plays, not asset labels I am interpreting. It is a
|
||||
strong name match. It is still a name match, and the port is authoring it.
|
||||
|
||||
Measuring it needs the guest's cue-play call observed with its argument — the
|
||||
same instrumentation Q4's residual wants, and not something this container can do
|
||||
today (it runs `--mute=true` against an SDL dummy device, so there is no audio
|
||||
path to watch either).
|
||||
|
||||
## ❔ Which BGM per screen — undecodable, reach already recorded
|
||||
|
||||
All 32 BGM cues are named `BGM_001`…`BGM_109`. Nothing in `SOUNDS`, `FILES` or the
|
||||
bank headers names a screen — see
|
||||
[`structures/bgm-two-stems.md`](structures/bgm-two-stems.md). Unchanged by this
|
||||
iteration.
|
||||
|
||||
## ❔ And a new negative: an individual SE's audio is not extractable yet
|
||||
|
||||
`Static.slb` is **8 353 472 readable bytes** (declared 8 970 240 — exactly the
|
||||
616 768 over-declaration the corpus already records), and it contains
|
||||
**0 `RIFF`, 0 `seek`, 0 `WAVE`** — scanned over the whole buffer, so this is not
|
||||
an offset problem. Every other bank on the disc is delimited by `seek` magic at
|
||||
`data_at + declared_size` (7 620/7 620 in
|
||||
[`slb-data-offset.md`](structures/slb-data-offset.md)); `Static.slb` is outside
|
||||
that population. So the route that extracts every voice line and every BGM does
|
||||
**not** give you `SE_UI_CURSOR`'s audio: the cue is named, the bank is named, and
|
||||
the wave inside the bank is not locatable by any boundary marker.
|
||||
|
||||
**The named next step is `Pj_Silph.xgs`** — the XACT project file `SETTINGS`
|
||||
points at, which in XACT is exactly where cue→wave-index lives. It **is** in
|
||||
`sound.pak`: `name_hash("Pj_Silph.xgs")` resolves to TOC index 9454. ⚠️ Its entry
|
||||
is 533 bytes at a 2048-aligned offset and carries no `XGSF` magic — and its region
|
||||
has phase 1728, so those 533 bytes are very likely the *previous* bank's tail
|
||||
rather than its own (the leading-region effect, [`slb-data-offset.md`]
|
||||
(structures/slb-data-offset.md)). Locating its real bytes is the first job, not
|
||||
parsing XACT.
|
||||
|
||||
## For the port
|
||||
|
||||
* the cue **names and ids** are disc facts — use them as the event vocabulary;
|
||||
* which event fires which cue is **authored from the table above**;
|
||||
* 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
|
||||
assets, not in the naming.
|
||||
Reference in New Issue
Block a user