Refutes a DECISIONS claim and decodes the element the port withheld on my say-so. The claim that title_jp s ptlogo_eff2 at 125 percent is the single drawn element in the whole export at a scale that is not a whole multiple of 100 percent rested on a census of PARENTS only. Opening the 45 leaves as well finds thirteen distinct non-whole-multiple scales -- 75, 96, 99, 101, 103, 112, 125, 150, 204x208, 210x220, 250, and the 75x100 / 96x100 / 99x100 pairs -- with 125 among the rarest at two occurrences. ptlogo1 and ptlogo2 carry 101/103/112 on the ENGLISH title too, so it is not a Japanese-build peculiarity. The claim s real content was "the only one the port draws", which is about the export s element set rather than the disc. And ptlogo_eff2 is decoded. The 125 percent lasts 57 units, about 0.95 s -- a scale-0 to 125 to scale-0 flash between t=50 and t=107, a transient rather than a steady state, which is why it looked anomalous in a census of resting poses. The leaf draws at 100 percent as two superimposed copies of the same sprite at alpha 160 and 80, each rotating a full 360 degrees over 960 units: a slow double-layered spin, 16 s per revolution. This is exactly the case the ptloop rule could not separate. There the parent had expired so leaf-wins and parent-ignored were indistinguishable; here the parent carries real geometry including a scale that reaches zero twice. If parent scale gates the leaf the spin is a 0.95 s flash; if the leaf runs on its own timeline it spins for 16 s. Nothing on the disc chooses between them, and title_jp has no oracle capture, so it is undecodable in this container -- the port is right to withhold it, and the Japanese-locale capture MISSION has parked would settle it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
43 lines
1.8 KiB
Rust
43 lines
1.8 KiB
Rust
//! Dump a record's parent keyframes and its nested `.rat` leaf's, for any entry.
|
|
//!
|
|
//! cargo run -p sylpheed-formats --example leaf_dump -- <pak> <entry> <name>
|
|
use sylpheed_formats::{pak, ui_layout};
|
|
|
|
fn a(k: &ui_layout::Keyframe) -> u32 { k.fade >> 24 }
|
|
fn t(k: &ui_layout::Keyframe) -> i64 { k.time.map(|v| v as i64).unwrap_or(-1) }
|
|
|
|
fn show(tag: &str, els: &[ui_layout::Element]) {
|
|
for e in els {
|
|
println!(" {tag} {:?} pivot=({},{}) kind={:#x}", e.name, e.pivot_x, e.pivot_y, e.kind);
|
|
for k in &e.keyframes {
|
|
println!(" t={:<5} a={:<4} scale=({},{}) rot={:<5} pos=({},{}) tint={:#010x}",
|
|
t(k), a(k), k.scale_x, k.scale_y, k.rotation_deg, k.x, k.y, k.tint);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let mut it = std::env::args().skip(1);
|
|
let path = it.next().expect("pak");
|
|
let entry: usize = it.next().expect("entry").parse().expect("entry");
|
|
let want = it.next().expect("name");
|
|
let ar = pak::PakArchive::open(&path).expect("open");
|
|
let bytes = ar.read(&ar.entries()[entry]).expect("read");
|
|
let b = ui_layout::parse_build(&bytes).expect("build");
|
|
println!("entry {entry}: {} elements, design {}x{}", b.elements.len(), b.design_w, b.design_h);
|
|
let els: Vec<_> = b.elements.iter().filter(|e| e.name.contains(&want)).cloned().collect();
|
|
show("PARENT", &els);
|
|
for e in &els {
|
|
match b.records.get(&e.name) {
|
|
Some(&(off, size)) => {
|
|
println!(" -- leaf of {:?}: {size} B at {off}", e.name);
|
|
match ui_layout::parse_build(&bytes[off..off + size]) {
|
|
Some(lb) => show(" LEAF", &lb.elements),
|
|
None => println!(" leaf did not parse"),
|
|
}
|
|
}
|
|
None => println!(" -- {:?} has NO leaf record", e.name),
|
|
}
|
|
}
|
|
}
|