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.
72 lines
3.5 KiB
Python
72 lines
3.5 KiB
Python
"""Verify the native/legacy file mappings and Windows MCI decoders without playing audio."""
|
|
import ctypes
|
|
from pathlib import Path
|
|
import re
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def asm_paths():
|
|
for file in [ROOT / "src_graphics/audio_data.inc", ROOT / "src_graphics/casino_actions_data.inc"]:
|
|
definitions = {}
|
|
current = None
|
|
for line in file.read_text(encoding="ascii").splitlines():
|
|
match = re.match(r"(\w+) db (.+)$", line)
|
|
continuation = re.match(r"\s+db (.+)$", line)
|
|
if match:
|
|
current = match[1]
|
|
definitions[current] = match[2]
|
|
elif continuation and current:
|
|
definitions[current] += "," + continuation[1]
|
|
else:
|
|
current = None
|
|
for symbol, payload in definitions.items():
|
|
chunks = re.findall(r'"[^"]*"|\d+', payload)
|
|
raw = b"".join(c[1:-1].encode("ascii") if c.startswith('"') else bytes([int(c)]) for c in chunks)
|
|
name = raw.rstrip(b"\0").decode("cp1251")
|
|
if name.endswith(".wav"):
|
|
yield symbol, name
|
|
|
|
|
|
def main():
|
|
native = dict(asm_paths())
|
|
assert native["soundCards"].endswith("playing_cards_deck_flick_through_001_20485.wav")
|
|
assert native["soundCoin"].endswith("Звук монеты брошенной в воздух и упавшей на поверхность.wav")
|
|
assert native["soundRoulette"].endswith("roulette-wheel-throw-2.wav")
|
|
assert native["rrDrySound3D"].endswith("revolverdryfirec.wav")
|
|
assert native["rrFireSound3D"].endswith("b05e1ac8be34248.wav")
|
|
assert native["soundClick"] != native["rrDrySound3D"]
|
|
assert native["soundDiceRoll"] != native["soundCards"]
|
|
engine = (ROOT / "casino3d.inc").read_text(encoding="cp1251")
|
|
assert "invoke PlaySoundA, OFFSET sound" not in engine
|
|
assert "call InitSounds" in engine.split("run_game_body:")[1].split("LaunchClassicGame ENDP")[0]
|
|
legacy = (ROOT / "poker.asm").read_text(encoding="cp1251")
|
|
recordings = set(native.values())
|
|
recordings.update(re.findall(r'open "(assets\\audio\\[^"\r\n]+\.wav)" type waveaudio', legacy))
|
|
checked = 0
|
|
for name in sorted(recordings):
|
|
if name.endswith("gman-wakeup.wav") and not (ROOT / name).exists():
|
|
continue # Optional future voice-over.
|
|
path = ROOT / name
|
|
assert path.is_file(), f"Missing audio: {name}"
|
|
command = f'open "{path}" type waveaudio alias audiotest'
|
|
error = ctypes.windll.winmm.mciSendStringW(command, None, 0, None)
|
|
assert error == 0, f"MCI cannot open {name}: {error}"
|
|
try:
|
|
error = ctypes.windll.winmm.mciSendStringW("set audiotest time format milliseconds", None, 0, None)
|
|
assert error == 0
|
|
length = ctypes.create_unicode_buffer(64)
|
|
error = ctypes.windll.winmm.mciSendStringW("status audiotest length", length, 64, None)
|
|
assert error == 0 and int(length.value) > 0
|
|
finally:
|
|
ctypes.windll.winmm.mciSendStringW("close audiotest", None, 0, None)
|
|
if ctypes.windll.kernel32.GetACP() == 1251:
|
|
error = ctypes.windll.winmm.mciSendStringA(command.encode("cp1251"), None, 0, None)
|
|
assert error == 0, f"MCI A/CP1251 cannot open {name}: {error}"
|
|
ctypes.windll.winmm.mciSendStringA(b"close audiotest", None, 0, None)
|
|
checked += 1
|
|
print(f"PASS: {checked} WAV files decoded; native and legacy mappings verified.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|