re: the proven offsets ARE candidates -- these mis-anchors are selection failures

debug_vertex_run_starts exposes the anchor scan's candidate list: Stage_S01 has
15710 stride-24 starts and all three capture-proven offsets (0x3c55d8 twin,
0x40e418 bridge, 0x44a32c eng_02_l) are among them. anchor_pool_mesh takes the
first that validates, so an earlier lookalike wins. Scoped to the current
decoder's e106 cases; does not overturn the residual-51 finding.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 02:11:41 +00:00
parent 26f1bdf6fd
commit 76a433f75c
4 changed files with 65 additions and 17 deletions

View File

@@ -154,7 +154,12 @@ fn main() {
let n: usize = m.meshes.iter().map(|s| s.positions.len()).sum();
by_count.entry(n).or_default().push(m.name.clone());
}
println!("{:<12} {:>7} {:<44} our resources with that vcount", "file offset", "vcount", "claimed by our decode");
// Is a capture-proven offset even a candidate the scan considers?
// Absent ⇒ the run scan misses it; present ⇒ selection picked another.
let starts: BTreeSet<usize> =
sylpheed_formats::mesh::debug_vertex_run_starts(&bytes, 24).into_iter().collect();
eprintln!("{} stride-24 candidate starts in this container", starts.len());
println!("{:<12} {:>7} {:>9} {:<44} our resources with that vcount", "file offset", "vcount", "candidate", "claimed by our decode");
for (off, vcount) in &drawn {
let who = ours
.get(off)
@@ -173,7 +178,8 @@ fn main() {
.next_back()
.map(|(o, v)| format!("{} @ -0x{:x}", v[0].0, off - o))
.unwrap_or_default();
println!("0x{off:<10x} {vcount:>7} {who:<44} {same:<34} {near}");
let cand = if starts.contains(off) { "yes" } else { "NO" };
println!("0x{off:<10x} {vcount:>7} {cand:>9} {who:<44} {same:<34} {near}");
}
return;
}

View File

@@ -613,6 +613,27 @@ impl Xbg7Model {
}
}
/// Diagnostic: the candidate vertex-buffer starts the stage anchor scan will
/// consider for a given `stride`, for one container. A runtime capture names the
/// offsets the engine really drew from (see `examples/shared_vbase_check.rs`), so
/// asking whether a proven offset is in this list separates the two possible
/// root causes of a mis-anchor: **absent** ⇒ the run scan misses it, **present**
/// ⇒ the scan sees it and the selection picks another.
pub fn debug_vertex_run_starts(bytes: &[u8], stride: usize) -> Vec<usize> {
if bytes.len() < 16 || &bytes[..4] != b"XPR2" {
return Vec::new();
}
let mut cur = Cursor::new(bytes);
let Ok(header) = Xpr2Header::read(&mut cur) else {
return Vec::new();
};
let data_base = header.header_size as usize;
if data_base >= bytes.len() {
return Vec::new();
}
vertex_run_starts(bytes, data_base, stride)
}
/// Scan the data section for offsets that begin a `stride`-sized unit-normal
/// vertex run (NORMAL is `f16×4` at vertex offset +12). A run *start* is an
/// offset whose normal is unit while the preceding stride slot's is not — i.e.