//! The keyframe record's two unexplained words (`+4`, `+8`) and the fade/tint — //! do any of them separate the four elements the port measures as rendering too //! dark (`ptframe1`/`2`, `ptframe3`/`4`) from the ones it measures as accurate? //! //! The T8aD header does not: no word and no bit of `+0x04`/`+0x08` puts the four //! frames on one side and `pteff10` (max alpha 130, wholly semi-transparent, and //! rendered nearly exact) on the other. The keyframe is the other place a //! per-element draw mode could live. //! //! cargo run -p sylpheed-formats --example frame_keyframe_unknowns 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 ar = PakArchive::open(root.join("dat/GP_TITLE.pak")).expect("GP_TITLE"); println!("{:<22} {:>5} {:>3} {:>10} {:>10} {:>8} {:>8} {:>8}", "element", "build", "kf", "unknown_4", "unknown_8", "fade", "tint", "rot"); let mut frame_sets: Vec<(String, i32, i32, u32, u32, i32)> = Vec::new(); let mut other_sets: Vec<(String, i32, i32, u32, u32, i32)> = Vec::new(); for build in [5usize, 6] { let by = ar.read(&ar.entries()[build]).expect("entry"); let b = ui_layout::parse_build(&by).expect("build"); for e in &b.elements { for (i, k) in e.keyframes.iter().enumerate() { println!("{:<22} {build:>5} {i:>3} {:>10} {:>10} {:08X} {:08X} {:>8}", e.name, k.unknown_4, k.unknown_8, k.fade, k.tint, k.rotation_deg); let row = (e.name.clone(), k.unknown_4, k.unknown_8, k.fade, k.tint, k.rotation_deg); if e.name.contains("frame") { frame_sets.push(row) } else { other_sets.push(row) } } } } println!("\nframe keyframes: {} other keyframes: {}", frame_sets.len(), other_sets.len()); for (label, get) in [ ("unknown_4", 0usize), ("unknown_8", 1), ("fade", 2), ("tint", 3), ("rotation", 4), ] { let val = |r: &(String, i32, i32, u32, u32, i32)| -> i64 { match get { 0 => r.1 as i64, 1 => r.2 as i64, 2 => r.3 as i64, 3 => r.4 as i64, _ => r.5 as i64 } }; let fv: std::collections::BTreeSet = frame_sets.iter().map(val).collect(); let ov: std::collections::BTreeSet = other_sets.iter().map(val).collect(); let only_frames: Vec<&i64> = fv.iter().filter(|v| !ov.contains(v)).collect(); println!("{label:<10} frames take {:?} others take {} distinct values; frame-only values: {:?}", fv, ov.len(), only_frames); } }