"""Offline, byte-preserving replacement of explicitly listed MASM UI labels.""" import argparse import json import re from pathlib import Path ROOT = Path(__file__).resolve().parents[2] MAP = ROOT / "assets/data/ui-ru.json" def compile_ui(check=False): translations = json.loads(MAP.read_text(encoding="utf-8")) declarations = re.compile(rb"^(\w+)([ \t]+db[ \t]+)([^\r\n]+(?:\r?\n[ \t]+db[ \t]+[^\r\n]+)*)", re.M) seen = set() changes = [] paths = [ROOT / "casino3d.inc", *sorted((ROOT / "src_graphics").glob("*_data.inc"))] for path in paths: original = path.read_bytes() def replace(match): symbol = match[1].decode("ascii") if symbol not in translations: return match[0] assert symbol not in seen, f"Duplicate declaration: {symbol}" seen.add(symbol) values = [*translations[symbol].encode("cp1251"), 0] chunks = [values[i:i + 32] for i in range(0, len(values), 32)] newline = b"\r\n" if b"\r\n" in original else b"\n" encoded = (newline + b" db ").join(",".join(map(str, chunk)).encode("ascii") for chunk in chunks) return match[1] + match[2] + encoded updated = declarations.sub(replace, original) if updated != original: changes.append(path.relative_to(ROOT).as_posix()) if not check: path.write_bytes(updated) assert seen == translations.keys(), f"Missing labels: {translations.keys() - seen}" if check: assert not changes, f"Translation not compiled: {changes}" print(f"PASS: {len(seen)} Russian labels, CP1251 bytes, {len(changes)} files updated") if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--check", action="store_true") compile_ui(parser.parse_args().check)