From 06f9af75ea31d38d58a484a23a80080ab51349bd Mon Sep 17 00:00:00 2001 From: sylph-decoder Date: Mon, 31 Aug 2026 02:50:35 +0000 Subject: [PATCH] re: decode the dialog table -- 70/70 records, DLG_SELECT_DIFFICULTY is id 2000 Chasing the reach I recorded this morning found the binding it said was missing. Every DLG_ string in the image is pointed at by one aligned word at a 12-byte stride: {u32 handler, u32 id, u32 name_ptr}, spanning 0x820A0A2C..0x820A0D68 with three distinct handlers. Complete -- 70 names, 70 records, none unmatched -- and the ids are banded and monotonic with a single gap at 24. Read from the image directly. Refutation attempt on the shared reach, which both agents had recorded: 'another four-button dialog with the same rows would be indistinguishable'. Scanned every build in every pak for four buttons within 6 px of 259/329/399/469. Control found both incumbents; zero rivals exist anywhere on the disc. So the geometric identification is unique disc-wide, which is stronger than what either of us claimed. Still unbound: id 2000 to a pak entry. The tie remains uniqueness plus the oracle capture, not a pointer. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v --- .../examples/four_button_row_rivals.rs | 55 +++++++++++++++++++ docs/re/data/difficulty-is-a-dialog.txt | 48 ++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 crates/sylpheed-formats/examples/four_button_row_rivals.rs diff --git a/crates/sylpheed-formats/examples/four_button_row_rivals.rs b/crates/sylpheed-formats/examples/four_button_row_rivals.rs new file mode 100644 index 00000000..1aff3697 --- /dev/null +++ b/crates/sylpheed-formats/examples/four_button_row_rivals.rs @@ -0,0 +1,55 @@ +//! Is `GP_DIALOG` 2/3 the ONLY build on the disc with four buttons at 259/329/399/469? +//! +//! Both agents recorded the same reach on the DIFFICULTY identification: entries +//! 2/3 are picked out by button count and geometry, not by a binding from +//! `DLG_SELECT_DIFFICULTY` to a pak entry, so "another four-button dialog with the +//! same rows would be indistinguishable". This tests whether such a rival exists. +//! +//! CONTROL: the scan must find GP_DIALOG 2 and 3 themselves. A rival-search that +//! cannot find the incumbent proves nothing. +//! +//! cargo run -p sylpheed-formats --example four_button_row_rivals +use sylpheed_formats::{pak::PakArchive, ui_layout}; +use std::path::PathBuf; + +const WANT: [i32; 4] = [259, 329, 399, 469]; + +fn main() { + let root = PathBuf::from(std::env::var("SYLPHEED_DISC").expect("SYLPHEED_DISC")); + 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().map(|x| x == "pak").unwrap_or(false)) + .collect(); + paks.sort(); + let (mut incumbent, mut rivals) = (0, 0); + for p in &paks { + let Ok(ar) = PakArchive::open(p) else { continue }; + let pname = p.file_name().unwrap().to_string_lossy().to_string(); + for (i, e) in ar.entries().iter().enumerate() { + let Ok(by) = ar.read(e) else { continue }; + let Some(b) = ui_layout::parse_build(&by) else { continue }; + let mut ys: Vec = b + .elements + .iter() + .filter(|el| el.name.contains("btn") && !el.name.contains('f')) + .map(|el| el.rest().map(|k| k.y).unwrap_or(el.pivot_y as i32)) + .collect(); + ys.sort(); + ys.dedup(); + if ys.len() != 4 { + continue; + } + let close = ys.iter().zip(WANT.iter()).all(|(a, b)| (a - b).abs() <= 6); + if close { + let is_inc = pname == "GP_DIALOG.pak" && (i == 2 || i == 3); + if is_inc { incumbent += 1 } else { rivals += 1 } + println!(" {}{pname:24} entry {i:4} rows {ys:?}", + if is_inc { "INCUMBENT " } else { "RIVAL " }); + } + } + } + println!("\ncontrol: found {incumbent} incumbent build(s) (want 2) — {}", + if incumbent == 2 { "PASSED" } else { "FAILED" }); + println!("{rivals} rival build(s) elsewhere on the disc"); +} diff --git a/docs/re/data/difficulty-is-a-dialog.txt b/docs/re/data/difficulty-is-a-dialog.txt index 83fb5e3a..e3c48a0d 100644 --- a/docs/re/data/difficulty-is-a-dialog.txt +++ b/docs/re/data/difficulty-is-a-dialog.txt @@ -64,3 +64,51 @@ # the DLG_* names live in a string list, and what maps a name to an archive entry # is not decoded. Another 4-button dialog with the same rows would be # indistinguishable by this evidence. + +################################################################################ +# ✅ DECODED 2026-08-31 (later): THE DIALOG TABLE. `DLG_SELECT_DIFFICULTY` = id 2000. +# +# Chasing the reach above -- "no binding from the DLG_ name to anything" -- found +# one. Every DLG_ string in the image is pointed at by exactly one aligned word, +# at a regular 12-byte stride. The table is: +# +# struct { u32 handler; u32 id; u32 name_ptr; } // 12 bytes, big-endian +# +# spanning 0x820A0A2C .. 0x820A0D68, three distinct handler values +# (0x821CFD80, 0x821D05D8, 0x821D0808). +# +# ✅ COMPLETE: 70 DLG_ names in the image, 70 records, ZERO names without one. +# ids are banded and monotonic, with a single gap at 24: +# 0..23 sign-in, storage, save/load/replay, GO_TITLE, GO_NEXT +# 25..43 autosave, training, weapon develop, custom keys, menu jumps +# 98, 99 DLG_MESSAGE_BOX_YES_NO, DLG_MESSAGE_BOX +# 1000 DLG_MISSION_OBJECTIVE +# 2000 **DLG_SELECT_DIFFICULTY** +# 2001..3 SYSTEM_PAUSE, LEADERBOARD_MENU_JUMP, LEADERBOARD_MENU_NEXT +# 2100..15 DLG_STAGE_TITLE01..16 +# 8000 DLG_RATING_ESRB +# 9000..2 trial dialogs +# +# Read from /image/sylpheed.pe directly -- these are the bytes the console ran, +# not a database row. +# +################################################################################ +# ✅ REFUTATION ATTEMPT ON THE SHARED REACH -- IT SURVIVES, AND IS NOW BOUNDED. +# +# Both agents recorded: "another four-button dialog with the same rows would be +# indistinguishable by this evidence". Tested by scanning EVERY build in EVERY pak +# for four buttons within 6 px of rows 259/329/399/469 +# (examples/four_button_row_rivals.rs): +# +# INCUMBENT GP_DIALOG.pak entry 2 rows [259, 329, 399, 469] +# INCUMBENT GP_DIALOG.pak entry 3 rows [259, 329, 399, 469] +# control: 2 incumbents found (want 2) -- PASSED +# RIVALS ELSEWHERE ON THE DISC: **0** +# +# So the hypothetical rival does not exist here. The geometric identification is +# UNIQUE DISC-WIDE, which is a stronger statement than the one either of us +# recorded, and it was cheap to get. +# +# ⚠️ WHAT IS STILL NOT BOUND: id 2000 -> a pak entry. The table gives name -> id +# and the disc gives a unique four-button build; nothing found so far connects the +# two. The tie is uniqueness of geometry plus the oracle capture, not a pointer.