#!/usr/bin/env python3 """Parse a RATC bundle's header SPRITE DECLARATION TABLE: u32 count at 0x14, then fixed 60-byte entries of [name, NUL-padded | 4 u32 flags | pivotX | pivotY | 0]. Check each pivot against half the decoded texture's real dimensions.""" import struct, sys, glob, re, os def decls(d): n = struct.unpack_from(">I", d, 0x14)[0] out = [] for i in range(n): o = 0x20 + i * 60 if o + 60 > len(d): break name = d[o:o+28].split(b"\0")[0].decode("ascii", "replace") px, py = struct.unpack_from(">II", d, o + 48) out.append((name, px, py)) return n, out def texmap(prefix): t = {} for f in glob.glob(f"pause-tex/{prefix}_*.png"): m = re.match(rf".*/{prefix}_(.+)\.t32_(\d+)x(\d+)\.png", f) if m: t[m.group(1) + ".t32"] = (int(m.group(2)), int(m.group(3))) return t for path, prefix in [(sys.argv[1], sys.argv[2])]: d = open(path, "rb").read() n, ds = decls(d) tm = texmap(prefix) print(f"{os.path.basename(path)}: count={n}, parsed={len(ds)}") ok = bad = miss = 0 for name, px, py in ds: if name in tm: w, h = tm[name] hit = (px == w // 2 and py == h // 2) ok, bad = ok + hit, bad + (not hit) flag = "OK " if hit else "MISMATCH" print(f" {flag} {name:28s} tex {w:4d}x{h:<4d} half {w//2:4d},{h//2:<4d} decl {px:4d},{py:<4d}") else: miss += 1 print(f" ? {name:28s} (no decoded texture) decl {px:4d},{py:<4d}") print(f" => pivot == half(texture): {ok} ok, {bad} mismatch, {miss} unchecked")