60 lines
1.8 KiB
Python
60 lines
1.8 KiB
Python
|
|
import struct, os
|
||
|
|
IN_PATH = r"K:\ghidra\Crusader_Decomp\binary\Crusader - No Remorse Memdump Weapons.bin"
|
||
|
|
OUT_PATH = r"K:\ghidra\Crusader_Decomp\binary\vram_weapons.bmp"
|
||
|
|
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")
|
||
|
|
# read pixels (little-endian 16bpp)
|
||
|
|
count = min(len(data) // 2, W * H)
|
||
|
|
pixels = [None] * (W * H)
|
||
|
|
for i in range(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
|
||
|
|
pixels[i] = (r, g, b)
|
||
|
|
# fill remaining if any
|
||
|
|
for i in range(count, W*H):
|
||
|
|
pixels[i] = (0,0,0)
|
||
|
|
# BMP row padding
|
||
|
|
row_bytes_unpadded = 3 * W
|
||
|
|
row_size = (row_bytes_unpadded + 3) // 4 * 4
|
||
|
|
pixel_data = bytearray()
|
||
|
|
for y in range(H-1, -1, -1):
|
||
|
|
row_start = y * W
|
||
|
|
for x in range(W):
|
||
|
|
r,g,b = pixels[row_start + x]
|
||
|
|
pixel_data.extend(bytes((b, g, r)))
|
||
|
|
pad = row_size - row_bytes_unpadded
|
||
|
|
if pad:
|
||
|
|
pixel_data.extend(b"\x00" * pad)
|
||
|
|
# headers
|
||
|
|
bfType = b'BM'
|
||
|
|
bfSize = 14 + 40 + len(pixel_data)
|
||
|
|
bfReserved1 = 0
|
||
|
|
bfReserved2 = 0
|
||
|
|
bfOffBits = 14 + 40
|
||
|
|
bmp = bytearray()
|
||
|
|
bmp.extend(bfType)
|
||
|
|
bmp.extend(struct.pack('<IHHI', bfSize, bfReserved1, bfReserved2, bfOffBits))
|
||
|
|
# DIB header (BITMAPINFOHEADER)
|
||
|
|
biSize = 40
|
||
|
|
biWidth = W
|
||
|
|
biHeight = H
|
||
|
|
biPlanes = 1
|
||
|
|
biBitCount = 24
|
||
|
|
biCompression = 0
|
||
|
|
biSizeImage = len(pixel_data)
|
||
|
|
biXPelsPerMeter = 2835
|
||
|
|
biYPelsPerMeter = 2835
|
||
|
|
biClrUsed = 0
|
||
|
|
biClrImportant = 0
|
||
|
|
bmp.extend(struct.pack('<IIIHHIIIIII', biSize, biWidth, biHeight, biPlanes, biBitCount, biCompression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUsed, biClrImportant))
|
||
|
|
bmp.extend(pixel_data)
|
||
|
|
with open(OUT_PATH, 'wb') as f:
|
||
|
|
f.write(bmp)
|
||
|
|
print('Wrote', OUT_PATH, 'bytes=', len(bmp))
|