init
This commit is contained in:
Executable
+78
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Verify that every manifest resource round-trips to TDKPIN.EXE."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import struct
|
||||
import wave
|
||||
from collections import Counter
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
def main() -> None:
|
||||
manifest = json.loads((ROOT / "assets" / "manifest.json").read_text(encoding="utf-8"))
|
||||
source = (ROOT / manifest["source"]).read_bytes()
|
||||
assert hashlib.sha256(source).hexdigest() == manifest["source_sha256"]
|
||||
assert manifest["resource_count"] == 63
|
||||
assert len(manifest["resources"]) == 63
|
||||
assert not manifest["decode_errors"]
|
||||
|
||||
expected_types = {
|
||||
"DAT": 34,
|
||||
"PAL": 1,
|
||||
"WAV": 16,
|
||||
"BITMAP": 3,
|
||||
"ICON": 1,
|
||||
"GROUP_ICON": 1,
|
||||
"VERSION": 1,
|
||||
"DIALOG": 6,
|
||||
}
|
||||
assert Counter(entry["type"] for entry in manifest["resources"]) == expected_types
|
||||
|
||||
for entry in manifest["resources"]:
|
||||
raw = (ROOT / entry["raw_path"]).read_bytes()
|
||||
offset = entry["file_offset"]
|
||||
allocated_size = entry["allocated_size"]
|
||||
assert len(raw) == allocated_size
|
||||
assert raw == source[offset : offset + allocated_size]
|
||||
assert hashlib.sha256(raw).hexdigest() == entry["raw_sha256"]
|
||||
for decoded_path in entry["decoded_paths"]:
|
||||
assert (ROOT / decoded_path).is_file()
|
||||
if entry["type"] in {"DAT", "BITMAP", "ICON"}:
|
||||
png_paths = [path for path in entry["decoded_paths"] if path.endswith(".png")]
|
||||
assert len(png_paths) == 1
|
||||
with Image.open(ROOT / png_paths[0]) as image:
|
||||
assert image.width == entry["image"]["width"]
|
||||
assert image.height == abs(entry["image"]["height"])
|
||||
if entry["type"] == "WAV":
|
||||
wav_path = ROOT / entry["decoded_paths"][0]
|
||||
with wave.open(str(wav_path), "rb") as stream:
|
||||
assert stream.getnchannels() == entry["audio"]["channels"]
|
||||
assert stream.getframerate() == entry["audio"]["sample_rate"]
|
||||
assert stream.getsampwidth() * 8 == entry["audio"]["sample_width_bits"]
|
||||
if entry["type"] == "DIALOG":
|
||||
dialog = json.loads((ROOT / entry["decoded_paths"][0]).read_text(encoding="utf-8"))
|
||||
assert len(dialog["controls"]) == dialog["declared_control_count"]
|
||||
if "actual_size" in entry:
|
||||
assert 0 < entry["actual_size"] <= allocated_size
|
||||
|
||||
# Verify that the resource intervals do not overlap one another.
|
||||
ranges = sorted(
|
||||
(entry["file_offset"], entry["file_offset"] + entry["allocated_size"])
|
||||
for entry in manifest["resources"]
|
||||
)
|
||||
for previous, current in zip(ranges, ranges[1:]):
|
||||
assert previous[1] <= current[0]
|
||||
|
||||
print("Verified 63/63 raw resources and all decoded derivatives")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user