"""Compile and verify real MASM startup pages and the post-admission briefing.""" import argparse import hashlib from pathlib import Path import subprocess import sys from PIL import Image, ImageChops, ImageDraw from check_artifacts import toolchain ROOT = Path(__file__).resolve().parents[2] OUT = ROOT/'build/scratch' sys.path.insert(0,str(ROOT/'tools/generators')) from make_presentation_text import TEXT def snapshot_runtime(): return {p:hashlib.sha256(p.read_bytes()).digest() for p in (ROOT/'runtime').rglob('*') if p.is_file()} def main(): parser = argparse.ArgumentParser() parser.add_argument('--window',action='store_true') args = parser.parse_args() OUT.mkdir(parents=True,exist_ok=True) # Prevent silent clipping of the Russian copy or a missing font character. for name,text in TEXT.items(): assert all(len(line)<=39 for line in text.splitlines()),name assert b'\x97' not in text.encode('cp1251'),name before = snapshot_runtime() ml,link = toolchain() sdk = Path('C:/Program Files (x86)/Windows Kits/10/Lib') lib = next(p/'um/x86' for p in sorted(sdk.iterdir(),reverse=True) if (p/'um/x86/kernel32.lib').exists()) commands = [[ml,'/c','/coff','/Cp','/nologo','/I.','/DPRESENTATION_TEST=1', '/Fobuild/scratch/presentation-test.obj','poker.asm'], [link,'/nologo','/SUBSYSTEM:CONSOLE','/LIBPATH:'+str(lib), '/OUT:build/scratch/presentation-test.exe','build/scratch/presentation-test.obj', 'kernel32.lib','winmm.lib','user32.lib','ws2_32.lib','gdi32.lib']] if args.window: commands[0].insert(1,'/DPRESENTATION_WINDOW_TEST=1') try: for command in commands: subprocess.run(list(map(str,command)),cwd=ROOT,check=True,timeout=120) result = subprocess.run([str(OUT/'presentation-test.exe')],cwd=ROOT,timeout=120) assert result.returncode == 0,f'Native presentation check failed: {result.returncode:#x}' finally: assert before == snapshot_runtime(),'Test changed player saves' frames=[] for index in range(12): raw = (OUT/f'presentation-{index:02}.bgra').read_bytes() assert len(raw)==640*480*4 image=Image.frombytes('RGBA',(640,480),raw,'raw','BGRA').convert('RGB') image.save(OUT/f'presentation-{index:02}.png') frames.append(image) assert len({im.tobytes() for im in frames})==len(frames),'Frozen/repeated presentation' for index in (1,2): assert len(frames[index].getcolors(640*480))>5,'Missing native text' # Opening starts at screen centre and expands horizontally, then vertically. for index in (3,4,5,6,7): image=frames[index] assert image.getpixel((320,240)) in ((62,231,216),(8,16,27),(220,75,155)),index assert ImageChops.difference(frames[9],frames[11]).getbbox(),'Typewriter did not advance' sheet=Image.new('RGB',(3*640,4*504),(8,12,20)) draw=ImageDraw.Draw(sheet) for index,image in enumerate(frames): x,y=index%3*640,index//3*504 sheet.paste(image,(x,y)) draw.text((x+12,y+484),f'Native ASM / {index:02}',fill='white') sheet.save(OUT/'presentation-contact.png') if args.window: image=Image.frombytes('RGBA',(640,480),(OUT/'presentation-window.bgra').read_bytes(),'raw','BGRA') image.convert('RGB').save(OUT/'presentation-window.png') print('PASS: ordered startup, automatic/key/skip transitions, guest admission, ' 'centred deployment, typewriter, input cleanup, 50% entry music, ' 'MCI playback/volume, no modal restart, manual track/stop, unchanged saves/RNG/bank; ' '12 native captures'+('; 150 Win32 frames' if args.window else '')) if __name__=='__main__': main()