//! Are `GP_DIALOG`'s 140 entries adjacent EN/JP pairs, one per dialog record? //! //! The dialog table has 70 records and the archive has 140 entries. If the //! pairing is adjacent — (0,1), (2,3), … — then dialog index = entry / 2, and the //! unbound id-to-entry join becomes an ordering question rather than a search. //! //! Test: for each pair, compare the SET of element names. GP_TITLE's EN/JP pairs //! share their sprite sets exactly except for the title art (4/7), so identical //! sets are the signature of a language pair. //! //! cargo run -p sylpheed-formats --example dialog_pairing use std::collections::BTreeSet; use std::path::PathBuf; use sylpheed_formats::{pak::PakArchive, ui_layout}; fn names(ar: &PakArchive, i: usize) -> Option> { let by = ar.read(&ar.entries()[i]).ok()?; let b = ui_layout::parse_build(&by)?; Some(b.elements.iter().map(|e| e.name.clone()).collect()) } fn main() { let root = PathBuf::from(std::env::var("SYLPHEED_DISC").expect("SYLPHEED_DISC")); let ar = PakArchive::open(root.join("dat/GP_DIALOG.pak")).expect("GP_DIALOG"); let n = ar.entries().len(); let (mut adj_same, mut adj_diff, mut skipped) = (0, 0, 0); for k in (0..n).step_by(2) { match (names(&ar, k), names(&ar, k + 1)) { (Some(a), Some(b)) => { if a == b { adj_same += 1; println!(" identical pair: entries {k}/{}", k + 1) } else { adj_diff += 1 } } _ => skipped += 1, } } println!("ADJACENT pairing (2k, 2k+1): identical {adj_same} differing {adj_diff} unreadable {skipped}"); // rival hypothesis: halves, (i, i+70) let (mut h_same, mut h_diff, mut h_skip) = (0, 0, 0); for k in 0..n / 2 { match (names(&ar, k), names(&ar, k + n / 2)) { (Some(a), Some(b)) => { if a == b { h_same += 1 } else { h_diff += 1 } } _ => h_skip += 1, } } println!( "HALVES pairing (i, i+70): identical {h_same} differing {h_diff} unreadable {h_skip}" ); }