//! Are `palogo_gamearts_eff` / `palogo_seta_eff` dwell-FALLBACK cases, or PLATEAU //! cases? The port agent lists them among `GP_TITLE`'s four visible fallback //! fires; this census listed only `palogo_sqex_eff` and `palogo_anima_eff`. //! //! It matters because the two are different defects. A plateau is a pose the //! element genuinely HOLDS, and `rest_plateau()` returning it is correct. Only the //! fallback is the unsound path. //! cargo run -p sylpheed-formats --example palogo_eff_check use std::path::PathBuf; use sylpheed_formats::{pak::PakArchive, ui_layout}; 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"); for (i, e) in ar.entries().iter().enumerate() { let Ok(by) = ar.read(e) else { continue }; let Some(b) = ui_layout::parse_build(&by) else { continue; }; for el in &b.elements { if !el.name.starts_with("palogo") || !el.name.contains("eff") { continue; } // A single-keyframe element has no gap to maximise, so neither path // applies and `rest()` trivially returns the only pose. Excluding it // here matches the census, which filters `len < 2`. if el.keyframes.len() < 2 { continue; } let plateau = el.keyframes.windows(2).position(|w| { w[0].x == w[1].x && w[0].y == w[1].y && w[0].scale_x == w[1].scale_x && w[0].scale_y == w[1].scale_y && w[0].fade == w[1].fade }); let ks: Vec = el .keyframes .iter() .map(|k| { format!( "{}:a{} {},{} {}%", k.time.map(|v| v.to_string()).unwrap_or("-".into()), (k.fade >> 24) & 0xff, k.x, k.y, k.scale_x ) }) .collect(); let r = el.rest(); println!("e{i:<3} {:24} kf=[{}]", el.name, ks.join(" ")); println!( " plateau at pair {:?} -> path: {} rest a={} t={:?}", plateau, if plateau.is_some() { "PLATEAU (sound: the pose is held)" } else { "DWELL FALLBACK (unsound)" }, r.map(|k| (k.fade >> 24) & 0xff).unwrap_or(0), r.and_then(|k| k.time) ); } } }