RECORDANDRONCO/tools/gen_placeholders.py

78 lines
2.6 KiB
Python

#!/usr/bin/env python3
"""Generate placeholder sprite PNGs for Phase A (stdlib only).
OpenRA PngSheet slices multi-frame sheets via an embedded tEXt chunk
"FrameSize: w,h" (see engine PngSheetLoader.cs). Real art replaces these in
Phase D — keep the filenames.
"""
import os, struct, zlib
OUT = os.path.join(os.path.dirname(__file__), '..', 'mods', 'vinylgod', 'sequences', 'assets')
PINK = (255, 45, 150, 255)
DARK = (30, 26, 32, 255)
GREY = (90, 85, 95, 255)
CLEAR = (0, 0, 0, 0)
def chunk(tag, data):
return struct.pack('>I', len(data)) + tag + data + struct.pack('>I', zlib.crc32(tag + data))
def write_png(path, w, h, px, text=None):
raw = b''.join(b'\x00' + b''.join(bytes(px[y * w + x]) for x in range(w)) for y in range(h))
out = b'\x89PNG\r\n\x1a\n' + chunk(b'IHDR', struct.pack('>IIBBBBB', w, h, 8, 6, 0, 0, 0))
for k, v in (text or {}).items():
out += chunk(b'tEXt', k.encode() + b'\x00' + v.encode())
out += chunk(b'IDAT', zlib.compress(raw)) + chunk(b'IEND', b'')
open(path, 'wb').write(out)
print(f'wrote {path} {w}x{h}')
def canvas(w, h, fill=CLEAR):
return [fill] * (w * h)
def rect(px, w, x0, y0, x1, y1, c):
for y in range(y0, y1):
for x in range(x0, x1):
px[y * w + x] = c
def disc(px, w, cx, cy, r, c):
for y in range(int(cy - r), int(cy + r) + 1):
for x in range(int(cx - r), int(cx + r) + 1):
if (x - cx) ** 2 + (y - cy) ** 2 <= r * r:
px[y * w + x] = c
def box_sprite(path, size, body, accent):
px = canvas(size, size)
m = size // 8
rect(px, size, m, m, size - m, size - m, body)
rect(px, size, m, m, size - m, m + 2, accent) # top trim
disc(px, size, size / 2, size / 2, size // 5, accent) # centre disc
write_png(path, size, size, px)
os.makedirs(OUT, exist_ok=True)
# wax: 12 density frames, 32x32, horizontal strip
W, H, N = 32, 32, 12
px = canvas(W * N, H)
blob = [(9, 9), (22, 12), (14, 21), (24, 24), (7, 24), (17, 7), (26, 17), (11, 15),
(20, 19), (15, 27), (5, 16), (27, 8)]
for f in range(N):
for i in range(f + 1):
cx, cy = blob[i]
for dx in range(W): # draw into frame f's slice
pass
gx = f * W + cx
disc(px, W * N, gx, cy, 3, PINK if i % 3 == 0 else DARK)
write_png(os.path.join(OUT, 'wax.png'), W * N, H, px, text={'FrameSize': '32,32'})
box_sprite(os.path.join(OUT, 'digger.png'), 24, PINK, DARK)
box_sprite(os.path.join(OUT, 'pressplant.png'), 64, DARK, PINK)
box_sprite(os.path.join(OUT, 'ampstack.png'), 32, GREY, PINK)
box_sprite(os.path.join(OUT, 'vault.png'), 32, DARK, GREY)