From 38f58ea559c03f7d325c077e8c65ab242740a51b Mon Sep 17 00:00:00 2001 From: "Claude (auto-RE)" Date: Tue, 11 Aug 2026 21:10:08 +0000 Subject: [PATCH] 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/.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_.tbl and VOICE_, 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) --- docs/re/INDEX.md | 2 +- docs/re/captures/movie-subtitle-voice-map.csv | 102 ++++++++++++++++++ docs/re/movie-subtitle-link.md | 75 +++++++++++++ 3 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 docs/re/captures/movie-subtitle-voice-map.csv create mode 100644 docs/re/movie-subtitle-link.md diff --git a/docs/re/INDEX.md b/docs/re/INDEX.md index 8cd04e5..1edc9e0 100644 --- a/docs/re/INDEX.md +++ b/docs/re/INDEX.md @@ -17,7 +17,7 @@ Promote to a prose `structures/…md` file when a format needs behavioural notes | T8aD 2D texture | 🟡 | `sylpheed-formats/src/t8ad.rs` | ~85% decode; **colours ✅ CONFIRMED** ([k8888](structures/texture-color-k8888.md)); ~15% variants deferred | | RATC bundle | 🟡 | `sylpheed-formats/src/ratc.rs` | child listing confirmed; one level deep | | LSTA sprite list | 🟡 | `sylpheed-formats/src/lsta.rs` | inline T8aD frames | -| IXUD subtitle | 🟡 | `sylpheed-formats/src/ixud.rs` | timed cues; **movie↔track link unknown** (dynamic item) | +| IXUD subtitle | 🟡/✅ | `sylpheed-formats/src/ixud.rs` + [movie link](movie-subtitle-link.md) | timed cues. **The movie↔subtitle↔voice link is solved — statically**, from the movie config record in `tables.pak` (schema `0x067025b9`), not from the running game as this row previously assumed: [101 movies mapped](captures/movie-subtitle-voice-map.csv), 94 with subtitles, 83 with voice, 21 with a telop overlay. 93 of 94 subtitle refs resolve in the language paks; **`SUBTITLE_S12B.tbl` is missing from all six languages** — a dangling reference on the disc. Naming is `SUBTITLE_.tbl` / `VOICE_` with six documented exceptions. The record's ~104 **script ids** are ❔ — positional pairing drifts by three because the IDXD pool dedupes repeated values | | Fonts (ttf/otf/ttc) | ✅ | `sylpheed-formats/src/font.rs` | standard OpenType, parsed via ttf-parser | | XBG7 mesh | 🟡/❔ | `sylpheed-formats/src/mesh.rs` + `tests/mesh_disc.rs` ([xbg7](structures/xbg7-mesh.md)) | weapons/props: declaration-driven variable stride (36 models), GPU-confirmed. **Stage containers: 5662 sub-models across 22 stages** via content-anchored grouped pools (`stage_models`). Quantized hero bodies (DeltaSaber `f004`) still declined | | Capital-ship part placement | 🟡 | `sylpheed-formats/src/ship.rs` (static) + [runtime capture](ship-placement-runtime-capture.md) | hull placement static-exact; external parts approximate statically. **Runtime capture** (Canary F10 → VS-constant WorldView) gives ground truth — validated on `e106` destroyer; not yet baked into the viewer | diff --git a/docs/re/captures/movie-subtitle-voice-map.csv b/docs/re/captures/movie-subtitle-voice-map.csv new file mode 100644 index 0000000..aa5bb02 --- /dev/null +++ b/docs/re/captures/movie-subtitle-voice-map.csv @@ -0,0 +1,102 @@ +movie,telop,subtitle,voicetrack +logo1.wmv,,, +logo2.wmv,,, +logo3.wmv,,, +logo4.wmv,,, +ADV.wmv,,,VOICE_ADV +SYLPH_HD720p_8M-CBR_2ch.wmv,pwterop_s01a.prt,SYLPH_HD720p_8M-CBR_2ch.tbl, +S00A.wmv,,SUBTITLE_S00A.tbl,VOICE_S00A +S01A.wmv,,SUBTITLE_S01A.tbl,VOICE_S01A +RT01A.wmv,pwrt01.prt,SUBTITLE_RT01A.tbl,VOICE_RT01A +RT01B.wmv,,SUBTITLE_RT01B.tbl,VOICE_RT01B +RT01C_1.wmv,,SUBTITLE_RT01C_1.tbl,VOICE_RT01C_1 +RT01C_2.wmv,,SUBTITLE_RT01C_2.tbl,VOICE_RT01C_2 +S02A.wmv,pwterop_s02a.prt,SUBTITLE_S02A.tbl,VOICE_S02A +S02B.wmv,,SUBTITLE_S02B.tbl,VOICE_S02B +S02C.wmv,,SUBTITLE_S02C.tbl,VOICE_S02C +RT02A.wmv,pwrt02.prt,SUBTITLE_RT02A.tbl,VOICE_RT02A +RT02B.wmv,,SUBTITLE_RT02B.tbl,VOICE_RT02B +RT02C.wmv,,SUBTITLE_RT02C.tbl,VOICE_RT02C +RT02D_1.wmv,,SUBTITLE_RT02D_1.tbl,VOICE_RT02D_1 +RT02D_2.wmv,,SUBTITLE_RT02D_2.tbl,VOICE_RT02D_2 +hokyu_LS_s02A.wmv,,SUBTITLE_hokyu_LS_s02A.tbl,VOICE_D_450 +hokyu_LS_s02H.wmv,,SUBTITLE_hokyu_LS_s02H.tbl,VOICE_D_453 +S03A.wmv,,SUBTITLE_S03A.tbl,VOICE_S03A +RT03A.wmv,pwrt03.prt,SUBTITLE_RT03A.tbl,VOICE_RT03A +RT03B.wmv,,SUBTITLE_RT03B.tbl,VOICE_RT03B +RT03C.wmv,,SUBTITLE_RT03C.tbl,VOICE_RT03C +RT03D.wmv,,SUBTITLE_RT03D.tbl,VOICE_RT03D +hokyu_LS_s03A.wmv,,SUBTITLE_hokyu_LS_s03A.tbl, +hokyu_LS_s03H.wmv,,SUBTITLE_hokyu_LS_s03H.tbl, +S04A.wmv,,SUBTITLE_S04A.tbl,VOICE_S04A +S04B.wmv,,SUBTITLE_S04B.tbl,VOICE_S04B +RT04A.wmv,pwrt04.prt,SUBTITLE_RT04A.tbl,VOICE_RT04A +RT04B.wmv,,SUBTITLE_RT04B.tbl,VOICE_RT04B +hokyu_DS_s02A.wmv,,SUBTITLE_hokyu_DS_s02A.tbl,VOICE_D_452 +S05A.wmv,,SUBTITLE_S05A.tbl,VOICE_S05A +RT05A.wmv,pwrt05.prt,SUBTITLE_RT05A.tbl,VOICE_RT05A +RT05B.wmv,,SUBTITLE_RT05B.tbl,VOICE_RT05B +RT05C.wmv,,SUBTITLE_RT05C.tbl,VOICE_RT05C +S06A.wmv,pwterop_s06a.prt,SUBTITLE_S06A.tbl,VOICE_S06A +S06B.wmv,,SUBTITLE_S06B.tbl,VOICE_S06B +RT06A.wmv,pwrt06.prt,SUBTITLE_RT06A.tbl,VOICE_RT06A +RT06B.wmv,,SUBTITLE_RT06B.tbl,VOICE_RT06B +RT06C.wmv,,SUBTITLE_RT06C.tbl,VOICE_RT06C +RT06D.wmv,,SUBTITLE_RT06D.tbl,VOICE_RT06D +hokyu_LS_s06A.wmv,,SUBTITLE_hokyu_LS_s06A.tbl, +hokyu_LS_s06H.wmv,,SUBTITLE_hokyu_LS_s06H.tbl, +S07A.wmv,,SUBTITLE_S07A.tbl,VOICE_S07A +S07B.wmv,,SUBTITLE_S07B.tbl,VOICE_S07B +RT07A.wmv,pwrt07.prt,SUBTITLE_RT07A.tbl,VOICE_RT07A +RT07B.wmv,,SUBTITLE_RT07B.tbl,VOICE_RT07B +RT07C.wmv,,SUBTITLE_RT07C.tbl,VOICE_RT07C +hokyu_DS_s07A.wmv,,SUBTITLE_hokyu_DS_s07A.tbl, +hokyu_DS_s07H.wmv,,SUBTITLE_hokyu_DS_s07H.tbl,VOICE_D_454 +RT08A.wmv,pwrt08.prt,SUBTITLE_RT08A.tbl,VOICE_RT08A +RT08B.wmv,,SUBTITLE_RT08B.tbl,VOICE_RT08B +RT08C.wmv,,SUBTITLE_RT08C.tbl,VOICE_RT08C +hokyu_DS_s08A.wmv,,SUBTITLE_hokyu_DS_s08A.tbl, +S09B.wmv,,SUBTITLE_S09B.tbl,VOICE_S09B +RT09A.wmv,pwrt09.prt,SUBTITLE_RT09A.tbl,VOICE_RT09A +RT09B.wmv,,SUBTITLE_RT09B.tbl,VOICE_RT09B +RT09C.wmv,,SUBTITLE_RT09C.tbl,VOICE_RT09C +RT09D.wmv,,SUBTITLE_RT09D.tbl,VOICE_RT09D +hokyu_LS_s09A.wmv,,SUBTITLE_hokyu_LS_s09A.tbl,VOICE_D_451 +hokyu_LS_s09H.wmv,,SUBTITLE_hokyu_LS_s09H.tbl, +S10B.wmv,,SUBTITLE_S10B.tbl,VOICE_S10B +RT10A.wmv,pwrt10.prt,SUBTITLE_RT10A.tbl,VOICE_RT10A +RT10B.wmv,,SUBTITLE_RT10B.tbl,VOICE_RT10B +S11A.wmv,,SUBTITLE_S11A.tbl,VOICE_S11A +S11C.wmv,,SUBTITLE_S11C.tbl,VOICE_S11C +RT11A.wmv,pwrt11.prt,SUBTITLE_RT11A.tbl,VOICE_RT11A +RT11B.wmv,,SUBTITLE_RT11B.tbl,VOICE_RT11B +RT11C.wmv,,SUBTITLE_RT11C.tbl,VOICE_RT11C +hokyu_LS_s11A.wmv,,SUBTITLE_hokyu_LS_s11A.tbl, +S12A.wmv,,SUBTITLE_S12A.tbl,VOICE_S12A +S12B.wmv,,SUBTITLE_S12B.tbl,VOICE_S12B +S12C.wmv,,SUBTITLE_S12C.tbl,VOICE_S12C +RT12A.wmv,pwrt12.prt,SUBTITLE_RT12A.tbl,VOICE_RT12A +RT12B_1.wmv,,SUBTITLE_RT12B_1.tbl,VOICE_RT12B_1 +RT12B_2.wmv,,SUBTITLE_RT12B_2.tbl,VOICE_RT12B_2 +S13A.wmv,,SUBTITLE_S13A.tbl,VOICE_S13A +S13B.wmv,,SUBTITLE_S13B.tbl,VOICE_S13B +RT13A.wmv,pwrt13.prt,SUBTITLE_RT13A.tbl,VOICE_RT13A +RT13B_1.wmv,,SUBTITLE_RT13B_1.tbl,VOICE_RT13B_1 +RT13B_2.wmv,,SUBTITLE_RT13B_2.tbl,VOICE_RT13B_2 +hokyu_DS_s13A.wmv,,SUBTITLE_hokyu_DS_s13A.tbl, +S14A.wmv,,SUBTITLE_S14A.tbl,VOICE_S14A +RT14A.wmv,pwrt14.prt,SUBTITLE_RT14A.tbl,VOICE_RT14A +RT14B.wmv,,SUBTITLE_RT14B.tbl,VOICE_RT14B +RT14C.wmv,,SUBTITLE_RT14C.tbl,VOICE_RT14C +hokyu_DS_s14H.wmv,,SUBTITLE_hokyu_DS_s14H.tbl, +S15A.wmv,pwterop_s15a.prt,SUBTITLE_S15A.tbl,VOICE_S15A +S15B.wmv,,SUBTITLE_S15B.tbl,VOICE_S15B +S15C.wmv,,SUBTITLE_S15C.tbl,VOICE_S15C +RT15A.wmv,pwrt15.prt,SUBTITLE_RT15A.tbl,VOICE_RT15A +RT15B.wmv,,SUBTITLE_RT15B.tbl,VOICE_RT15B +RT15C.wmv,,SUBTITLE_RT15C.tbl,VOICE_RT15C +hokyu_LS_s15A.wmv,,SUBTITLE_hokyu_LS_s15A.tbl, +S16A.wmv,pwterop_s16a.prt,SUBTITLE_S16A.tbl,VOICE_S16A +RT16C.wmv,pwrt16.prt,SUBTITLE_RT16C.tbl,VOICE_RT16C +hokyu_LS_s24A.wmv,,, +hokyu_LS_s27A.wmv,,, diff --git a/docs/re/movie-subtitle-link.md b/docs/re/movie-subtitle-link.md new file mode 100644 index 0000000..2aa8c03 --- /dev/null +++ b/docs/re/movie-subtitle-link.md @@ -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 +``` + +`.pak+` resolves inside `dat/movie/.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_.tbl` — the only departure is the staff + roll, `SYLPH_HD720p_8M-CBR_2ch.wmv` → `SYLPH_HD720p_8M-CBR_2ch.tbl`; +- voice tracks are `VOICE_` — 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.