re: partial field map inside the live definition object, and why the automation failed
Anchoring on a unit whose disc record sets a field locates it in the live object: Size_X/Y/Z (+0x30/34/38) and HP (+0x54) confirmed across five capital ships and the player fighter; +0x74 (0.8) and +0x84 (0.97) are probable ThrusterRatio and ResistanceParalyze but rest on a single anchoring unit; +0x40 varies per unit and is unidentified. live_offsets.rs automates the correlation and currently produces one hit which is false -- YawDragFactor 2.0 collided with the integer 2 at +0x0c stored as a denormal. Causes recorded: get_f32 is unreliable on default-heavy IDXD records because the value-before-key pairing shifts, and 96 words only reaches +0x180 while RadarRange/FCSRange sit beyond it. Next run dumps 512 words. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
31
crates/sylpheed-formats/examples/unit_fields.rs
Normal file
31
crates/sylpheed-formats/examples/unit_fields.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
//! Every key/value a named unit record actually sets on disc.
|
||||
//!
|
||||
//! The live definition object in guest RAM has no field names; to find where a
|
||||
//! field like `HQRatio` sits inside it, anchor on a unit whose disc record DOES
|
||||
//! set that field and look for the value. This prints those anchors.
|
||||
//! Run: unit_fields <disc-root> <substring of ID>...
|
||||
use sylpheed_formats::idxd::IdxdObject;
|
||||
use sylpheed_formats::pak::PakArchive;
|
||||
|
||||
fn main() {
|
||||
let disc = std::env::args().nth(1).expect("disc root");
|
||||
let want: Vec<String> = std::env::args().skip(2).collect();
|
||||
let pak = PakArchive::open(format!("{disc}/dat/GP_MAIN_GAME_E.pak")).expect("pak");
|
||||
for entry in pak.entries() {
|
||||
let Ok(bytes) = pak.read(entry) else { continue };
|
||||
let Ok(obj) = IdxdObject::parse(&bytes) else { continue };
|
||||
let Some(id) = obj.get_raw("ID") else { continue };
|
||||
if !want.iter().any(|w| id.contains(w.as_str())) {
|
||||
continue;
|
||||
}
|
||||
println!("=== {id} (schema {:08x})", obj.schema_hash);
|
||||
// The pool interleaves VALUE before KEY (see the module docs), so the
|
||||
// pairs read (t[i] = value, t[i+1] = key).
|
||||
let t = obj.tokens();
|
||||
let mut i = 0;
|
||||
while i + 1 < t.len() {
|
||||
println!(" {:<30} {}", t[i + 1], t[i]);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user