Identify the tie record as RAC1's TiePacketHeader, and retract a formula
The 16-byte tie record is R&C1's TiePacketHeader offset for offset: a data pointer at +0, then R&C1's byte fields at +4 through +0x10. The identification is not a resemblance but R&C1's own rule -- bfc_distance == 5 * shader_count -- holding on all 15,219 records of all 2,177 blocks on all 27 levels. Measured over the same set, and reported rather than asserted where it is not universal: bfc_distance == 5 * shader_count 15219 / 15219 vert_ofs <= vert_size all scissor_size <= scissor_ofs all control_size <= control_count all color_ofs == vert_size 12640 / 15219 color_ofs == vert_ofs + vert_size 0 / 15219 color_count, strip_count, strip_vertex_count zero 15089 / 15077 / 15078 R&C1's rule for the colour offset holding on none of them is the interesting line: the two games use that field differently, so it is named color_ofs for what this game's majority reads as and the 2,579 exceptions are counted rather than averaged away. TieRecord parses all twelve fields, invariants_hold asserts only the universal four, and the disc test counts the rest. A packet-length formula is withdrawn rather than softened. (vert_ofs + vert_size + scissor_ofs + scissor_size) * 16 was measured at 61 of 61 pairs and is not reproduced on the correct blocks -- 0 of 13,042. The block set was the error, not the arithmetic: the script that produced the 61 read packets[2] where packets[1] was meant, so it measured 461 blocks instead of the 2,177 the class tables define, and the formula agreed perfectly with a population that was not the tie blocks. TieRecord::packet_bytes goes with it, and the retraction is recorded in the format doc and in the struct. That misread also explains why the earlier RAM verification saw different numbers for the two inputs -- same lesson as rule 3, arriving through a wrong subscript instead of a wrong span.
This commit is contained in:
@@ -100,7 +100,7 @@ pub fn verify(
|
||||
// enough to find: a run of one repeated byte occurs all over RAM.
|
||||
let probe = records
|
||||
.iter()
|
||||
.map(|r| r.fields)
|
||||
.map(|r| r.trailing_bytes())
|
||||
.find(|f| f.iter().collect::<std::collections::HashSet<_>>().len() >= 4)
|
||||
.ok_or_else(|| anyhow!("no record has a distinctive field run"))?;
|
||||
|
||||
@@ -123,7 +123,7 @@ pub fn verify(
|
||||
let ok_fields = records
|
||||
.iter()
|
||||
.enumerate()
|
||||
.all(|(k, r)| ram.slice(base + k * 16 + 4, 12) == Some(&r.fields[..]));
|
||||
.all(|(k, r)| ram.slice(base + k * 16 + 4, 12) == Some(&r.trailing_bytes()[..]));
|
||||
if ok_ptr && ok_fields {
|
||||
table_ram = Some(base);
|
||||
relocated = records.len();
|
||||
|
||||
Reference in New Issue
Block a user