re: the movie/subtitle/voice link is solved statically -- INDEX called it a dynamic unknown
INDEX carried IXUD as "movie<->track link unknown (dynamic item)". It is a config record on the disc: tables.pak schema 0x067025b9, whose keys match the movie game-part symbols in the executable (MOVIE / TELOP / SUBTITLE / VOICETRACK, plus SUBTITLE_FONT / SUBTITLE_Y / SUBTITLE_HEIGHT next to silph::GamePart_Movie::Impl::OnPrepare). 101 movies mapped: 94 with a subtitle, 83 with a voice track, 21 with a telop. Every subtitle reference was looked up in dat/movie/<lang>.pak and 93 of 94 resolve -- SUBTITLE_S12B.tbl resolves in NONE of the six languages, a dangling reference on the retail disc rather than a decode failure. Naming is SUBTITLE_<base>.tbl and VOICE_<base>, with the staff roll and five supply movies (VOICE_D_450..454) as documented exceptions, so a reimplementation can resolve by convention and fall back to the table for those six. Deliberately NOT published: the record's ~104 script ids paired to movies. Positional pairing drifts by three -- visible at the tail, where S24/S27_SUPPLY_ACROPOLIS would have to map to hokyu_LS_s24A/s27A and do not -- because the IDXD pool dedupes repeated values and an id whose movie was already named contributes no token. The CSV is keyed by movie file instead. For the intro-movie work: ADV.wmv has VOICE_ADV and no subtitle, no telop. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
75
docs/re/movie-subtitle-link.md
Normal file
75
docs/re/movie-subtitle-link.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# The movie ↔ subtitle ↔ voice link ✅ (static)
|
||||
|
||||
[`INDEX`](INDEX.md) carried the IXUD subtitle format as 🟡 with **"movie↔track
|
||||
link unknown (dynamic item)"** — i.e. a question expected to need the running
|
||||
game. It does not: the link is a config record on the disc, and it verifies
|
||||
against the disc's own contents.
|
||||
|
||||
## Where it is
|
||||
|
||||
`dat/tables.pak`, the IDXD record with schema `0x067025b9`. Its keys come from
|
||||
the movie game-part — the executable carries them next to the symbol
|
||||
`silph::GamePart_Movie::Impl::OnPrepare`:
|
||||
|
||||
```
|
||||
PATH = dat\movie\ SUBTITLE_FONT = fra.pak+GOTHICB.TTF
|
||||
SUBTITLE_Y = 600 SUBTITLE_HEIGHT = 33
|
||||
MOVIE TELOP SUBTITLE VOICETRACK
|
||||
```
|
||||
|
||||
Each movie is one group of values:
|
||||
|
||||
```
|
||||
S02A.wmv MOVIE
|
||||
fra.pak+pwterop_s02a.prt TELOP (optional overlay)
|
||||
fra.pak+SUBTITLE_S02A.tbl SUBTITLE
|
||||
VOICE_S02A VOICETRACK
|
||||
```
|
||||
|
||||
`<lang>.pak+<member>` resolves inside `dat/movie/<lang>.pak`, and the six
|
||||
language paks (`eng`, `fra`, `deu`, `esp`, `ita`, `jpn`) each carry the same
|
||||
member names — so the prefix in the table is just the build's language and the
|
||||
member name is the portable part. The recovered map is
|
||||
[`captures/movie-subtitle-voice-map.csv`](captures/movie-subtitle-voice-map.csv):
|
||||
**101 movies, 94 with a subtitle, 83 with a voice track, 21 with a telop.**
|
||||
|
||||
## Verified, and one real defect
|
||||
|
||||
Every subtitle reference was looked up in the language paks. **93 of 94 resolve.
|
||||
`SUBTITLE_S12B.tbl` resolves in none of the six languages** — a dangling
|
||||
reference on the retail disc, not a decode failure on our side. Worth knowing
|
||||
before the reimplementation treats a missing subtitle table as a bug of its own.
|
||||
|
||||
The naming is a convention with two documented exceptions:
|
||||
|
||||
- subtitles are `SUBTITLE_<movie base>.tbl` — the only departure is the staff
|
||||
roll, `SYLPH_HD720p_8M-CBR_2ch.wmv` → `SYLPH_HD720p_8M-CBR_2ch.tbl`;
|
||||
- voice tracks are `VOICE_<movie base>` — except five supply-run movies
|
||||
(`hokyu_LS_s02A`, `hokyu_LS_s02H`, `hokyu_DS_s02A`, `hokyu_DS_s07H`,
|
||||
`hokyu_LS_s09A`), which point at shared lines `VOICE_D_450…454`.
|
||||
|
||||
So a reimplementation can resolve a movie's subtitle and voice **by convention**,
|
||||
and should fall back to this table for those six cases rather than assuming it.
|
||||
|
||||
## What is *not* recoverable from this record
|
||||
|
||||
The record also lists ~104 **script ids** (`LOGO1`, `ADVERTISE_MOVIE`,
|
||||
`STAFF_ROLL`, `MS00A`, `STAGE01_PHASE01`, `S02_SUPPLY_ACROPOLIS`, …) — the names
|
||||
stage scripts use to trigger a movie. Pairing them positionally with the 101
|
||||
movie groups **does not work**: the counts differ by three and the drift is
|
||||
visible at the tail, where the last ids (`S24_SUPPLY_ACROPOLIS`,
|
||||
`S27_SUPPLY_ACROPOLIS`) would have to map to `hokyu_LS_s24A.wmv` /
|
||||
`hokyu_LS_s27A.wmv` and under positional pairing do not.
|
||||
|
||||
The cause is the same IDXD property that bit the Arsenal table: **the string pool
|
||||
stores each distinct string once**, so an id whose movie was already named
|
||||
earlier contributes no new value token and its group silently disappears. The id
|
||||
list is therefore ❔ until the binary node/index region is decoded — and the CSV
|
||||
is deliberately keyed by **movie file**, which is the part the data actually
|
||||
supports.
|
||||
|
||||
## Note for the intro-movie investigation
|
||||
|
||||
`ADV.wmv` — the one the emulator work is about — has `VOICETRACK = VOICE_ADV`
|
||||
and **no subtitle and no telop**. So a correct playback of it needs the video and
|
||||
that one voice track, nothing else from this table.
|
||||
Reference in New Issue
Block a user