re: settle the 49.6/92.3 split -- both are real, and the second explanation was wrong too
sylpheed-port corrected their own reconciliation and I reproduced it: 0 nested records on this disc lack a timed keyframe. All 1530 are static -- timed, every pose at t == 0 -- so the question is well-formed there and 'not exact' is a real answer, not an absent one. A static record still declares a cycle length. So the two percentages are two populations and neither corrects the other: 92.3 % of animated records, 49.6 % of all nested records including static ones, same numerator 1643. Both need their population attached. Two wrong explanations preceded this, both mine to carry: that my scan filtered untimed records, which .max() returning Some(0) prevents, and then their 'questions never asked' framing which I adopted. The page is rewritten to the settled state rather than stacked. Nothing the port depends on moved at any point. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
51
crates/sylpheed-formats/examples/static_record_census.rs
Normal file
51
crates/sylpheed-formats/examples/static_record_census.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
//! Are the records with `max t == 0` UNTIMED, or timed with every pose at 0?
|
||||
//!
|
||||
//! I wrote that 1 530 records are "questions never asked" — no timed keyframe, so
|
||||
//! `max t` is 0 by absence. `sylpheed-port` now says zero records on this disc are
|
||||
//! like that: all 1 530 are timed, every pose at t = 0, so the question is
|
||||
//! well-formed and "not exact" is a real answer. This checks it.
|
||||
//!
|
||||
//! cargo run -p sylpheed-formats --example static_record_census
|
||||
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 mut paks: Vec<_> = std::fs::read_dir(root.join("dat"))
|
||||
.expect("dat")
|
||||
.filter_map(|e| e.ok().map(|e| e.path()))
|
||||
.filter(|p| p.extension().map(|x| x == "pak").unwrap_or(false))
|
||||
.collect();
|
||||
paks.sort();
|
||||
let (mut untimed, mut all_zero, mut nonzero) = (0usize, 0usize, 0usize);
|
||||
for p in &paks {
|
||||
let Ok(ar) = PakArchive::open(p) else { continue };
|
||||
for e in ar.entries() {
|
||||
let Ok(by) = ar.read(e) else { continue };
|
||||
let Some(b) = ui_layout::parse_build(&by) else { continue };
|
||||
for (_, (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 };
|
||||
let times: Vec<u32> = leaf
|
||||
.elements
|
||||
.iter()
|
||||
.flat_map(|el| el.keyframes.iter().filter_map(|k| k.time))
|
||||
.collect();
|
||||
if times.is_empty() {
|
||||
untimed += 1;
|
||||
} else if times.iter().max() == Some(&0) {
|
||||
all_zero += 1;
|
||||
} else {
|
||||
nonzero += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("nested RATC records that parse: {}", untimed + all_zero + nonzero);
|
||||
println!(" NO timed keyframe at all : {untimed}");
|
||||
println!(" timed, every pose at t == 0 : {all_zero}");
|
||||
println!(" timed, largest t > 0 : {nonzero}");
|
||||
}
|
||||
Reference in New Issue
Block a user