This branch predates CI on `main`. `cargo fmt --all` only; no behaviour. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
64 lines
2.7 KiB
Rust
64 lines
2.7 KiB
Rust
//! Do `GP_TITLE` records that declare a cycle while sitting at t = 0 actually move?
|
|
//!
|
|
//! A static record still declares a cycle length, so a nonzero `+0x08` against a
|
|
//! largest keyframe time of 0 is a real disagreement. `sylpheed-port` turned that
|
|
//! into a check on the screens they ship: 20 such records in GP_TITLE, and none
|
|
//! with any element carrying more than one pose — so the declared cycle is
|
|
//! visually inert and holding them still is correct.
|
|
//!
|
|
//! This re-derives it. If any record had a multi-pose element, the port would be
|
|
//! holding something the disc says animates.
|
|
//!
|
|
//! cargo run -p sylpheed-formats --example static_cycle_inert
|
|
use std::path::PathBuf;
|
|
use sylpheed_formats::{pak::PakArchive, ui_layout};
|
|
|
|
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");
|
|
let (mut total, mut static_cycle, mut multipose) = (0usize, 0usize, 0usize);
|
|
for e in ar.entries() {
|
|
let Ok(by) = ar.read(e) else { continue };
|
|
let Some(b) = ui_layout::parse_build(&by) else {
|
|
continue;
|
|
};
|
|
for (name, (off, size)) in &b.records {
|
|
let rec = &by[*off..(*off + *size).min(by.len())];
|
|
if rec.len() < 0x10 || &rec[0..4] != b"RATC" {
|
|
continue;
|
|
}
|
|
let Some(leaf) = ui_layout::parse_build(rec) else {
|
|
continue;
|
|
};
|
|
total += 1;
|
|
let times: Vec<u32> = leaf
|
|
.elements
|
|
.iter()
|
|
.flat_map(|el| el.keyframes.iter().filter_map(|k| k.time))
|
|
.collect();
|
|
let cycle = ui_layout::loop_length_units(rec).unwrap_or(0);
|
|
if times.is_empty() || times.iter().max() != Some(&0) || cycle == 0 {
|
|
continue;
|
|
}
|
|
static_cycle += 1;
|
|
let worst = leaf
|
|
.elements
|
|
.iter()
|
|
.map(|el| el.keyframes.len())
|
|
.max()
|
|
.unwrap_or(0);
|
|
if worst > 1 {
|
|
multipose += 1;
|
|
println!(
|
|
" 🔴 {name} declares {cycle} units and has an element with {worst} poses"
|
|
);
|
|
} else if name.starts_with("ptbtn1") {
|
|
println!(" {name:16} declares {cycle} units, max poses/element {worst}");
|
|
}
|
|
}
|
|
}
|
|
println!("\nnested records in GP_TITLE : {total}");
|
|
println!("declaring a cycle with every pose at t == 0 : {static_cycle}");
|
|
println!("...of those, any element with MORE THAN ONE pose : {multipose}");
|
|
}
|