Three of my errors were the label rather than the measurement, and a correction in one document did not reach the next page I wrote. The port built check-authored-vs-declared for values the disc can arbitrate and named the gap: capture-only values that name an element rest entirely on my label. check_labels.py closes that for the cases where the identification was itself made by matching a declared quantity -- 8 checks over two captures, all passing, with a --selftest that points the plate label at ptcopyright (the real error) and must fail. It does, at 82-83% against a 5% tolerance, with the other checks still passing so the failure is localised. Refutation of the port's "all five figures are also declared": lands for one. ptbtn00f's peak alpha of 80 is not declared anywhere -- ptbtn00.rat's parent peaks at 255 and its leaf is one keyframe at 255 flat, with the 120-unit loop declared but no amplitude. The period checks out; the amplitude is capture-only and their check cannot see it. Opens a 🟡 not mine originally: the corpus attributes the 120-unit loop to ptbtn00f, but it belongs to ptbtn00.rat whose leaf is ptbtn00.t32. Left uncorrected since the identification rests on the period, which holds under either name. Adds examples/leaf_keyframes.rs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jc4pciRArGHfxGGhEbwp5t
33 lines
1.6 KiB
Rust
33 lines
1.6 KiB
Rust
//! Dump the keyframes of any nested `.rat` leaf by name.
|
|
//!
|
|
//! cargo run -p sylpheed-formats --example leaf_keyframes -- GP_TITLE ptbtn00.rat 2 3 4
|
|
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 argv: Vec<String> = std::env::args().skip(1).collect();
|
|
let pak = argv[0].clone();
|
|
let rec = argv[1].clone();
|
|
let builds: Vec<usize> = argv[2..].iter().filter_map(|a| a.parse().ok()).collect();
|
|
let ar = PakArchive::open(root.join(format!("dat/{pak}.pak"))).expect("pak");
|
|
for e in builds {
|
|
let Ok(by) = ar.read(&ar.entries()[e]) else { continue };
|
|
let Some(b) = ui_layout::parse_build(&by) else { continue };
|
|
let Some(&(lo, ls)) = b.records.get(rec.as_str()) else { continue };
|
|
let leaf = &by[lo..(lo + ls).min(by.len())];
|
|
println!("=== {pak} entry {e} — {rec} (leaf {ls} bytes) ===");
|
|
if let Some(u) = ui_layout::loop_length_units(leaf) { println!(" declared loop: {u} units"); }
|
|
if let Some(lb) = ui_layout::parse_build(leaf) {
|
|
for el in &lb.elements {
|
|
println!(" {} — {} keyframes", el.name, el.keyframes.len());
|
|
for (i, k) in el.keyframes.iter().enumerate() {
|
|
println!(" kf{i:<2} t={:<5} x={:<6} y={:<6} fade={:08X} (alpha {:3})",
|
|
k.time.map(|t| t.to_string()).unwrap_or_else(|| "-".into()),
|
|
k.x, k.y, k.fade, k.fade >> 24);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|