Answers the port's ask about ptframe1/ptframe2, whose residual is uniquely higher on flat pixels than edges and signed one direction -- a body-intensity difference. Prior work covers .prm primitives and a refuted T8aD +0x04 bit; neither covers a .t32 element. All 15 words of the 60-byte declaration entry are read: 3 are the name, 8 constant, the rest kind, focus index, position and pivot. The frames are kind 0, identical to every other plain sprite. One candidate found and refuted by myself: T8aD +0x08 is the only word where both frames agree uniquely on that screen, at 0x8050 -- but 38 sprites carry it disc-wide, only 8 named frame, and the high byte tracks the archive. It is an atlas/format word, not a mode. Also records a false positive of my own test: +0x00 and +0x08 first read as 'separating the frames' because those words are the name string. So any blend the port picks is authored. Reach: not looked at the executable's draw path, where a mode selected in code rather than data would live. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
33 lines
1.4 KiB
Rust
33 lines
1.4 KiB
Rust
//! Which elements carry which values at the low-cardinality declaration words?
|
|
//!
|
|
//! `decl_entry_diff` found nothing separating `ptframe1`/`ptframe2` except their
|
|
//! NAME — +0x00 and +0x08 are the name string ("ptfr", ".t32"), so those two hits
|
|
//! are a false positive of that test, not a field.
|
|
//!
|
|
//! The remaining candidates for a per-element mode flag are the words with few
|
|
//! distinct values: +0x28 (3) and +0x2C (6). This prints who has what.
|
|
//!
|
|
//! cargo run -p sylpheed-formats --example decl_flag_words
|
|
use sylpheed_formats::{pak::PakArchive, ui_layout};
|
|
use std::path::PathBuf;
|
|
|
|
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 w = |i: usize, off: usize| -> u32 {
|
|
let o = AT + i * N + off;
|
|
u32::from_be_bytes([by[o], by[o + 1], by[o + 2], by[o + 3]])
|
|
};
|
|
println!("{:<22} {:>10} {:>10} {:>10} {:>10}", "element", "+0x28", "+0x2C", "+0x34", "kind");
|
|
for (i, e) in b.elements.iter().enumerate() {
|
|
let mark = if e.name.starts_with("ptframe") { " <- FRAME" } else { "" };
|
|
println!("{:<22} {:>10} {:>10} {:>10} {:>#10x}{mark}",
|
|
e.name, w(i, 0x28), w(i, 0x2C) as i32, w(i, 0x34), e.kind);
|
|
}
|
|
}
|