Probed with the EXISTING build detector -- no new decoding. 24 disc archives contain UI screen builds; the exporter reads one (dat/GP_TITLE.pak, hardcoded). GP_OPTIONS has 14 builds, GP_SAVE_LOAD 18, GP_DIALOG 105, GP_TUTORIAL 2. So LOAD GAME, TUTORIAL, OPTIONS and the NEW GAME difficulty chain are not blocked on the Decoder and need no format work. They are an exporter scope limit, and the exporter is the port's. Prioritised by the filter adopted after the plate: 'if this is wrong, what does a player experience?' Four dead menu entries beat an audio level, which beats timing minutiae. Flagged as NOT established: that the screens render (is_build says the record parses, not that sprites resolve or names are known), which GP_DIALOG entry is the difficulty dialog, and that more screens are free -- every one joins check-all's per-screen comparisons and needs a naming decision. Next unit widens to GP_OPTIONS only. Not all four: 139 new screens at once would make any regression unattributable.
43 lines
1.7 KiB
Rust
43 lines
1.7 KiB
Rust
//! Which disc archives contain UI screen builds?
|
|
//!
|
|
//! The exporter reads `dat/GP_TITLE.pak` and nothing else, so four of the five
|
|
//! main-menu destinations have no screen file to go to: `authored/flow.json`
|
|
//! records LOAD GAME as `GP_SAVE_LOAD`, OPTIONS as `GP_OPTIONS`, and NEW GAME's
|
|
//! chain as `DLG_SELECT_DIFFICULTY` -> `SELECT DATA`, all measured destinations
|
|
//! that this export cannot reach.
|
|
//!
|
|
//! This asks the cheap question before anyone refactors the exporter: does the
|
|
//! EXISTING build detector find anything in those archives? It changes nothing
|
|
//! and writes nothing.
|
|
//!
|
|
//! cargo run --release -p sylpheed-export --example probe_archives
|
|
use sylpheed_formats::{pak::PakArchive, ui_layout};
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
let disc = std::env::var("SYLPHEED_DISC").unwrap_or_else(|_| "/disc".into());
|
|
let mut names: Vec<String> = std::fs::read_dir(format!("{disc}/dat"))?
|
|
.filter_map(|e| e.ok())
|
|
.map(|e| e.file_name().to_string_lossy().into_owned())
|
|
.filter(|n| n.ends_with(".pak"))
|
|
.collect();
|
|
names.sort();
|
|
println!("{:<32} {:>7} {:>8}", "archive", "entries", "builds");
|
|
for n in names {
|
|
let path = format!("{disc}/dat/{n}");
|
|
let Ok(ar) = PakArchive::open(&path) else {
|
|
println!("{n:<32} {:>7} {:>8}", "-", "open failed");
|
|
continue;
|
|
};
|
|
let total = ar.entries().len();
|
|
let builds = ar
|
|
.entries()
|
|
.iter()
|
|
.filter(|e| ar.read(e).map(|b| ui_layout::is_build(&b)).unwrap_or(false))
|
|
.count();
|
|
if builds > 0 || n.contains("OPTIONS") || n.contains("SAVE") || n.contains("DIALOG") {
|
|
println!("{n:<32} {total:>7} {builds:>8}");
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|