Implement deployment card numeric rendering
This commit is contained in:
@@ -2539,6 +2539,30 @@ embedded-NUL termination, all observed comparison operand classes, and the exact
|
||||
case. The full 281-test engine suite, zero-warning Godot build, and threaded frontend selftest pass; manual
|
||||
DEBUGMAP and developer-menu visual rechecks remain.
|
||||
|
||||
### Formatted integers on text surfaces — opcode `0x205` (2026-07-21)
|
||||
|
||||
The deployment picker opened from an empty DEBUGMAP deployment slot uses a third numeric path. Its red
|
||||
unit-information card is built by `DRAWENP.BIN` on temporary surface `0x51`: ordinary `0x204` calls draw
|
||||
labels and separators such as `LV` and `/`, while 16 calls to previously skipped opcode `0x205` draw the
|
||||
level, current/maximum HP/SP/FS, and the two stat columns. This explains why the values alone were absent
|
||||
even after the separate `0x13a`/`0x23b` retained-glyph HUD path was restored.
|
||||
|
||||
`op_0x205_handler@0x422ab0` takes
|
||||
`(surface_slot, x, y, value, field_width, flags)`. It records the 13-dword instruction length, calls
|
||||
`format_integer_for_surface@0x407190`, and sends the returned string and adjusted x coordinate to the same
|
||||
`draw_string_to_surface@0x450150` worker used by opcode `0x204`. The field width includes an optional sign.
|
||||
Flag bit `0x1` zero-pads, `0x2` centers omitted leading cells, and `0x4` left-aligns; the default keeps the
|
||||
field's right edge fixed by moving x right for omitted cells. Bits `0x8`/`0x10` request a plus sign for a
|
||||
positive/zero value, while bit `0x20` gives zero a minus sign. Bit `0x10000`, used by every `DRAWENP` site,
|
||||
keeps half-width ASCII and uses half the current font-cell advance; without it,
|
||||
`ascii_to_fullwidth_cp932_inplace@0x417800` converts the formatted field to full-width CP932.
|
||||
|
||||
The VM now routes the formatted result through the existing styled surface-text host path, preserving the
|
||||
font, color, and effect changes surrounding each call. Focused tests reproduce DRAWENP's exact level-80
|
||||
call and cover half-width right alignment, zero padding, and the observed full-width left-aligned variant.
|
||||
DRAWENP is now 36/36 opcodes and 611/611 instructions handled; all 284 engine tests, the zero-warning Godot
|
||||
build, and threaded frontend selftest pass.
|
||||
|
||||
---
|
||||
|
||||
## Native walls backlog (targets for this loop)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
### 0x75 `set-font-size` (set-font-size, argc 1)
|
||||
- **summary:** (pixels) - set the primary text font height and rebuild its native rasterization state.
|
||||
- **grounding:** source=investigation, confidence=high
|
||||
- **depended on by:** 0x205
|
||||
- **evidence:** Ghidra /v2: op_0x75_handler@0x41ea10 calls text_set_primary_font_size@0x415bd0 on ctx+0x14940. The worker writes the negated pixel height to both primary LOGFONT states, derives width, and rebuilds font resources. HISTORY.BIN selects 22 pixels while active and restores 24 on exit.
|
||||
|
||||
### 0x76 `set-text-color` (set-text-color, argc 1)
|
||||
@@ -127,6 +128,7 @@
|
||||
### 0x204 `draw-string` (draw-string, argc 4)
|
||||
- **summary:** (surface_slot)(x)(y)(string) - rasterize a CP932 string immediately into a numbered graphics surface using current font/color/effect state.
|
||||
- **grounding:** source=investigation, confidence=high
|
||||
- **depended on by:** 0x205
|
||||
- **evidence:** Ghidra /v2: op_0x204_handler@0x422a60 resolves operand 4 as a string, fetches surface/x/y, then calls draw_string_to_surface@0x450150 on text manager ctx+0x14940. The worker validates and locks gfx-manager surface table +0xa590[slot], chooses text_raster_string_uncached@0x459d90 or cached/effect path @0x45b600, rasterizes GDI GetGlyphOutlineA bitmaps through text_blit_glyph_bitmap@0x458c80 using font/color state +0x4d0/+0x458, then unlocks. SC0000 0x9b2 draws the speaker name into 400x30 surface 0xd at (1,1); following 0x1fb binds it to retained object 0xe678 at (74,444).
|
||||
|
||||
### 0x20a `publish-adv-text-layout` (u00420CE0, argc 1)
|
||||
@@ -498,6 +500,14 @@ The handler clears the map embedded at retained-gfx owner+0x408, resets its coun
|
||||
- **grounding:** source=investigation, confidence=high
|
||||
- **evidence:** Ghidra handler 0x4229a0; negative operands read current obj+0x60, then worker 0x47e9b0 stores op2 at obj+0x30 and ARGB at +0x60. gfx_object_composite call-site 0x47f78f passes +0x30/+0x60 directly to gfx_object_blit_d3d9. Correct D3D9 constants at 0x4774c0 prove mode 1 writes SRCBLEND=5/SRCALPHA and DESTBLEND=2/ONE, not INVSRCALPHA. TITLE draws two opaque-black, no-colorkey SO022 flame sprites with mode 1; additive composition removes black and preserves the blue glow, verified in a windowed capture. Mode 2 transition setup and synchronized pixels prove 0xffffffff is identity, not solid white. SC0000 page 14 adds the mode-0 endpoint proof: after the EV052CA->EV052DA 0x223 crossfade, 0x203@0x12478 restores the base CG to mode 0 with preserved 0xffffffff; native keeps EV052DA visible while the port's tint-strength interpretation turns every texel white.
|
||||
|
||||
### 0x205 `draw-formatted-integer` (u00420A60, argc 6)
|
||||
- **summary:** Format an integer into a fixed-width decimal field and rasterize it immediately into a numbered graphics surface using the current font/color/effect state.
|
||||
- **grounding:** source=investigation, confidence=high
|
||||
- **depends on:** 0x75, 0x204
|
||||
- **evidence:** Ghidra /v2: op_0x205_handler@0x422ab0 fetches (surface,x,y,value,width,flags), calls format_integer_for_surface@0x407190, then draw_string_to_surface@0x450150. DRAWENP contains all 16 previously stubbed calls responsible for its level, HP/SP/FS, and stat values.
|
||||
|
||||
The field width includes an optional sign. Bit 0 zero-pads; bit 1 centers omitted leading cells; bit 2 left-aligns; bits 3/4 request '+' for positive/zero; bit 5 renders zero with '-'. With bit 16, output remains half-width ASCII and omitted-cell x adjustment uses half the current font cell advance; otherwise the formatter converts digits/signs to full-width CP932. Default alignment preserves the field's right edge by shifting x right for each omitted leading cell.
|
||||
|
||||
### 0x208 `get-texture-size` (get-texture-size, argc 3)
|
||||
- **summary:** 0x208 (slot)(out_w)(out_h) — writes the loaded texture's width/height into two output globals; keystone for bytecode-computed sprite/bg geometry (SC0000 label_12649)
|
||||
- **grounding:** source=inference, confidence=med
|
||||
@@ -1224,10 +1234,6 @@ op 0x90 (u0041BEB0, argc 7): `0x90 x y w h tgt_a tgt_b tgt_c`. Kelebek left it "
|
||||
- **summary:** —
|
||||
- **grounding:** source=kelebek, confidence=med
|
||||
|
||||
### 0x205 `u00420A60` (u00420A60, argc 6)
|
||||
- **summary:** —
|
||||
- **grounding:** source=kelebek, confidence=low
|
||||
|
||||
### 0x207 `u00420B00` (u00420B00, argc 8)
|
||||
- **summary:** —
|
||||
- **grounding:** source=kelebek, confidence=low
|
||||
|
||||
@@ -467,6 +467,16 @@ focused CP932/NUL, operand-resolution, and stale-destination regressions. All 28
|
||||
Godot build, and threaded selftest pass. The next bounded action is a visual recheck of the DEBUGMAP popup and
|
||||
TITLE developer menu.
|
||||
|
||||
The subsequent DEBUGMAP deployment-picker comparison exposed a separate numeric renderer in
|
||||
`DRAWENP.BIN`. Its red unit-information card draws labels and `/` separators through `0x204`, but draws
|
||||
level, HP/SP/FS pairs, and both stat columns through 16 calls to opcode `0x205`. Native `0x205` formats a
|
||||
fixed-width signed decimal field, applies zero-pad/alignment/half-width flags, adjusts the x anchor for
|
||||
suppressed leading cells, and rasterizes the result into the same temporary surface using current text
|
||||
style. The shared VM implementation now covers that path; focused tests use DRAWENP's exact level call and
|
||||
the observed half-width, zero-padded, and full-width variants. DRAWENP is now 611/611 instructions handled;
|
||||
all 284 engine tests, the zero-warning Godot build, and threaded frontend selftest pass. A manual
|
||||
deployment-card visual recheck remains.
|
||||
|
||||
## Later Phase B breadth
|
||||
|
||||
Once the natural spine and first gameplay loop are trustworthy, broaden in independent tracks:
|
||||
|
||||
Reference in New Issue
Block a user