fix: correct CJK tooltip layout and center option titles
This commit is contained in:
@@ -3,6 +3,54 @@
|
||||
Working log for the *The I of the Dragon* localization / HD project.
|
||||
Newest entries on top.
|
||||
|
||||
## 2026-09-20 — Center option titles and shorten tutorial exit prompt
|
||||
|
||||
- User confirmed the HUD tooltip fix in game.
|
||||
- Original tutorial text was `\aOK - quit, Cancel - continue tutorial.`;
|
||||
replaced the verbose literal Chinese translation with `\a退出教程?`.
|
||||
- Audio, game, video and controls titles all used fixed left x=620 before
|
||||
resolution scaling. Their panel/button center is reference x=640. At
|
||||
1280px, the 24px Chinese controls title was consequently 20px left of the
|
||||
Bind button center. Title-only draw wrappers now measure actual text width
|
||||
and subtract half from the transformed x=640 anchor, after screen scaling.
|
||||
- `test_cjk_titles.py` executes all four original title call sites with three
|
||||
text widths plus 1280/1920 screen-width cases. Both title tests and all 14
|
||||
tooltip/layout tests pass. Game source patcher and translated Strings.dat
|
||||
are deployed locally; the user confirmed both fixes in game.
|
||||
|
||||
## 2026-09-20 — Fix Chinese HUD tooltip overlap
|
||||
|
||||
- Reproduced the reported world-map/minimap tooltip bug in the game's actual
|
||||
x86 wrapped-text routine (`0x4ED380`) using Unicorn. It builds a one-byte
|
||||
temporary string before measuring each character, so the existing DBCS
|
||||
metrics hook measured isolated GB2312 bytes as width/height zero. This
|
||||
miscentered Chinese lines and advanced the next line by only the 5px line
|
||||
distance, overlapping the 12px Chinese artwork.
|
||||
- Added pair-aware read, append, and fit caves to `tools/apply_cjk.py`.
|
||||
GB2312 pairs now reach the measurer together, are appended/consumed together,
|
||||
and become complete-character wrap checkpoints. Initialized empty-line
|
||||
checkpoints correctly so mixed ASCII/CJK wraps retain the prior line height.
|
||||
A glyph wider than the available box is emitted intact rather than losing
|
||||
its lead byte; existing caller clipping remains responsible for box bounds.
|
||||
- Added `tools/test_cjk_layout.py`: executes the real layout/measurement
|
||||
instructions and captures only the Direct3D draw boundary. Fourteen tests
|
||||
cover screenshot tooltip strings, shortcuts, centering, control codes,
|
||||
measure-only height, mixed text, whitespace, narrow boxes, and oversize glyphs.
|
||||
The original overlap case changes from `(Chinese x=24,y=0; S x=20,y=5)` to
|
||||
`(Chinese x=12,y=0; S x=20,y=17)` in a 48px box.
|
||||
- No atlas, translation, font-size, or mission-script changes are needed.
|
||||
Original exe and patcher snapshots: `backup_game/font-layout-20260920/`.
|
||||
Local deployed program: `F:\steam\steamapps\common\The I of the Dragon\TheIOfTheDragon.exe`.
|
||||
|
||||
Validation (requires `unicorn`):
|
||||
`python tools/test_cjk_layout.py --exe build/cjk-layout-fixed.exe -v`
|
||||
|
||||
Progress audit: local HEAD matched Gitea `ca57488` before this fix; 1884 texture
|
||||
entries / 1882 preprocessed PNGs, 1397 geometry entries, and 479/496 translated
|
||||
Strings.dat IDs. Mission scripts, description tables, baked text, and HD
|
||||
upscaling remain separate unfinished work. Other-font CJK coverage is also
|
||||
still limited as documented in patch-notes.md.
|
||||
|
||||
## 2026-09-20 — Full `Strings.dat` translation
|
||||
|
||||
- Translated the `English` column for **479 / 496** entries (the rest are pure-format
|
||||
|
||||
@@ -100,6 +100,49 @@ Shrift_gb_Germany.TGA 2048 x 1024, 32bpp TGA (type 2, bottom-up, desc 0x08, 26
|
||||
|
||||
## Tools
|
||||
|
||||
### Option-title centering
|
||||
|
||||
Four original title sites push reference x=620 and directly draw text. The
|
||||
panel/Bind button center is reference x=640 (`0x4D8646`). Patch the title
|
||||
anchors to x=640 and redirect their draw calls to `.cjk+0x180500`:
|
||||
|
||||
| Page | Anchor instruction | Draw call |
|
||||
|---|---|---|
|
||||
| Audio | `0x4D748C` | `0x4D74A6` |
|
||||
| Game | `0x4D9A1C` | `0x4D9A36` |
|
||||
| Video | `0x4DDAB4` | `0x4DDACE` |
|
||||
| Controls | `0x4DE8C8` | `0x4DE8E2` |
|
||||
|
||||
The wrapper preserves registers, measures the supplied font/text using
|
||||
`0x4E7FD0`, subtracts half the measured width from the already transformed
|
||||
screen point, and tail-jumps to `0x4EAB70`. Ordinary option rows and unrelated
|
||||
draw calls retain their existing placement. Input opcodes are checked before
|
||||
these title edits. `tools/test_cjk_titles.py` tests the actual call-site code,
|
||||
coordinate transformation, measurement, and resulting draw positions.
|
||||
|
||||
### Wrapped-text layout correction
|
||||
|
||||
`0x4ED380` wraps/aligns tooltip paragraphs separately from the plain draw and
|
||||
measure loops. Its one-byte temporary string must be extended to a full GB2312
|
||||
character, otherwise a Chinese-only line has zero measured glyph height.
|
||||
|
||||
New hooks (all addresses apply to the documented Steam executable):
|
||||
|
||||
| Hook | Cave offset in .cjk | Purpose |
|
||||
|---|---|---|
|
||||
| `0x4ED430` | `0x180200` | Prepare a NUL-terminated one/two-byte character; preserve control-code flags |
|
||||
| `0x4ED50E` | `0x180300` | Append complete character, advance byte index, retain width/height at CJK break |
|
||||
| `0x4ED4E9` | `0x180400` | Preserve an overwide first CJK glyph instead of consuming only its lead byte |
|
||||
|
||||
Layout locals: `esp+0x18..0x1A` character plus NUL, `+0x1B` byte length,
|
||||
`+0x14` source byte index, `+0x24` output byte count, `+0x1C` last wrap
|
||||
checkpoint. Empty output initializes the checkpoint to `source_index-1`.
|
||||
The caves use spare space after the metric table; UVs and atlas pixels are
|
||||
unchanged. `tools/test_cjk_layout.py` runs the original layout and measurement
|
||||
machine code in Unicorn and captures line bytes and coordinates at the draw
|
||||
call boundary. This checks layout behavior without replacing it with a Python
|
||||
reimplementation.
|
||||
|
||||
- `tools/add_section.py` — append an executable PE section.
|
||||
- `tools/apply_cjk.py` — assemble the caves (keystone), add `.cjk`, write hooks and tables.
|
||||
- `tools/build_cjk.py` — build the atlas TGA + `cjk_glyph`/`cjk_metric` from a charset.
|
||||
|
||||
Reference in New Issue
Block a user