Wire the validated console palette model into the decoders #260

Closed
opened 2026-07-17 11:17:26 +02:00 by jqueuniet · 0 comments
jqueuniet commented 2026-07-17 11:17:26 +02:00 (Migrated from codeberg.org)

The palette model for the console/Amiga ports is fully validated (#214, PR #259): the dungeon-viewport palette is

CRAM line 1 == conv(bank[map_graphics_style(current map)][light_stripe])

with bank = the six 96-entry records at cls = (0x08, 0x00..0x05, 0x09, 0x00), map_graphics_style = dungeon.dat per-map w14 bits 7:4, light_stripe = the engine's 6-state light level (higher = darker), and conv = the high 3 bits of each channel byte. Background: docs/formats/palette-lut.md § "The lighting-stripe hypothesis" and § "VALIDATED".

Goal: wire the model into the decoders

dm2-graphics image decoding on the ports without a 256-colour master (Sega CD US/JP, Amiga EU, FM-Towns) should resolve viewport colours from static data given a (map_graphics_style, light_level) context — e.g. a palette-selection API that returns the 16-entry stripe for a (style, light) pair, used by iter_image_with_palette/render paths and the CLI convert flow (sensible default: stripe 1, the common in-game "good light" state). Banks 1 and 5 are byte-identical in the Sega CD US archive; selection must go through the style index, not content.

For per-object ornament recolouring, the cls3 = 0x0E LUT choice is per drawn object: an id-taking boolean gate (GDAT(0x0B, 0x00, 0x0A, object_type) == 1, jump-table entry 496) followed by the pointer-taking selector cls4 = table[record->byte4 >> 4] (entry 492, 0xFF = none) on the Actuator path, and cls4 = (word2 >> 3) & 0xFF on the simplified-sensor Text path — see docs/formats/palette-lut.md § "A5 jump-table decode and the cls4 selector". Full fidelity here needs dungeon context, so a first pass can reasonably stop at the viewport palette.

Known residues (minor, non-blocking)

  • CRAM line 2 is a second dynamic palette (torch-glow layer; the yellow tint on lit torches). Unresolved against the archive (previously seen as sub-palette #13 with slots 0/12 swapped).
  • Stripe 0 was never observed live; DM2 has no day cycle (always night), so it likely maps to a brighter-than-torch state such as a light spell.
  • The -0x1aa4(a5) gate global in the policy function is unidentified.
  • Which graphics.dat record holds the entry-492 cls4 byte table (locatable statically via the archive-base A5 globals -0x264e/-0x2646/-0x2642/-0x2640(a5)).
The palette model for the console/Amiga ports is fully validated (#214, PR #259): the dungeon-viewport palette is CRAM line 1 == conv(bank[map_graphics_style(current map)][light_stripe]) with `bank` = the six 96-entry records at `cls = (0x08, 0x00..0x05, 0x09, 0x00)`, `map_graphics_style` = dungeon.dat per-map `w14` bits 7:4, `light_stripe` = the engine's 6-state light level (higher = darker), and `conv` = the high 3 bits of each channel byte. Background: `docs/formats/palette-lut.md` § "The lighting-stripe hypothesis" and § "VALIDATED". ## Goal: wire the model into the decoders `dm2-graphics` image decoding on the ports without a 256-colour master (Sega CD US/JP, Amiga EU, FM-Towns) should resolve viewport colours from static data given a `(map_graphics_style, light_level)` context — e.g. a palette-selection API that returns the 16-entry stripe for a `(style, light)` pair, used by `iter_image_with_palette`/render paths and the CLI convert flow (sensible default: stripe 1, the common in-game "good light" state). Banks 1 and 5 are byte-identical in the Sega CD US archive; selection must go through the style index, not content. For per-object ornament recolouring, the `cls3 = 0x0E` LUT choice is per drawn object: an id-taking boolean gate (`GDAT(0x0B, 0x00, 0x0A, object_type) == 1`, jump-table entry 496) followed by the pointer-taking selector `cls4 = table[record->byte4 >> 4]` (entry 492, 0xFF = none) on the Actuator path, and `cls4 = (word2 >> 3) & 0xFF` on the simplified-sensor Text path — see `docs/formats/palette-lut.md` § "A5 jump-table decode and the cls4 selector". Full fidelity here needs dungeon context, so a first pass can reasonably stop at the viewport palette. ## Known residues (minor, non-blocking) - CRAM line 2 is a second dynamic palette (torch-glow layer; the yellow tint on lit torches). Unresolved against the archive (previously seen as sub-palette #13 with slots 0/12 swapped). - Stripe 0 was never observed live; DM2 has no day cycle (always night), so it likely maps to a brighter-than-torch state such as a light spell. - The `-0x1aa4(a5)` gate global in the policy function is unidentified. - Which graphics.dat record holds the entry-492 cls4 byte table (locatable statically via the archive-base A5 globals `-0x264e/-0x2646/-0x2642/-0x2640(a5)`).
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jqueuniet/dm2-tools#260
No description provided.