#!/usr/bin/env python3 """Check px68k's render of the packed layout against the same reference MAME is judged on (tools/bench/verify_frame256.py, criterion 3 and 4). python3 tools/bench/gvpack/verify_gvpack.py [blob] is 256x256 palette INDICES straight out of px68k's Grp_DrawLine8. """ import struct, sys import numpy as np raw = sys.argv[1] if len(sys.argv) > 1 else "tmp/gvpack_px68k.raw" blob = sys.argv[2] if len(sys.argv) > 2 else "tmp/frame256p.bin" g = np.frombuffer(open(raw, "rb").read(), np.uint8).reshape(256, 256) d = open(blob, "rb").read() W, H = struct.unpack(">HH", d[4:8]) pal = np.frombuffer(d[8:8+768], np.uint8).reshape(256, 3).astype(int) idx = np.frombuffer(d[8+768:8+768+W*H], np.uint8).reshape(H, W) yoff = (256 - H) // 2 act = g[yoff:yoff+H] fail = [] if not np.array_equal(act, idx): bad = act != idx fail.append(f"active area index-exact: {bad.sum()} px differ " f"(left half {bad[:, :128].sum()}, right half {bad[:, 128:].sum()})") bars = np.concatenate([g[:yoff], g[yoff+H:]]) if bars.size and (bars != 255).any(): fail.append(f"letterbox not the reserved black index 255: " f"{(bars != 255).sum()} px") if (act == 0).any(): fail.append(f"index 0 appeared in the picture: {(act == 0).sum()} px " f"-- it is the transparency key and must stay unused") for x in fail: print("FAIL " + x) if fail: sys.exit(1) p6 = lambda v: ((v << 2) | (v >> 4)) & 0xFF f = pal >> 3 render = lambda I: p6((f << 1) | I[:, None]) I = (((render(np.ones(256, int)) - pal) ** 2).sum(1) < ((render(np.zeros(256, int)) - pal) ** 2).sum(1)).astype(int) mse = ((render(I)[act].astype(int) - pal[idx]) ** 2).mean() print(f"OK {raw}: px68k renders the packed layout index-exact over {W}x{H}, " f"letterbox on the reserved black") print(f" palette ceiling vs 24-bit palettised source: " f"{10*np.log10(255**2/mse):.2f} dB")