KAZIK/tools/tests/check_hell_fps.py
Игорь Федосеев ce5121debd feat: add native hell expedition
Add a painting entrance, Freedoom combat and Doom-style HUD.

Persist the one-time clear reward in signed saves without changing file sizes. Include native regression checks and synchronized game/launcher builds.
2026-11-01 22:29:09 +03:00

53 lines
2.6 KiB
Python

"""Build and execute native MASM combat, renderer, progression and save checks."""
from pathlib import Path
import argparse
import hashlib
import subprocess
from PIL import Image
from check_artifacts import toolchain
ROOT = Path(__file__).resolve().parents[2]
OUT = ROOT / 'build/scratch'
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--window',action='store_true')
options = parser.parse_args()
OUT.mkdir(parents=True, exist_ok=True)
before = {p: hashlib.sha256(p.read_bytes()).digest() for p in (ROOT/'runtime').rglob('*') if p.is_file()}
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.','/DHELL_FPS_TEST=1',
'/Fobuild/scratch/hell-fps.obj','poker.asm'],
[link,'/nologo','/SUBSYSTEM:CONSOLE','/LIBPATH:'+str(lib),
'/OUT:build/scratch/hell-fps-test.exe','build/scratch/hell-fps.obj',
'kernel32.lib','winmm.lib','user32.lib','ws2_32.lib','gdi32.lib']]
if options.window:
commands[0].insert(1,'/DHELL_FPS_WINDOW_TEST=1')
for command in commands:
subprocess.run(list(map(str,command)),cwd=ROOT,check=True,timeout=120)
try:
result = subprocess.run([str(OUT/'hell-fps-test.exe')],cwd=OUT if options.window else ROOT,timeout=90)
finally:
assert before == {p: hashlib.sha256(p.read_bytes()).digest() for p in (ROOT/'runtime').rglob('*') if p.is_file()}, 'Test changed player saves'
assert result.returncode == 0, f'Native test failed at stage/exception {result.returncode:#x}'
for name in (('window',) if options.window else ('entry','court','portal','victory')):
raw = (OUT/f'hell-{name}.bgra').read_bytes()
assert len(raw) == 640*480*4
image = Image.frombytes('RGBA',(640,480),raw,'raw','BGRA').convert('RGB')
image.save(OUT/f'hell-{name}.png')
assert len(image.getcolors(640*480)) > 100, f'{name}: blank renderer'
if options.window:
print('PASS: real Win32 window, 120 presented frames, mouse-down/up events, firing, Mick Gordon playback, six SFX channels, clean return')
return
print('PASS: painting entrance, collision/LOS, multi-target seven-pellet shotgun, '
'single-ray pistol, armour/death/retry, gates/secrets, '
'1050 AI ticks, finite-ammo boss fight with dodging, first-clear reward, '
'native/preview save roundtrips, return, 4 native render captures')
if __name__ == '__main__':
main()