dm2-saves: retail skull.exe CREATURE_GIDX_ALT_TABLE applied unconditionally to Mac and Beta saves #174
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
CREATURE_GIDX_ALT_TABLE(records.rs~87) is documented as extracted from the retail DOSskull.exebinary, and its own comment notes the Mac build would need its own table. Yetcompute_creature_alt_species_mask— which consults it to choose between the 66-bit DEFAULT and 50-bit ALT creature masks — is applied unconditionally to every variant (sksave.rsdecode_full ~927 and to_bytes_from_fields ~1142), including Mac retail and DOS Beta v0.9 (Fires.exeis not covered at all).Impact
Any creature species whose descriptor bit0 differs between the retail
skull.exetable and the Mac/Beta engine binaries selects the wrong per-record mask width → full bitstream desync from that record onward on the affected platform. Currently a risk flag rather than a proven divergence (the Mac/Beta tables have not been compared), but the exposure is the same class as the mask-table differences already found between platforms (champion mask, Beta object masks).Fix direction
Extract the equivalent table from the Mac 68k
DATA_0000resource (same methodology asMAC_CHAMPION_MASK) and from the unpacked BetaFires.exe, compare against the retail table, and dispatch per variant if they differ (or document byte-identity if they do not).Investigated in #209; documented, not code-changed (kept open as a follow-up).
DOS/USA/skull.exeat file offset0x72568(36-byte stride,word[0] & 1, 64 entries, LSB-first) reproducesCREATURE_GIDX_ALT_TABLEbyte-for-byte.DOS/BETA/Fires.exeis a packed executable (the descriptor table is not a contiguous block in the on-disk image — cf. the FTL/hunk decoder effort), and the Mac 68k build keeps its descriptors in the resource fork in big-endian layout with an unverified stride.decode_fulland re-encode byte-for-byte with the retail table applied, so no observed creature diverges; re-selecting per variant without the extracted tables would be a guess that could regress those passing fixtures.The status is now documented precisely on the constant (commit
dca12e2c). Dispatch per variant once the Mac/Beta tables are extracted and shown to differ.Investigation result: byte-identity proven — no per-variant dispatch needed
Extracted the equivalent tables from both the Mac 68k binary and the unpacked Beta
Fires.exeand compared against retail. Both match; this resolves as the "document byte-identity" outcome.DOS retail (baseline)
Re-deriving from
DOS/USA/skull.exe@0x72568(36-byte stride,word[0] & 1, 64 entries, LSB-first) reproducesCREATURE_GIDX_ALT_TABLE = [ff 1f 10 00 e0 20 08 99]byte-for-byte.Mac retail: identical (all 64 entries)
READ_RECORD_CHECKCODE(CODE_00160x1330) reads the 7-bit species, calls jump-table entryA5+0x842→ CODE_00150x49ce, which maps species → gidx via the same GDATfind(0x0f, …, 0x0b, 0x05)(plus0x04fallback) and indexes a descriptor table atA5-0x3982withmulu.w #0x24— same 36-byte stride — testingword[0]bit0.DATA_0000is a word stream in which each0x0000word appends a zero run sized by the parallelZERO_0000resource (decompressor: CODE_00010x6e);DREL_0000holds A5 relocations. Reconstruction consumes both resources exactly to the0x681e-byte below-A5 size, and validates on three anchors (MAC_CHAMPION_MASK@A5-0x9d6, SGB mask @A5-0xa0e, BE-swapped ALT creature mask @A5-0x89e).word[0]values equal the retail LE values, and noDREL_0000relocation lands inside the table → identical bit0 table.DOS Beta v0.9: identical over its real table (56 entries)
scripts/unlzexe.pyunpacksFires.exe(278,128 B load module); the descriptor table is at unpacked offset0x4332e, same 36-byte layout.0xffffterminator sits at entry 56 (retail's at entry 63), and the bytes past it match retail's post-table data.bit0is identical to retail over entries 0–55.Consistent with all this, the Mac and Beta fixtures already round-trip byte-for-byte with the retail table applied.
Resolution
Updated the
records.rsper-variant status comment to record the proven identity and the extraction recipes. Side note:docs/formats/mac-post-sgb-reads.mdquotes the DOS SGB mask bytes for the0x4640byte-search — the Mac bytes are u16-swapped and the mask sits atA5-0xa0ein the reconstructed image.