KAZIK/tools/tests/check_jackbox.py
Artvasil09 41ba8f46ed feat: add rooftop city and optimize native terrace rendering
Add rooftop elevator, lounge, volumetric city, river and animated traffic. Prune invisible mesh faces, clip CPU surfaces, streamline compositing and add automatic/F8 roof quality profiles with renderer diagnostics.

Include dartboard/reticle improvements, tracked fortune orb numerals and fate-session visuals, native regression tests, compatible jukebox IDs and updated shipping executables.
2026-10-26 23:20:35 +03:00

125 lines
5.3 KiB
Python

"""Verification test suite for the Jukebox / Jackbox music system."""
import ctypes
from pathlib import Path
import re
import struct
ROOT = Path(__file__).resolve().parents[2]
def test_packed_assets():
world_bin = ROOT / "assets/animations/hall/jackbox-v1.bin"
ui_bin = ROOT / "assets/animations/hall/jackbox-ui-v1.bin"
assert world_bin.is_file(), f"Missing {world_bin}"
assert ui_bin.is_file(), f"Missing {ui_bin}"
# Check world bin header: ANM1, 256, 512, 3 frames
wdata = world_bin.read_bytes()
magic, w, h, frames, raw_len = struct.unpack("<4s4I", wdata[:20])
assert magic == b"ANM1", f"Bad magic: {magic}"
assert (w, h, frames) == (256, 512, 3), f"Bad dimensions: {w}x{h}, {frames} frames"
assert len(wdata) == 20 + raw_len == 20 + 256 * 512 * 4 * 3
print(f"[OK] jackbox-v1.bin verified: {frames} frames ({w}x{h}), {raw_len} bytes")
# Check UI bin header: ANM1, 640, 480, 1 frame
uidata = ui_bin.read_bytes()
magic, w, h, frames, raw_len = struct.unpack("<4s4I", uidata[:20])
assert magic == b"ANM1", f"Bad magic: {magic}"
assert (w, h, frames) == (640, 480, 1), f"Bad dimensions: {w}x{h}, {frames} frames"
assert len(uidata) == 20 + raw_len == 20 + 640 * 480 * 4
print(f"[OK] jackbox-ui-v1.bin verified: {frames} frame ({w}x{h}), {raw_len} bytes")
def test_audio_tracks():
data_inc = (ROOT / "src_graphics/jackbox_data.inc").read_bytes().decode("cp1251")
open_cmds = re.findall(r'open\s+"([^"]+)"\s+type\s+(\w+)\s+alias\s+jboxmusic', data_inc)
assert len(open_cmds) == 2, f"Expected 2 audio tracks, got {len(open_cmds)}"
for rel_path, media_type in open_cmds:
assert "assets\\music\\jackbox" in rel_path or "assets/music/jackbox" in rel_path, f"Track must be from jackbox directory: {rel_path}"
for rel_path, media_type in open_cmds:
full_path = ROOT / rel_path
assert full_path.is_file(), f"Audio file missing: {rel_path}"
# Test MCI open & close
cmd_open = f'open "{full_path}" type {media_type} alias testjbox'
err = ctypes.windll.winmm.mciSendStringW(cmd_open, None, 0, None)
assert err == 0, f"MCI failed to open {rel_path}: error {err}"
try:
length_buf = ctypes.create_unicode_buffer(64)
err = ctypes.windll.winmm.mciSendStringW("status testjbox length", length_buf, 64, None)
assert err == 0, f"MCI failed to query length of {rel_path}"
finally:
ctypes.windll.winmm.mciSendStringW("close testjbox", None, 0, None)
print(f"[OK] MCI verified track: {rel_path} ({media_type})")
def test_code_structure():
data_inc = (ROOT / "src_graphics/jackbox_data.inc").read_bytes().decode("cp1251")
code_inc = (ROOT / "src_graphics/jackbox.inc").read_bytes().decode("cp1251")
casino_inc = (ROOT / "casino3d.inc").read_bytes().decode("cp1251")
hall_inc = (ROOT / "src_graphics/hall_scene.inc").read_bytes().decode("cp1251")
world_inc = (ROOT / "src_graphics/world_dressing.inc").read_bytes().decode("cp1251")
city_inc = (ROOT / "src_graphics/city_bins.inc").read_bytes().decode("cp1251")
# Check constants
assert "MODE_JACKBOX equ 28" in data_inc
assert "INTERACT_JACKBOX equ 52" in data_inc
assert "JACKBOX_X equ FP_1*306/10" in data_inc
assert "JACKBOX_Y equ FP_1*235/10" in data_inc
assert "MATERIAL_JACKBOX_SIDE equ 121" in data_inc
assert "MATERIAL_JACKBOX_BACK equ 213" in data_inc
# Check procs
procs = [
"LoadJackboxArt3D", "FreeJackboxArt3D", "ResolveJackboxSurface3D",
"DrawJackboxCabinet3D", "RenderJackboxCabinet3D", "JackboxCanWalk3D",
"PlayJukeboxTrack3D", "StopJukeboxTrack3D", "BeginJackbox3D",
"HandleJackbox3D", "RenderJackbox3D",
"CalculateJukeboxFalloff", "UpdateJukeboxAudio3D",
"HandleJukeboxKeys3D", "RenderJukeboxVolumeHUD"
]
for p in procs:
assert f"{p} PROC" in code_inc, f"Missing proc: {p}"
# Check integrations
assert "include src_graphics\\jackbox_data.inc" in casino_inc
assert "include src_graphics\\jackbox.inc" in casino_inc
assert "MODE_JACKBOX" in casino_inc
assert "HandleJackbox3D" in casino_inc
assert "RenderJackbox3D" in casino_inc
assert "call HandleJukeboxKeys3D" in casino_inc
assert "call UpdateJukeboxAudio3D" in casino_inc
assert "call RenderJukeboxVolumeHUD" in casino_inc
assert "jboxUserVolume dd" in data_inc
assert "setaudio jboxmusic volume to" in data_inc
assert "call LoadJackboxArt3D" in world_inc
assert "call FreeJackboxArt3D" in world_inc
assert "call RenderJackboxCabinet3D" in world_inc
assert "INTERACT_JACKBOX" in hall_inc
assert "BeginJackbox3D" in hall_inc
assert "JackboxCanWalk3D" in hall_inc
assert "ResolveJackboxSurface3D" in city_inc
print("[OK] Code structure and all integrations verified.")
def test_binary_executable():
exe_path = ROOT / "poker.exe"
assert exe_path.is_file()
exe_bytes = exe_path.read_bytes()
assert b"jackbox-v1.bin" in exe_bytes
assert b"jackbox-ui-v1.bin" in exe_bytes
assert b"jboxmusic" in exe_bytes
print(f"[OK] poker.exe verified with embedded Jackbox strings ({len(exe_bytes)} bytes).")
if __name__ == "__main__":
test_packed_assets()
test_audio_tracks()
test_code_structure()
test_binary_executable()
print("\nALL JACKBOX / JUKEBOX VERIFICATION CHECKS PASSED!")