4.0 KiB
Decoder evidence
Firmware, extracted assets, and local validation receipts remain excluded from Git.
The reference wiki is /home/jordan/pokemon-triage-wiki; it is read-only input.
Reference counts must be tied to matching content hashes, not game names alone.
Indexed DMD bitmap grammar
plugins/dmd_bitmap.py implements a bounded decoder selected by structural pointer
tables and per-record encoding bytes. media_extract.py revision 4 preserves the
encoded record, exact decoded indices, and a PNG with an explicitly approximate
palette. Palette selection and application compositing are not established by
the index decoder.
The grammar was recovered from named functions in the Game of Thrones 1.37 Pro
ARM executable, SHA-256
637acf6d6ff171def2c6e75437534ece8ea4017959eccd616829ccd621f97828:
| Address | Routine |
|---|---|
0008bb24 |
image_alloc_and_decompress_column_whitespace |
0008bc70 |
image_alloc_and_decompress_row_whitespace |
0008bd84 |
image_alloc_and_decompress_row_16 |
0008be58 |
image_get_keyframe_and_decompress_column_delta |
0008bf64 |
image_get_keyframe_and_decompress_row_delta |
These addresses document the evidence; production decoding does not hardcode them.
The dispatch table at executable file offset 0x2849a4 has four pointers per
encoding. Records contain little-endian identity, flags, width, and height followed
by an encoding byte: <IIHHB. Payload starts at byte 13. Treating byte 12 as a
pixel, as the earlier approximate extraction did, shifts raw frames.
| Encoding | Interpretation |
|---|---|
| 0 | Raw eight-bit indices |
| 1 / 7 | Column / row whitespace packets |
| 3 / 9 | Column / row deltas against a preceding cached keyframe |
| 12 | Row four-bit indices, low nibble first |
Whitespace tokens use the upper six bits as a count and the lower two bits for
literal, zero fill, index-15 fill, or repeated next-byte fill. Delta tokens below
128 copy literal indices; tokens at least 128 skip 256-token existing indices.
A zero token terminates either packet stream. Bounds, complete frame coverage,
matching keyframe dimensions, and known encoding are required. Unsupported or
truncated records produce coverage failures rather than invented pixels.
scripts/validate_dmd_native.py runs the named ARM routines under Unicorn, hooks
allocation and copying, and compares their output with the Python decoder. It
does not execute firmware as a host process. Local receipts establish:
- Pokémon image SHA-256
2f1a958c1f859c339c716e53cc9ee752412373c486ea2a1bfd116eefce4617a3: all 28 compact records match those firmware routines pixel for pixel (data/validation/dmd-real/native-receipt.json). This is a cross-build grammar check using the GOT executable, not execution of Pokémon's own decoder. - GOT image SHA-256
b52720c75d5650b61005694cc61fd941d4ab5c054166f9a4eff2c71faf454d92: all 17,159 records parse; 34 representative compressed records match the native routines, covering every compressed encoding present (got-native-receipt.json,got-summary.jsonin the same directory).
The GOT counts are 4,071 raw, 4,231 row whitespace, 2,361 column whitespace, 18 row delta, 2 column delta, and 6,476 four-bit records. These checks establish index reconstruction for the cited inputs, not full coverage of every SPIKE build.
Other family evidence
SPIKE2 audio uses the pinned upstream source and executable-specific emulation
profiles recorded in docs/toolchain.lock.json. The Aerosmith main image produced
1,522 WAVs with no failed main-image sounds in
data/validation/spike2-real/audio/spike2-audio-evidence.json. Its menu executable
has no validated codec profile and remains a visible failure.
PCM sample rates come from structural metadata or matching executable ALSA call
evidence; they must not be guessed from a game label. Godot entries retain their
source ranges and validate supplied checksums. FFmpeg previews retain inspection
and full-decode readback evidence. Intel HEX records retain address and entry-point
metadata; the pinned upstream node4-* limitation remains explicit.