#!/usr/bin/env python3 """Frame -> flat (RGB888 palette + index plane) blob for the MAME Lua loader. Packing into the X68000 palette word is done Lua-side on purpose: the exact channel order is a hardware fact we intend to CONFIRM BY EYE, not assume, so it has to be cheap to change without regenerating the blob. """ import sys, struct, glob import numpy as np from PIL import Image src, out = sys.argv[1], sys.argv[2] f = sorted(glob.glob(f"{src}/*.png"))[int(sys.argv[3]) if len(sys.argv) > 3 else 0] im = Image.open(f).convert("RGB") W, H = im.size q = im.quantize(colors=256, method=Image.MEDIANCUT, dither=Image.NONE) pal = np.array(q.getpalette()[:256*3], dtype=np.uint8).reshape(256, 3) idx = np.asarray(q, dtype=np.uint8) with open(out, "wb") as fh: fh.write(b"DLXR") fh.write(struct.pack(">HH", W, H)) fh.write(pal.tobytes()) fh.write(idx.tobytes()) # reference PNG of exactly what the X68000 should display Image.fromarray(pal[idx]).save(out.replace(".bin", "_ref.png")) print(f"src={f} {W}x{H} colors={len(np.unique(idx))} -> {out}")