# DEVLOG Working log for the *The I of the Dragon* localization / HD project. Newest entries on top. ## 2026-09-20 — Chinese in the main menu (first playable) - Built `tools/build_cjk.py`: renders the full GB2312 set (7445 double-byte codes) as **12x12** glyphs with simsun (crisp/binary, matching the game's pixel font) into a **2048x1024** TGA. The original 256x128 ASCII artwork is copied to (0,0), so all existing `Fonts.dat` rects keep working unchanged (verified byte-identical). Also emits `cjk_glyph.bin` / `cjk_metric.bin`. Advance/height = 12 (the UI font cap height is ~11-12px), drawn 1px up to fit the cell. - `tools/cn_strings.py` + `tools/make_cn_strings.py`: translate the `English` column of `Strings.dat` to GB2312 (46 entries; escape-aware so `\"%s\"` formats survive). - `tools/install_cjk.py`: one-shot deploy/restore (backs up exe/res/strings; rebuilds `Textures.res` with the new atlas, drops the loose atlas, patches the exe and the strings). - **Result**: the main menu renders Chinese — 开始新游戏 / 载入游戏 / 选项 / 教程 / 制作人员 / 退出 / 载入上次存档:"…" — confirmed by the user on screen. ### Fixed a byte-order bug in the metrics cave The draw cave decoded the code as `(first<<8)|second`, but the metrics cave used `movzx eax,al; mov ah,[ebx+1]` which produced `(second<<8)|first`. Every CJK width measured as 0, so centred labels (the "Start New Game" button) were flushed right. Fixed to `movzx eax,al; shl eax,8; mov al,[ebx+1]`. Centring is now correct. ### Notes / next - The menu button labels *are* dynamic (`Strings.dat`) — the earlier suspicion of baked button images was wrong; the layer confusion came from the animated particle background. - Remaining UI text that is baked into textures (credits, tutorial pics) still needs redrawing. - Next: translate the rest of `Strings.dat`, scripts and `*Description.dat`; then HD textures. ## 2026-09-20 — Double-byte font patch proven - Reverse-engineered the whole text pipeline (see `patch-notes.md`). - Built `tools/add_section.py` (PE section injection) and verified the patched exe still runs. - Built `tools/apply_cjk.py`: assembles two code caves with keystone, adds a `.cjk` section, hooks the draw loop (`0x4EACB0`) and the metrics loop (`0x4E8026`). - **Verified on screen**: a GB2312-coded string `0xC1FA` (龙) in a menu label rendered a 16x16 glyph at the mapped atlas position (green control test). Double-byte decode + render works. - Game files restored afterwards (exe SHA1 `9EDB9B99...`, `Textures.res` byte-identical). ### Next 1. Big atlas (2048x2048): ASCII glyphs (copied) + CJK glyphs; re-point `Fonts.dat` `Texture` + ASCII rects. 2. Generator for `cjk_glyph` / `cjk_metric` tables from a chosen charset. 3. Convert `Strings.dat`, scripts, and `*Description.dat` display text to GB2312. 4. Redraw baked-in text textures (menu buttons, credits, tutorial). 5. Package: patched exe + atlas + data files. ## 2026-09-20 — HD texture preprocessing - Cracked the `.res` archive format and built `res_unpack.py` / `res_repack.py` (byte-identical round-trip once 16-byte alignment was found). - Extracted `Textures.res` (1884) and `Geometry.res` (1397). - Built `preprocess.py` (TGA/DDS→PNG, classification) and `make_plan.py`. - Result: 63.6 Mpix, 1882 PNG, 0 failures. Plan: 1195 upscale / 499 tiling / 182 review / 8 skip (6 font atlases + 2 non-textures). ## 2026-09-20 — Cracking the `.dat` obfuscation - `Fonts.dat` / `UnitDescription.dat` / `AIDescription.dat` decoded: `b"==" + XOR(plaintext, "GBDFYTNE")`; key at `0x620D18`, decoder at `0x4AE1D0`. - `Fonts.dat` parsed: 4 font blocks, per-char atlas rects; parser keeps only the first byte of `Code` (`0x4EC168`), so the stock engine is single-byte. ## 2026-09-20 — Initial findings - Engine has a data-driven multi-language system: per-language folders for scripts/speech/video/UI textures and language columns in `Strings.dat`. - Text is externalized: `Strings.dat` (499 entries, plain) and plain-text scripts. - First font test: replaced the `e` glyph in `Shrift_gb_Germany.TGA` and confirmed the atlas override works in game (rendered 龙 where `e` was). - Investigated the "pirate build": PROPHET 2009 Topware release, languages EN/DE/PL/CZ/HU, **no Chinese**; its exe is identical to the Steam exe (no engine patch), so the Chinese build the user remembers was a different repack (not recoverable from it). ## Decisions - Do the localization ourselves (route B): patch the engine for double-byte text, build our own font atlas, translate only display text (never Ids / event names / unit types) to avoid trigger bugs. - Keep the repository text-only; regenerate binaries from scripts (see `.gitignore`).