Serves Q6's open question. boot-config-and-gamepart-registry.md records a count-match for the title part's event numbers -- four menu items load an external archive, EXTRAS stays inside GP_TITLE -- explicitly as an observation rather than a decode. Half of it is disc-checkable and now has support. Every button record in all 16 GP_TITLE entries: ptbtn00 (the plate), ptbtn01..05 (main menu), ptbtn11..13 (EXTRAS). No fourth button screen, so no DIFFICULTY build, and DIFFICULTY is what NEW GAME opens. The other four destinations have their own paks -- GP_OPTIONS, GP_SAVE_LOAD, GP_TUTORIAL -- while EXTRAS' two children are GP_MISSION_SELECT and GP_MOVIE_THEATER, so EXTRAS is internal and its children are not. Still NOT a decode of the event numbers: the shape the count-match asserts is real on the disc, but nothing shows a given event is a given row. Negative recorded with its reach: DIFFICULTY's build is not located. I searched for an 8-button-record build on the assumption its four items pair with f variants, as GP_TITLE's screens do. They may not, so the negative is narrower than 'not found'. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
31 lines
1.2 KiB
Rust
31 lines
1.2 KiB
Rust
//! Every button record in `GP_TITLE.pak`, per entry.
|
|
//!
|
|
//! Testing half of the count-match in boot-config-and-gamepart-registry.md:
|
|
//! "four menu items load an external archive, EXTRAS stays inside GP_TITLE".
|
|
//! If DIFFICULTY (NEW GAME's destination, EASY/NORMAL/HARD/BACK) is also inside
|
|
//! GP_TITLE, then NEW GAME loads nothing external and that reading is wrong.
|
|
//!
|
|
//! cargo run -p sylpheed-formats --example gp_title_buttons
|
|
use sylpheed_formats::{pak::PakArchive, ui_layout};
|
|
use std::path::PathBuf;
|
|
|
|
fn main() {
|
|
let root = PathBuf::from(std::env::var("SYLPHEED_DISC").expect("SYLPHEED_DISC"));
|
|
let ar = PakArchive::open(root.join("dat/GP_TITLE.pak")).expect("GP_TITLE.pak");
|
|
for (i, e) in ar.entries().iter().enumerate() {
|
|
let Ok(by) = ar.read(e) else { continue };
|
|
let Some(b) = ui_layout::parse_build(&by) else { continue };
|
|
let mut btns: Vec<String> = b
|
|
.records
|
|
.keys()
|
|
.filter(|n| n.starts_with("ptbtn"))
|
|
.cloned()
|
|
.collect();
|
|
btns.sort();
|
|
if btns.is_empty() {
|
|
continue;
|
|
}
|
|
println!("entry {i:2} {:2} button records {:?}", btns.len(), btns);
|
|
}
|
|
}
|