The movie manifest (tables.pak, schema 0x067025b9) is the game's authoritative mission -> phase -> cutscene table. Previously we only scraped VOICE_/SUBTITLE_/.wmv strings by prefix; now we decode the real two-array (slot-keys, then value-records) structure. MovieEntry gains slot, kind (System/Intro/Phase/PhaseEnd/Supply), mission, phase, subtitle, and telop (the previously-ignored .prt on-screen text overlay). Valueless slots (stages with no resupply video) are recovered without decoding the binary node region, via the fully-derivable MS<NN><X> -> S<NN><X> anchors. Backward compatible: movie/voice_token and resolve_voice_entry/voice_token/is_manifest are unchanged. Validated end-to-end on the real disc: 101 entries (104 slots - 3 gaps), typed System=6/Intro=27/Phase=32/PhaseEnd=18/Supply=18. examples/manifest_map.rs dumps the full map. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
47 lines
1.5 KiB
Rust
47 lines
1.5 KiB
Rust
//! Validation: dump the parsed mission/phase cutscene map from the real manifest.
|
|
use sylpheed_formats::movie_manifest::{self, MovieKind};
|
|
use sylpheed_formats::pak::PakArchive;
|
|
|
|
fn main() {
|
|
let disc = std::env::var("SYLPHEED_DISC").expect("set SYLPHEED_DISC");
|
|
let arc = PakArchive::open(format!("{disc}/dat/tables.pak")).unwrap();
|
|
let man = arc
|
|
.entries()
|
|
.iter()
|
|
.find_map(|e| arc.read(e).ok().filter(|b| movie_manifest::is_manifest(b)))
|
|
.expect("manifest");
|
|
let entries = movie_manifest::parse(&man);
|
|
let mut counts = [0usize; 5];
|
|
for e in &entries {
|
|
counts[match e.kind {
|
|
MovieKind::System => 0,
|
|
MovieKind::Intro => 1,
|
|
MovieKind::Phase => 2,
|
|
MovieKind::PhaseEnd => 3,
|
|
MovieKind::Supply => 4,
|
|
}] += 1;
|
|
let m = e.mission.map(|x| x.to_string()).unwrap_or_default();
|
|
let p = e.phase.map(|x| x.to_string()).unwrap_or_default();
|
|
println!(
|
|
"{:<22} {:<9} m={:<2} p={:<1} {:<16} {:<14} tel={:<14} sub={}",
|
|
e.slot,
|
|
format!("{:?}", e.kind),
|
|
m,
|
|
p,
|
|
e.movie,
|
|
e.voice_token.as_deref().unwrap_or("-"),
|
|
e.telop.as_deref().unwrap_or("-"),
|
|
e.subtitle.as_deref().unwrap_or("-"),
|
|
);
|
|
}
|
|
eprintln!(
|
|
"TOTAL {} entries — System={} Intro={} Phase={} PhaseEnd={} Supply={}",
|
|
entries.len(),
|
|
counts[0],
|
|
counts[1],
|
|
counts[2],
|
|
counts[3],
|
|
counts[4]
|
|
);
|
|
}
|