46 lines
1.4 KiB
Python
46 lines
1.4 KiB
Python
import struct, zlib
|
|
IN_PATH = r"K:\ghidra\Crusader_Decomp\binary\Crusader - No Remorse Memdump Weapons.bin"
|
|
OUT_PATH = r"K:\ghidra\Crusader_Decomp\binary\vram_weapons.png"
|
|
W, H = 1024, 512
|
|
with open(IN_PATH, 'rb') as f:
|
|
data = f.read()
|
|
exp = W * H * 2
|
|
if len(data) < exp:
|
|
print(f"Warning: expected {exp} bytes, got {len(data)} bytes")
|
|
count = min(len(data) // 2, W * H)
|
|
# build raw RGB rows top-to-bottom
|
|
rows = []
|
|
for y in range(H):
|
|
row = bytearray()
|
|
for x in range(W):
|
|
i = y * W + x
|
|
if i < count:
|
|
off = i * 2
|
|
val = data[off] | (data[off+1] << 8)
|
|
b = (val & 0x1F) << 3
|
|
g = ((val >> 5) & 0x1F) << 3
|
|
r = ((val >> 10) & 0x1F) << 3
|
|
else:
|
|
r = g = b = 0
|
|
row.extend([r, g, b])
|
|
rows.append(b"\x00" + bytes(row))
|
|
raw = b"".join(rows)
|
|
comp = zlib.compress(raw, level=9)
|
|
# PNG helpers
|
|
def chunk(ch_type, data):
|
|
out = struct.pack('>I', len(data)) + ch_type + data
|
|
import zlib
|
|
crc = zlib.crc32(ch_type + data) & 0xffffffff
|
|
out += struct.pack('>I', crc)
|
|
return out
|
|
png = b"\x89PNG\r\n\x1a\n"
|
|
# IHDR
|
|
ihdr = struct.pack('>IIBBBBB', W, H, 8, 2, 0, 0, 0) # 8-bit, truecolor, no interlace
|
|
png += chunk(b'IHDR', ihdr)
|
|
# IDAT
|
|
png += chunk(b'IDAT', comp)
|
|
# IEND
|
|
png += chunk(b'IEND', b'')
|
|
with open(OUT_PATH, 'wb') as f:
|
|
f.write(png)
|
|
print('Wrote', OUT_PATH, 'size=', len(png))
|