//! How do a parent record's alpha ramp and its nested `.rat` leaf's compose? //! //! The port emits both but will not draw the leaf without knowing the rule -- //! rightly, since drawing on a guess trades a visible 1.82 % error for an //! invisible wrong one. There is an oracle for this: the GPU draw capture //! records **vertex colours**, and on the title's `ptloop` draw they are //! `C3FFFFFF` and `B6FFFFFF` -- alpha **195** and **182**, not 255. So the game's //! composed alpha is observable, and a candidate rule either predicts those two //! numbers or does not. //! //! cargo run -p sylpheed-formats --example leaf_alpha_compose -- use sylpheed_formats::{pak, ui_layout}; fn alpha_of(kf: &ui_layout::Keyframe) -> u32 { // The keyframe block's +0 is an ARGB fade colour; alpha is its high byte. kf.fade >> 24 } fn main() { let path = std::env::args().nth(1).expect("usage: "); let ar = pak::PakArchive::open(&path).expect("open"); let e = &ar.entries()[4]; // GP_TITLE entry 4 = the English title let bytes = ar.read(e).expect("read"); let build = ui_layout::parse_build(&bytes).expect("build"); for name in ["ptloop01.rat", "ptloop02.rat"] { println!("\n=== {name} ==="); if let Some(el) = build.elements.iter().find(|x| x.name == name) { println!(" PARENT keyframes (t, alpha, scale, rot, x,y):"); for k in &el.keyframes { println!(" t={:<5} a={:<4} scale=({},{}) rot={:<5} ({},{})", k.time.map(|t| t as i64).unwrap_or(-1), alpha_of(k), k.scale_x, k.scale_y, k.rotation_deg, k.x, k.y); } } match build.records.get(name) { Some(&(off, size)) => { let leaf = &bytes[off..off + size]; match ui_layout::parse_build(leaf) { Some(lb) => { for le in &lb.elements { println!(" LEAF element {:?}:", le.name); for k in &le.keyframes { println!(" t={:<5} a={:<4} scale=({},{}) rot={:<5} ({},{})", k.time.map(|t| t as i64).unwrap_or(-1), alpha_of(k), k.scale_x, k.scale_y, k.rotation_deg, k.x, k.y); } } } None => println!(" leaf did not parse"), } } None => println!(" no leaf record"), } } println!("\nOBSERVED in the draw capture: quad A alpha 195 (0xC3), quad B alpha 182 (0xB6)"); }