"""Subtitles (dialogue objects in packages) and menu text (localization files): parse, apply, revert.""" import hashlib import struct import os import pytest import synth from ackit import loctext, subtitles from ackit.game import Game from ackit.texts import MODIFIED, ORIGINAL, TextConflictError from ackit.workspace import Workspace SUB_KEY = "SUB:INT:%s:0" % synth.SPEECH_EVENT def _sha(p): return hashlib.sha1(open(p, "rb").read()).hexdigest() def _ws(root, tmp_path): return Workspace(root, store_root=str(tmp_path / "store"), archives=["INT", "SFX", "BANK"]) def _files(root): d = os.path.join(root, "BmGame") return {os.path.join(a, f): _sha(os.path.join(a, f)) for a, _, fs in os.walk(d) for f in fs} # --- formats ------------------------------------------------------------------------------------ def test_fstring_encoding(): b = subtitles.encode_fstring("Hi", 10, "a") assert b == b"\x06\x00\x00\x00Hi\0\0\0\0" and subtitles.read_fstring(b, 0)[0] == "Hi" w = subtitles.encode_fstring("Привет", 4 + 2 * 8, "w") assert subtitles.read_fstring(w, 0) == ("Привет", 20, "w") with pytest.raises(subtitles.SubtitleError): subtitles.encode_fstring("too long", 10, "a") with pytest.raises(subtitles.SubtitleError): subtitles.encode_fstring("→", 10, "a") # not in cp1252 # every byte reads back as it was, also the 5 that Python's cp1252 leaves undefined (UTF-8 in two game strings) raw = struct.pack(" 9000 s = next(x for x in lines if x.sound) assert ws.texts.current(subtitles.key("ITA", s.speech, s.line)) == s.text menu = ws.texts.menu("ITA") assert len(menu) > 7000 and all(e.lang == "ITA" for e in menu)