//! Does anything in the declaration entry mark a **focused** button state, or is //! the pairing really just a naming convention? //! //! `mark_focused_states` pairs `pgmenu_btn00f.t32` with `pgmenu_btn00.t32` by //! name, and the backlog has carried the obvious suspicion ever since: `kind` is //! a flags word — `0x10` means untextured primitive, `0x4` a repeated instance, //! `0x3002` a button record — so a focus bit would be the cheapest possible //! answer. This sweeps every screen build on the disc and asks the question //! exactly, rather than plausibly. //! //! It is written to be able to FAIL to find anything: the interesting outcome is //! as likely to be "no bit distinguishes them" as "here is the bit", and either //! way the number is what goes in the docs. use std::collections::HashMap; use std::path::{Path, PathBuf}; use sylpheed_formats::{pak::PakArchive, ratc, ui_layout}; mod common; use common::disc_root; const DECL_TABLE_AT: usize = 0x20; const DECL_ENTRY: usize = 60; fn for_each_build(root: &Path, mut f: impl FnMut(&str, &[u8])) { let mut paks: Vec = std::fs::read_dir(root.join("dat")) .expect("dat/") .flatten() .map(|e| e.path()) .filter(|p| p.extension().and_then(|s| s.to_str()) == Some("pak")) .collect(); paks.sort(); for p in &paks { let name = p.file_name().unwrap().to_string_lossy().to_string(); let Ok(arc) = PakArchive::open(p) else { continue; }; for e in arc.entries() { let Ok(bytes) = arc.read(e) else { continue }; if ratc::is_ratc(&bytes) { f(&name, &bytes); } } } } fn word_at(bundle: &[u8], index: usize, off: usize) -> Option { let at = DECL_TABLE_AT + index * DECL_ENTRY + off; bundle .get(at..at + 4) .map(|b| u32::from_be_bytes([b[0], b[1], b[2], b[3]])) } /// Compare every name-paired (focused, base) pair on the disc, word by word. #[test] fn focused_and_base_declaration_entries_are_compared_word_by_word() { let Some(root) = disc_root() else { eprintln!("SKIP: extracted disc not found (set SYLPHEED_DISC to enable)"); return; }; let mut pairs = 0usize; // For each unread word of the 60-byte entry, how often does it differ? let mut differs: HashMap = HashMap::new(); // kind bits that are set on the focused entry and clear on its base. let mut set_on_focused: HashMap = HashMap::new(); let mut kind_equal = 0usize; let mut examples: Vec = Vec::new(); for_each_build(&root, |pak, bytes| { let Some(build) = ui_layout::parse_build(bytes) else { return; }; if build.from_fallback { return; } let index_of: HashMap = build .elements .iter() .enumerate() .map(|(i, e)| (e.name.to_ascii_lowercase(), i)) .collect(); for (i, el) in build.elements.iter().enumerate() { if !el.focused { continue; } let l = el.name.to_ascii_lowercase(); let Some((stem, ext)) = l.rsplit_once('.') else { continue; }; let base_name = format!("{}.{}", &stem[..stem.len() - 1], ext); let Some(&j) = index_of.get(&base_name) else { continue; }; pairs += 1; let base = &build.elements[j]; if el.kind == base.kind { kind_equal += 1; } else { let only_focused = el.kind & !base.kind; for bit in 0..32 { if only_focused & (1 << bit) != 0 { *set_on_focused.entry(1 << bit).or_default() += 1; } } } for off in (0..DECL_ENTRY).step_by(4) { if off < 28 { continue; // the name } let (a, b) = (word_at(bytes, i, off), word_at(bytes, j, off)); if a.is_some() && a != b { *differs.entry(off).or_default() += 1; } } if examples.len() < 6 { examples.push(format!( "{pak}: {} kind {:#x} vs base {} kind {:#x}", el.name, el.kind, base.name, base.kind )); } } }); eprintln!("focused/base pairs on the disc: {pairs}"); eprintln!("pairs whose `kind` is IDENTICAL: {kind_equal}"); let mut bits: Vec<_> = set_on_focused.iter().collect(); bits.sort(); eprintln!("kind bits set on focused but not base: {bits:?}"); let mut d: Vec<_> = differs.iter().collect(); d.sort(); eprintln!("declaration words that ever differ (offset -> pairs): {d:?}"); for e in &examples { eprintln!(" {e}"); } assert!( pairs > 0, "no focused/base pairs found — the sweep is broken" ); // MEASURED 2026-08-24, and asserted so the answer cannot rot back into a // suspicion: all 54 pairs on the disc carry the SAME `kind`, no bit is ever // set on the focused entry and clear on its base, and the only words of the // 60-byte declaration entry that ever differ are +48 and +52 — the PIVOT, // i.e. where the sprite sits, not what it is. So the entry does not mark a // focused state at all, and the naming pairing is not a shortcut around a // field that exists: there is no field. assert_eq!(pairs, 54, "the disc has 54 name-paired focused elements"); assert_eq!( kind_equal, pairs, "some pair's `kind` differs from its base" ); assert!( set_on_focused.is_empty(), "a kind bit distinguishes focused from base: {set_on_focused:?}" ); let mut offs: Vec = differs.keys().copied().collect(); offs.sort(); assert_eq!( offs, vec![48, 52], "a declaration word other than the pivot differs between focused and base" ); }