"""Check actual native Russian-roulette party frames and shipping code parity.""" import argparse import hashlib from pathlib import Path from PIL import Image, ImageDraw, ImageStat from check_card_exit_build import Coff ROOT = Path(__file__).resolve().parents[2] def frames(): names = ["ready", "turn", "out", "win", "exit"] sheet = Image.new("RGB", (1280, 3 * 504), (20, 25, 29)) draw = ImageDraw.Draw(sheet) signatures = [] for i, name in enumerate(names): path = ROOT / "build/actions" / f"rr-party-{name}.bmp" image = Image.open(path).convert("RGB") assert image.size == (640, 480) assert len(image.getcolors(640 * 480)) > 1000, name assert sum(ImageStat.Stat(image.crop((0, 400, 640, 480))).stddev) > 5, name signatures.append(hashlib.sha256(image.tobytes()).digest()) image.save(path.with_suffix(".png")) x, y = (i % 2) * 640, (i // 2) * 504 sheet.paste(image, (x, y + 24)) draw.text((x + 8, y + 6), f"Native Russian party: {name}", fill="white") assert len(set(signatures)) == len(names) sheet.save(ROOT / "build/actions/rr-party-contact.png") print("PASS: five distinct native party frames: setup, active seat, elimination, win and exit dialog") def parity(): tested = Coff(ROOT / "build/actions/actions-test.obj") shipping = Coff(ROOT / "build/graphics/poker.obj") procedures = (("RRPartyInit3D", 0), ("RRPartyReset3D", 0), ("RRPartySetCount3D", 4), ("RRPartyInput3D", 0), ("RRLoadCylinder3D", 0), ("RRPartyHit3D", 0), ("RRPartyNext3D", 0), ("RRPartyWin3D", 0), ("RRPartyLose3D", 0), ("AbortRussianRound3D", 0), ("RenderRRPartyCharacters3D", 0), ("RenderRRPartyGun3D", 0), ("RenderRRPartyControls3D", 0), ("RenderRussianExit3D", 0), ("StartRussianRound3D", 0), ("AdvanceRussianScene3D", 0), ("HandleRussianInput3D", 0), ("RenderRussianGame3D", 0), ("RenderRussianTable3D", 0)) for name, size in procedures: symbol = f"_{name}@{size}" assert tested.signature(symbol) == shipping.signature(symbol), name print("PASS: shipping party turns, payouts, reloading, animation and exit match native-tested MASM") if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--parity", action="store_true") args = parser.parse_args() frames() if args.parity: parity()