//! Does a screen declare its own OPAQUE BLACK backdrop? Disc-wide. //! //! `sylpheed-port` observed that the splash builds declare `palogo_eff0.prm` as a //! full-screen primitive at t=0 with `fade_argb 0xff000000` -- alpha 255 over RGB //! 000000 -- and turned it into a candidate predicate: a declared opaque-black //! backdrop separates STANDALONE screens from COMPOSITED ones. On their sixteen //! exported screens it splits 12 / 4, with all four exceptions independently known //! to be composited (the two `press_start` plates, and two loading builds that //! carry the `pgloading_*` set without its backdrop). //! //! That matters because the corpus previously told them "no content rule exists, //! take the entry index" -- correct for the question asked (recognise the splash), //! but this is a content rule for a different and useful question. They asked for //! it to be tested against an archive they do not have. This is that test. //! //! CONTROL: it must reproduce the 12/4 split on GP_TITLE's sixteen composable //! bundles before its disc-wide numbers mean anything. //! //! cargo run -p sylpheed-formats --example black_backdrop_predicate use std::io::Write; use std::path::PathBuf; use sylpheed_formats::{pak::PakArchive, ui_layout}; /// A screen declares its own backdrop if some `.prm` primitive holds /// `fade == 0xff000000` at t = 0: full alpha over black. fn has_black_backdrop(b: &ui_layout::UiBuild) -> Option { for el in &b.elements { if !el.name.ends_with(".prm") { continue; } if let Some(k) = el.keyframes.iter().find(|k| k.time == Some(0)) { if k.fade == 0xff00_0000 { return Some(el.name.clone()); } } } None } fn main() { let root = PathBuf::from(std::env::var("SYLPHEED_DISC").expect("SYLPHEED_DISC")); println!("== CONTROL: GP_TITLE's 16 composable bundles (port reports 12 with, 4 without)"); let ar = PakArchive::open(root.join("dat/GP_TITLE.pak")).expect("GP_TITLE.pak"); let (mut y, mut n) = (0, 0); for e in 0..16usize { let Ok(by) = ar.read(&ar.entries()[e]) else { continue; }; let Some(b) = ui_layout::parse_build(&by) else { continue; }; match has_black_backdrop(&b) { Some(nm) => { y += 1; println!(" entry {e:>2} YES {nm}") } None => { n += 1; println!(" entry {e:>2} no") } } } println!(" -> {y} with, {n} without\n"); println!("== DISC-WIDE, over every screen build"); let mut paks: Vec = std::fs::read_dir(root.join("dat")) .expect("dat/") .filter_map(|e| e.ok().map(|e| e.path())) .filter(|p| p.extension().is_some_and(|x| x == "pak")) .collect(); paks.sort(); let (mut tot, mut with) = (0usize, 0usize); for pak in &paks { let Ok(ar) = PakArchive::open(pak) else { continue; }; let name = pak.file_name().unwrap().to_string_lossy().to_string(); let (mut t, mut w) = (0usize, 0usize); for e in ar.entries() { let Ok(by) = ar.read(e) else { continue }; if !ui_layout::is_build(&by) { continue; } let Some(b) = ui_layout::parse_build(&by) else { continue; }; t += 1; if has_black_backdrop(&b).is_some() { w += 1 } } if t > 0 { println!("{name:30} {w:4} / {t:<4} declare a black backdrop"); std::io::stdout().flush().ok(); } tot += t; with += w; } println!( "\n{with} of {tot} screen builds disc-wide declare an opaque-black backdrop \ ({:.1} %)", 100.0 * with as f64 / tot as f64 ); println!("--- END ---"); }