This branch predates CI on `main`. `cargo fmt --all` only; no behaviour. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
50 lines
1.9 KiB
Rust
50 lines
1.9 KiB
Rust
// The settled screen, computed from the keyframe times alone.
|
|
//
|
|
// `rest()` picks each element's last HOLD keyframe independently, which is right
|
|
// for an element that ends settled and wrong for a transient: a 2-frame flash
|
|
// holds at its PEAK, so `rest()` leaves it burning forever. The settled screen is
|
|
// instead one INSTANT that every element is posed at, and the instant to pick is
|
|
// inside the longest interval during which no element has a keyframe at all.
|
|
use sylpheed_formats::{pak, ui_layout};
|
|
fn main() {
|
|
let mut a = std::env::args().skip(1);
|
|
let pk = a.next().unwrap();
|
|
let ar = pak::PakArchive::open(&pk).unwrap();
|
|
let only: Option<usize> = a.next().and_then(|s| s.parse().ok());
|
|
for (i, e) in ar.entries().iter().enumerate() {
|
|
if let Some(o) = only {
|
|
if o != i {
|
|
continue;
|
|
}
|
|
}
|
|
let Ok(by) = ar.read(e) else { continue };
|
|
let Some(b) = ui_layout::parse_build(&by) else {
|
|
continue;
|
|
};
|
|
if b.elements.len() < 2 {
|
|
continue;
|
|
}
|
|
let mut ts: Vec<u32> = b
|
|
.elements
|
|
.iter()
|
|
.flat_map(|el| el.keyframes.iter().filter_map(|k| k.time))
|
|
.collect();
|
|
if ts.len() < 2 {
|
|
continue;
|
|
}
|
|
ts.sort_unstable();
|
|
ts.dedup();
|
|
// longest gap between consecutive keyframe times
|
|
let (mut best, mut lo, mut hi) = (0u32, 0u32, 0u32);
|
|
for w in ts.windows(2) {
|
|
if w[1] - w[0] > best {
|
|
best = w[1] - w[0];
|
|
lo = w[0];
|
|
hi = w[1];
|
|
}
|
|
}
|
|
println!("{:>4} {:<28} times {:>3} span {:>4} settle window [{lo},{hi}] = {best} units ({:.2}s) -> t={}",
|
|
i, format!("{:08x}",e.name_hash), ts.len(), ts.last().unwrap(), best as f64/60.0, lo+best/2);
|
|
}
|
|
}
|