This branch predates CI on `main`. `cargo fmt --all` only; no behaviour. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
66 lines
2.6 KiB
Rust
66 lines
2.6 KiB
Rust
//! Does a textured element's declaration carry anything that distinguishes the
|
|
//! two FRAME elements from every other element on the main menu?
|
|
//!
|
|
//! `sylpheed-port` asks for the blend/alpha mode of `ptframe1`/`ptframe2`. Prior
|
|
//! work is on `.prm` PRIMITIVES (`ui-prm-blend-mode.md`, undecodable with reach —
|
|
//! no field, the declaration words are constant) and on a refuted `T8aD +0x04`
|
|
//! bit. Neither covers a `.t32` element's own declaration entry, which is 60
|
|
//! bytes and mostly unread.
|
|
//!
|
|
//! This dumps every declaration entry on the menu and reports, per 4-byte word,
|
|
//! whether the two frames share a value that no other element has. A word that
|
|
//! separates exactly those two is a candidate; one that does not, is not.
|
|
//!
|
|
//! cargo run -p sylpheed-formats --example decl_entry_diff
|
|
use std::path::PathBuf;
|
|
use sylpheed_formats::{pak::PakArchive, ui_layout};
|
|
|
|
const AT: usize = 0x20;
|
|
const N: usize = 60;
|
|
|
|
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");
|
|
let by = ar.read(&ar.entries()[5]).expect("entry 5");
|
|
let b = ui_layout::parse_build(&by).expect("build");
|
|
let names: Vec<String> = b.elements.iter().map(|e| e.name.clone()).collect();
|
|
let frames: Vec<usize> = names
|
|
.iter()
|
|
.enumerate()
|
|
.filter(|(_, n)| n.starts_with("ptframe"))
|
|
.map(|(i, _)| i)
|
|
.collect();
|
|
println!("{} elements; frames at indices {:?}", names.len(), frames);
|
|
|
|
let word = |i: usize, w: usize| -> u32 {
|
|
let o = AT + i * N + w * 4;
|
|
u32::from_be_bytes([by[o], by[o + 1], by[o + 2], by[o + 3]])
|
|
};
|
|
println!("\nper-word: does a value separate EXACTLY the two frames?");
|
|
for w in 0..N / 4 {
|
|
let fv: Vec<u32> = frames.iter().map(|&i| word(i, w)).collect();
|
|
let same_in_frames = fv.windows(2).all(|p| p[0] == p[1]);
|
|
let others: Vec<u32> = (0..names.len())
|
|
.filter(|i| !frames.contains(i))
|
|
.map(|i| word(i, w))
|
|
.collect();
|
|
let unique = same_in_frames && !others.contains(&fv[0]);
|
|
let distinct = {
|
|
let mut v: Vec<u32> = (0..names.len()).map(|i| word(i, w)).collect();
|
|
v.sort_unstable();
|
|
v.dedup();
|
|
v.len()
|
|
};
|
|
println!(
|
|
" +0x{:02X} frames {:?} distinct values {distinct:2}{}",
|
|
w * 4,
|
|
fv.iter().map(|v| format!("{v:08X}")).collect::<Vec<_>>(),
|
|
if unique {
|
|
" <- SEPARATES THE FRAMES"
|
|
} else {
|
|
""
|
|
}
|
|
);
|
|
}
|
|
}
|