Files
TeslaRel410/emulator/firmware-decomp/emu860c/texstore.py
T
CydandClaude Opus 4.8 cc2d9290be M3 texel decode: the game's own textures recovered from the wire
Action 0x1a carries the textures: header[32] {handle, byte_size, u, v, mode}
+ v rows of 256 bytes, texels in 0x00BBGGRR words. The netdeath session's 20
textures decode to real game art -- 'PLAYER 1/5' HUD labels, a squadron
dragon emblem, metal-panel/grating/terrain surfaces, and the pilot callsign
'Cyd' (texsheet.png in the session scratchpad). The M3 texel FORMAT is
solved; texstore.py builds the handle->RGB store. Remaining: per-quad texid
binding + (texu,texv) sampling to skin the geometry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 16:18:39 -05:00

31 lines
1.2 KiB
Python

"""M3 texel store: parse the game wire's action-0x1a texture uploads into a
handle -> (u_size, v_size, mode, RGB array) dict. Format: header[32] =
{handle, byte_size, u, v, mode, ...}, then v rows of 256 bytes, texels in
0x00BBGGRR little-endian words (bytes R,G,B,0). Verified: decodes to the real
game textures (HUD 'PLAYER n' labels, squadron emblem, panel/terrain art)."""
import struct
import numpy as np
def build_texstore(recs):
store = {}
i = 0
while i < len(recs):
a, p = recs[i]
if a == 0x1a and len(p) == 32:
h = [struct.unpack_from('<I', p, 4 * k)[0] for k in range(8)]
handle, u, v, mode = h[0], h[2], h[3], h[4]
rb = b''
j = i + 1
while j < len(recs) and recs[j][0] == 0x1a and len(recs[j][1]) == 256:
rb += bytes(recs[j][1]); j += 1
n = u * v
if n and len(rb) >= n * 4:
arr = np.frombuffer(rb[:n * 4], dtype=np.uint8).reshape(v, u, 4)
# v-flip (rows arrive bottom-up: 'PLAYER' reads mirrored otherwise)
store[handle] = (u, v, mode, arr[::-1, :, :3].copy())
i = j
else:
i += 1
return store