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
+5 -1
View File
@@ -228,7 +228,11 @@ Phase 1 hands over the extents; this phase works out what each one contains.
with the WAD LZ77 decoder, bit order and header length ruled out" note
was wrong about the cause: the decoder was right and the input was not
what it looked like. Corrected in `plan/level-assets.md`.
- [~] `sound_bank` — container framing parsed (`SoundBankHeader::parse`,
- [~] `sound_bank` — the `SBlk` head is now characterised: `"SBlk", 1, 4,
"DAW\0", 0` constant on 27/27, and `+0x14` is the only varying word, with
its low 16 bits always zero (`0x0092..=0x0103`). It tracks body length at
~100 bytes/unit and is **not** a count -- ratio 91.2..110.8, and no stride
makes it exact. The absence of a stride is asserted too. Container framing parsed (`SoundBankHeader::parse`,
`parse_sound_bank`); `SBlk` and `DAW` bounds verified on 27/27. The
**record fields inside `SBlk` are not decoded**, and `DAW` shows no
detectable stride, consistent with ADPCM. See the note under