SBlk head characterised: four constants and one word that is not a count

sound_bank's head was parsed but never characterised. Across all 27 levels the
SBlk region opens identically for its first twelve bytes:

    +0x00 "SBlk"   +0x04 1   +0x08 4   +0x0c "DAW\0"   +0x10 0

and +0x14 is the only word that varies. It varies with its low sixteen bits zero
on all 27, leaving 0x0092..0x0103 -- 146 to 259.

That is the shape of a record count, and it tracks the body length at close to
100 bytes per unit. It is not one:

    body / field_14     91.2 .. 110.8 across 27 levels
    any stride 0..80 with body = stride*word + constant exactly:  no

So the test asserts the negative too. If a stride ever makes the relation exact
on all 27, sound_bank_sblk_head_is_constant_apart_from_one_word fails and asks
for the record size to be revisited. A near-miss at 100 bytes/record is exactly
what hardens into a name the next time somebody glances at it; the constants are
also checked individually so a real deviation names which one moved.

The DAW region begins with sixteen zero bytes then block-structured data with
16-byte periodicity and slowly varying nibbles -- consistent with block
compressed audio, not decoded. Recorded as such.

Two mistakes, both mine, both the same shape as earlier ones:

1. The constructor bound `format_tag` with a `let` BEFORE the two words that
   precede it in the file, consuming bytes 4..8 and shifting every field after
   it. The struct literal listed the names in the right order; the statements did
   not. A scratch script reading the same bytes gave the opposite answer, which
   is what exposed it. Fixed, with a comment, because "read the lets in file
   order" gets undone otherwise.

2. Inserting the new test ahead of an existing one stranded that test's #[test]
   on my doc comment -- silently unregistering
   tie_vertex_element_is_16_bytes_with_fixed_texcoords. This is the SAME mistake
   as two commits ago and I made it again. It again surfaced only as clippy's
   "never used" rather than as a missing test. Restored and verified by listing
   the registered tests rather than trusting the count.

240 tests, clippy clean, both tie vertex tests confirmed present.
This commit is contained in:
2026-10-13 07:29:07 +02:00
parent bc5ebe559f
commit 28ab7e094b
4 changed files with 195 additions and 1 deletions
+42
View File
@@ -2142,3 +2142,45 @@ field means anything. The test's power came from `i16[0..2]` being the only slot
with tens of thousands of distinct values. **A passing result from a method that
has run out of discriminative power is not a passing result**, and the 1x rows are
recorded so the table is not later mistaken for nine confirmations.
## The `SBlk` head: four constants, one unidentified word
The sound extent's 24-byte head was parsed but not characterised. Across all 27
levels the `SBlk` region opens identically for its first twelve bytes:
+0x00 "SBlk"
+0x04 1
+0x08 4
+0x0c "DAW\0"
+0x10 0
+0x14 varies
`+0x14` is the only part that differs between levels, and it differs with its
**low sixteen bits zero on all 27**, leaving `0x0092..=0x0103` -- 146 to 259.
That is the shape of a record count, and it tracks the `SBlk` body length at
close to 100 bytes per unit. It is not one:
body / field_14 91.2 .. 110.8 across the 27 levels
any stride 0..80 making body = stride * word + constant exactly: no
A near-miss at 100 bytes/record is exactly the kind of thing that hardens into a
name the next time somebody glances at it, so the test asserts the negative
alongside the positive: if a stride ever makes the relation exact on all 27, the
test fails and asks for the record size to be revisited.
Asserted in `sound_bank_sblk_head_is_constant_apart_from_one_word`, which checks
the four constants individually so a real deviation names which moved, the zero
low half, the value range, and the absence of a fixed stride.
The `DAW` region begins with sixteen zero bytes and then block-structured data
with 16-byte periodicity and slowly varying nibbles, consistent with block
compressed audio. It is not decoded.
Two notes on how this was measured. Reading the level 0 head directly from a
scratch script gave a field order that the parser disagreed with, because the
constructor bound `format_tag` with a `let` *before* the two words that precede
it in the file -- consuming bytes 4..8 and shifting everything after. The struct
literal named the fields in the right order; the statements did not. It is fixed
with a comment saying so, since "read the `let`s in file order" is the kind of
thing that gets undone.