Chinese main menu: font atlas + GB2312 tables + Strings translation
- build_cjk.py: 2048x1024 UI atlas (original ASCII at 0,0 + full GB2312 at 12px) and cjk_glyph/cjk_metric tables. - cn_strings.py + make_cn_strings.py: escape-aware GB2312 rewrite of Strings.dat (46 entries). - install_cjk.py: one-shot deploy/restore (exe patch, atlas loose+res, strings). - apply_cjk.py: fix metrics cave code byte order (was (second<<8)|first) so CJK width measures correctly and centred labels are no longer flushed right. - docs: DEVLOG + patch notes for the atlas and the fix.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
"""Patch the `English` column of `Data\\Misc\\Strings.dat` with simplified Chinese.
|
||||
|
||||
Reads the byte-exact file (single byte code page), replaces only the value that
|
||||
follows `Id = "<id>"` and `English = "..."`, and writes GB2312 double byte text.
|
||||
The original is preserved next to it as `Strings.dat.orig` (once).
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from cn_strings import CN_STRINGS
|
||||
|
||||
DEFAULT_GAME = r"F:\steam\steamapps\common\The I of the Dragon"
|
||||
|
||||
|
||||
def patch(raw, mapping):
|
||||
done, missing = [], []
|
||||
for sid, cn in mapping.items():
|
||||
enc = cn.encode("gb2312")
|
||||
pat = re.compile(
|
||||
rb'(Id\s*=\s*"' + re.escape(sid.encode("latin1")) + rb'"'
|
||||
rb'\s*[\r\n]+\s*English\s*=\s*")(?:[^"\\]|\\.)*(")'
|
||||
)
|
||||
new, n = pat.subn(lambda m: m.group(1) + enc + m.group(2), raw, count=1)
|
||||
if n:
|
||||
raw = new
|
||||
done.append(sid)
|
||||
else:
|
||||
missing.append(sid)
|
||||
return raw, done, missing
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--game", default=DEFAULT_GAME)
|
||||
ap.add_argument("--file", default=None)
|
||||
ap.add_argument("--restore", action="store_true")
|
||||
args = ap.parse_args()
|
||||
|
||||
path = args.file or os.path.join(args.game, "Data", "Misc", "Strings.dat")
|
||||
bak = path + ".orig"
|
||||
|
||||
if args.restore:
|
||||
if os.path.exists(bak):
|
||||
open(path, "wb").write(open(bak, "rb").read())
|
||||
print("restored", path)
|
||||
else:
|
||||
print("no backup at", bak)
|
||||
return
|
||||
|
||||
if not os.path.exists(bak):
|
||||
open(bak, "wb").write(open(path, "rb").read())
|
||||
print("backup ->", bak)
|
||||
|
||||
raw = open(path, "rb").read()
|
||||
out, done, missing = patch(raw, CN_STRINGS)
|
||||
open(path, "wb").write(out)
|
||||
print("patched %d/%d strings (%d bytes)" % (len(done), len(CN_STRINGS), len(out)))
|
||||
if missing:
|
||||
print("MISSING:", missing, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user