Files
Syplheed-Reborn/docs/re/movie-subtitle-link.md
Claude (auto-RE) 38f58ea559 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>
2026-08-11 21:10:08 +00:00

3.5 KiB

The movie ↔ subtitle ↔ voice link (static)

INDEX 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: 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.wmvSYLPH_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.