D228: fix white NPC-weapon-texture patches -- IA16 palette intensity/alpha byte-order bug

GE_TEXDUMP on Facility (-level_34) found ~14% of LOD-textured CI uploads
whose palette is IA16 (intensity-alpha, not RGBA16) rendering solid
near-white. A GE_D228 correlation probe ruled out the texpool/RC2-clip
hypothesis this row started with -- decoded size exactly matched the base
tile every time, so the data reaches import_texture fine.

The real bug: palette_to_rgba32's G_TT_IA16 branch read
intensity = palentry & 0xff (low byte), alpha = palentry >> 8 (high byte)
-- backwards relative to the already-correct direct-IA16 decode
(import_texture_ia16) a few lines above it in the same file, which reads
intensity from the first byte (high, after gfx_dp_load_tlut's PD_BE16
swap) and alpha from the second. A dim, fully-opaque palette entry (e.g.
intensity=0x58, alpha=0xff) decoded backwards as bright and
mostly-transparent -- the white-patch symptom.

Fix: swap the two lines to match the working convention.

User-verified live: AK47 and other metallic guns render correctly.
Headless -level_34 run crash-free pre-verification; a full sweep is
still owed (the user's own game instance was running concurrently this
session, so verify.sh/taskkill were avoided).

Claude-Session: https://claude.ai/code/session_016DQUKGLZxFtPy52MkKXXog
This commit is contained in:
James Dansereau committed 2026-09-12 21:20:51 -04:00
1 parent 53c9a879f3
commit dac4ae7c0c
4 files changed
+29 -5

No files matched your search

+17 -1
View File
@@ -1144,4 +1144,20 @@ and turns every such overrun into a fatal `*** stack smashing detected ***`
hardware supports and GE's own assets exercise is not "PD-only" just
because the first investigation happened to hit it on a draw that
shouldn't have taken that path. §F **D195**.
§F **D247**.
- **D228 — when two decode paths exist for the same underlying format,
check them against each other for a swapped byte order, not just against
the spec.** `palette_to_rgba32`'s `G_TT_IA16` branch (CI texture whose
palette is intensity-alpha, not RGBA16) read `intensity = palentry & 0xff`,
`alpha = palentry >> 8` — exactly backwards relative to the *already
correct* direct-IA16 decode (`import_texture_ia16`) a few lines above it
in the same file, which reads `intensity = addr[2*i]` (first/high byte),
`alpha = addr[2*i+1]` (second/low byte), matching what `gfx_dp_load_tlut`'s
`PD_BE16` byte-swap actually produces. A dim, fully-opaque texel (e.g.
intensity=0x58, alpha=0xff) decoded backwards as bright and
mostly-transparent — read as "white missing-texture patches" (AK47 and
other metallic weapon materials, whose grayscale-metal-plus-opacity look
is a natural fit for IA16 palettes). Two importers for the same source
format existing side by side in one file is exactly the situation where
one silently drifts from the other; when investigating a decode bug, diff
the suspect path against its sibling path for the same format before
re-deriving the bit layout from scratch. §F **D228**.