- Add ResolveHellAssetPath to automatically load *-hell variants during tournamentMode with fallback to vanilla assets - Rebuild Hell Tower briefing menu using HellTower_menu background with smooth floor cursor and sliding callout info card - Fix buffer overrun in RenderHellTower3D by packing helltower-menu at native 640x480 resolution with bounds-checked blit - Temporarily disable tower background music per user request - Add asset packing pipeline, verification tools, and automated 10-floor run-through smoke test
93 lines
4.3 KiB
Python
93 lines
4.3 KiB
Python
"""Validation test suite for Hell Tower custom assets and redesigned menu."""
|
|
import os
|
|
import struct
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def test_asset_packs():
|
|
print("[1] Verifying Hell Tower binary packs...")
|
|
anm1_packs = [
|
|
(ROOT / "assets/animations/hall/helltower-menu.bin", 640, 480, 1, 1228800),
|
|
(ROOT / "assets/animations/coin/table-v1-hell.bin", 640, 480, 1, 1228800),
|
|
(ROOT / "assets/animations/wheel/closeup-v1-hell.bin", 640, 480, 1, 1228800),
|
|
(ROOT / "assets/animations/wheel/table-v1-hell.bin", 640, 480, 1, 1228800),
|
|
(ROOT / "assets/animations/buckshot/room-v2-hell.bin", 640, 480, 1, 1228800),
|
|
(ROOT / "assets/animations/buckshot/dealer-v2-hell.bin", 256, 224, 16, 16 * 256 * 224 * 4),
|
|
(ROOT / "assets/animations/buckshot/dealer-actions-v3-hell.bin", 256, 224, 16, 16 * 256 * 224 * 4),
|
|
(ROOT / "assets/animations/buckshot/death-v3-hell.bin", 256, 224, 12, 12 * 256 * 224 * 4),
|
|
]
|
|
|
|
for path, exp_w, exp_h, exp_frames, exp_bytes in anm1_packs:
|
|
assert path.exists(), f"Missing pack: {path}"
|
|
data = path.read_bytes()
|
|
assert len(data) >= 20, f"File too small: {path}"
|
|
magic, w, h, frames, byte_count = struct.unpack("<4sIIII", data[:20])
|
|
assert magic == b"ANM1", f"Bad magic {magic} for {path}"
|
|
assert w == exp_w, f"Width mismatch: expected {exp_w}, got {w} for {path}"
|
|
assert h == exp_h, f"Height mismatch: expected {exp_h}, got {h} for {path}"
|
|
assert frames == exp_frames, f"Frames mismatch: expected {exp_frames}, got {frames} for {path}"
|
|
assert byte_count == exp_bytes, f"Bytes mismatch: expected {exp_bytes}, got {byte_count} for {path}"
|
|
assert len(data) == 20 + exp_bytes, f"File size mismatch: {len(data)} != {20 + exp_bytes}"
|
|
print(f" [OK] ANM1 {path.name}: {w}x{h}, {frames} frames, {len(data)} bytes")
|
|
|
|
# CTA1 card table pack
|
|
card_table = ROOT / "assets/textures/card-table-hell.bin"
|
|
assert card_table.exists(), "Missing card-table-hell.bin"
|
|
c_data = card_table.read_bytes()
|
|
c_magic, c_w, c_h, c_bytes = struct.unpack("<4sIII", c_data[:16])
|
|
assert c_magic == b"CTA1", f"Bad CTA1 magic: {c_magic}"
|
|
assert c_w == 640 and c_h == 480, f"Bad size: {c_w}x{c_h}"
|
|
assert c_bytes == 1228800, f"Bad bytes: {c_bytes}"
|
|
assert len(c_data) == 16 + 1228800
|
|
print(f" [OK] CTA1 card-table-hell.bin: {c_w}x{c_h}, {len(c_data)} bytes")
|
|
|
|
|
|
def test_code_integrations():
|
|
print("[2] Verifying ASM code integrations...")
|
|
# Check hell_tower_data.inc
|
|
ht_data = (ROOT / "src_graphics/hell_tower_data.inc").read_text(encoding="cp1251")
|
|
assert "hellTowerMenuArt3D" in ht_data
|
|
assert "hellTowerMenuPath3D" in ht_data
|
|
assert "towerCursorY" in ht_data
|
|
assert "towerCursorTargetY" in ht_data
|
|
assert "towerCalloutAnim" in ht_data
|
|
assert "ResolveHellAssetPath PROTO" in ht_data
|
|
assert "FreeTowerMinigameAssets PROTO" in ht_data
|
|
print(" [OK] hell_tower_data.inc verified.")
|
|
|
|
# Check scene_animation.inc
|
|
scene_anim = (ROOT / "src_graphics/scene_animation.inc").read_text(encoding="cp1251")
|
|
assert "ResolveHellAssetPath PROC" in scene_anim
|
|
assert "invoke ResolveHellAssetPath" in scene_anim
|
|
print(" [OK] scene_animation.inc verified.")
|
|
|
|
# Check card_table_assets.inc
|
|
card_assets = (ROOT / "src_graphics/card_table_assets.inc").read_text(encoding="cp1251")
|
|
assert "invoke ResolveHellAssetPath" in card_assets
|
|
print(" [OK] card_table_assets.inc verified.")
|
|
|
|
# Check hell_tower.inc
|
|
ht_code = (ROOT / "src_graphics/hell_tower.inc").read_text(encoding="cp1251")
|
|
assert "FreeTowerMinigameAssets PROC" in ht_code
|
|
assert "call FreeTowerMinigameAssets" in ht_code
|
|
assert "hellTowerMenuArt3D.pixels" in ht_code
|
|
assert "towerCursorTargetY" in ht_code
|
|
assert "towerCalloutAnim" in ht_code
|
|
print(" [OK] hell_tower.inc verified.")
|
|
|
|
|
|
def test_executable():
|
|
print("[3] Verifying poker.exe build...")
|
|
exe = ROOT / "poker.exe"
|
|
assert exe.exists(), "poker.exe does not exist"
|
|
size = exe.stat().st_size
|
|
print(f" [OK] poker.exe verified ({size} bytes)")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
test_asset_packs()
|
|
test_code_integrations()
|
|
test_executable()
|
|
print("\nALL HELL TOWER CUSTOM ASSET AND MENU CHECKS PASSED SUCCESSFULLY!")
|