# # PER-HEAD A/B scoreboard for the packed gauge framebuffer. # # L4GAUGE.CFG configures ten logical ports onto ONE 640x480x16 buffer, each # port owning a BIT MASK, not a rectangle -- the VDB later splits the planes # into the pod's separate physical heads. Comparing RGB is therefore # meaningless; the only useful question is "which HEAD differs, and where". # # DOSBox presents the buffer as RGB565 with bit replication, so the original # 16-bit word is recovered exactly by R>>3, G>>2, B>>3. # import sys from PIL import Image BOX = (8, 52, 648, 531) PORTS = [ ("sec", 0x003F), # the 3-D scene (6-bit colour) ("overlay", 0x00C0), ("Mfd1", 0x0100), ("Eng1", 0x0200), ("Mfd2", 0x0400), ("Eng2", 0x0800), ("Mfd3", 0x1000), ("Eng3", 0x2000), ("Heat", 0x4000), ("Comm", 0x8000), ] def words(path): im = Image.open(path).convert("RGB").crop(BOX) w, h = im.size px = im.load() out = [] for y in range(h): row = [] for x in range(w): r, g, b = px[x, y] row.append(((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)) out.append(row) return out, w, h def main(ship_path, ours_path): A, w, h = words(ship_path) B, w2, h2 = words(ours_path) if (w, h) != (w2, h2): print("SIZE MISMATCH") return print("%-8s %8s %8s %8s %8s %s" % ("head", "shipped", "ours", "missing", "extra", "extra-bbox")) for name, mask in PORTS: sa = so = both = 0 xs = [] ys = [] for y in range(h): ra, rb = A[y], B[y] for x in range(w): a = (ra[x] & mask) != 0 b = (rb[x] & mask) != 0 if a: sa += 1 if b: so += 1 if a and b: both += 1 if b and not a: xs.append(x) ys.append(y) bbox = ("(%d,%d)-(%d,%d)" % (min(xs), min(ys), max(xs), max(ys)) if xs else "-") print("%-8s %8d %8d %8d %8d %s" % (name, sa, so, sa - both, so - both, bbox)) main(sys.argv[1], sys.argv[2])