This branch predates CI on `main`. `cargo fmt --all` only; no behaviour. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
59 lines
2.2 KiB
Rust
59 lines
2.2 KiB
Rust
//! Are `GP_DIALOG` entries 0/1 and 2/3 a LANGUAGE PAIR or a DUPLICATE?
|
|
//!
|
|
//! They are the only two adjacent pairs in that archive with identical element
|
|
//! sets; every other adjacent pair is two unrelated dialogs. Left open as
|
|
//! "untested" — identical element names are equally consistent with a language
|
|
//! pair (same layout, different glyphs baked into the textures) and with a
|
|
//! byte-for-byte duplicate.
|
|
//!
|
|
//! The bytes decide it: identical entries are a duplicate; entries that share
|
|
//! every element name but differ in payload are a language pair.
|
|
//!
|
|
//! CONTROL: entries 10/11, known to be two DIFFERENT dialogs (stage 10 vs stage
|
|
//! 02), must come out as differing — and by a lot. A comparator that cannot
|
|
//! separate two unrelated dialogs cannot judge two similar ones.
|
|
//!
|
|
//! cargo run -p sylpheed-formats --example dialog_pair_identity
|
|
use std::path::PathBuf;
|
|
use sylpheed_formats::pak::PakArchive;
|
|
|
|
fn cmp(ar: &PakArchive, a: usize, b: usize, what: &str) {
|
|
let (Ok(x), Ok(y)) = (ar.read(&ar.entries()[a]), ar.read(&ar.entries()[b])) else {
|
|
println!("{what}: unreadable");
|
|
return;
|
|
};
|
|
let same_len = x.len() == y.len();
|
|
let n = x.len().min(y.len());
|
|
let diff = (0..n).filter(|&i| x[i] != y[i]).count();
|
|
let first = (0..n).find(|&i| x[i] != y[i]);
|
|
println!("{what}");
|
|
println!(
|
|
" sizes {} / {} ({})",
|
|
x.len(),
|
|
y.len(),
|
|
if same_len { "equal" } else { "DIFFER" }
|
|
);
|
|
println!(
|
|
" differing bytes over the common prefix: {diff} / {n} ({:.2}%)",
|
|
100.0 * diff as f64 / n as f64
|
|
);
|
|
match first {
|
|
None if same_len => println!(" => BYTE-IDENTICAL — a duplicate"),
|
|
None => println!(" => one is a prefix of the other"),
|
|
Some(o) => println!(" => first difference at offset 0x{o:X}"),
|
|
}
|
|
}
|
|
|
|
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");
|
|
cmp(
|
|
&ar,
|
|
10,
|
|
11,
|
|
"CONTROL: entries 10/11 — known two different dialogs",
|
|
);
|
|
cmp(&ar, 0, 1, "entries 0/1");
|
|
cmp(&ar, 2, 3, "entries 2/3 — the DIFFICULTY build");
|
|
}
|