KAZIK/tools/tests/check_city_lighting.py
Artvasil09 3ad5bf4c9d Develop assembly-only casino scenes and native games
Add native Durak, poker, blackjack, roulette, Buckshot and billiards scenes with animation assets and regression tests. Improve arrival, city, hall, profiles, shops, audio and exit handling; remove the portable C game core and refresh shipping executables.
2026-10-08 22:39:19 +03:00

55 lines
2.3 KiB
Python

"""Compare real MASM lightmap frames; this script is offline QA, not game code."""
import json
import struct
from pathlib import Path
from PIL import Image, ImageChops, ImageStat
def main():
root = Path(__file__).resolve().parents[2]
output = root / "build/actions"
off = Image.open(output / "street-light-off.bmp").convert("RGB")
on = Image.open(output / "street-light-on.bmp").convert("RGB")
assert on.size == off.size == (640, 480)
changed_ground = 0
warm_ground = 0
saturated = 0
for y in range(280, 480):
for x in range(640):
before, after = off.getpixel((x, y)), on.getpixel((x, y))
if before != after:
changed_ground += 1
if after[0] - before[0] > after[2] - before[2]:
warm_ground += 1
saturated += min(after) == 255
assert changed_ground > 2000, "Lamp/window spill is not visible on the ground"
assert warm_ground > changed_ground * .7, "Light is not warm/localized"
assert saturated < 1000, "Lighting washed out the pavement"
assert sum(ImageStat.Stat(on).stddev) > 30, "Texture detail disappeared"
on.save(output / "street-light-on.png")
off.save(output / "street-light-off.png")
ImageChops.difference(on, off).save(output / "street-light-difference.png")
for name in ("poker-exit", "blackjack-exit"):
frame = Image.open(output / f"{name}.bmp").convert("RGB")
assert frame.size == (640, 480)
assert frame.getpixel((40, 128)) == (213, 199, 158), name
assert frame.getpixel((64, 300)) == (213, 199, 158), name
assert frame.getpixel((328, 300)) == (85, 101, 85), name
frame.save(output / f"{name}.png")
elapsed = struct.unpack("<2I", (output / "street-light-perf.bin").read_bytes())
report = {
"result": "PASS",
"changed_ground_pixels": changed_ground,
"warm_ground_pixels": warm_ground,
"saturated_ground_pixels": saturated,
"frame_ms_light_off": round(elapsed[0] / 12, 2),
"frame_ms_light_on": round(elapsed[1] / 12, 2),
"note": "Headless native render timing, not a whole-game FPS benchmark",
}
(output / "city-lighting-report.json").write_text(json.dumps(report, indent=2))
print(json.dumps(report))
if __name__ == "__main__":
main()