docs: CLEAR!! already English + HUD render model (GP0-ring evidence)

Corrects and refines the Bucket-1/3 findings with live GPU evidence:

- CLEAR!! banner: ALREADY renders in stylized Latin ("CLEAR!!") — verified
  on-screen in a gameplay stage. Not Japanese; no translation needed. The
  earlier "resister/baked-sprite" assumption was wrong.

- In-game HUD (ステージ/バッテリー): pinned the render model via the always-on
  GP0 ring (gpu_frame_dump). The game composites — ~6 draw prims/frame,
  rebuilding only the animated foreground (character/blocks, ~8 textured 0x2C
  quads at screen y>=31, via BIOS DMA from an OT at ~0x138xxx). The HUD (screen
  y~8) is composed ONCE at stage-load, not per-frame, and has no static SJIS
  source (RAM-scan proof). Remapping it needs catching that stage-load compose
  (a fresh stage load while observing) and a scoped blit/tile intercept — not a
  source-patch. NOT shipped: no clean pixel-verified remap this pass, and a
  blanket VRAM font swap would corrupt katakana elsewhere (Rule 5, no hacks).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matthew Stanley
2026-07-05 18:07:42 -07:00
parent 938fc26f17
commit 4c19677b9e
+38 -28
View File
@@ -729,35 +729,45 @@ address, *regardless of draw path* (per-glyph sprite loop OR string formatter)
both read the same bytes. It CANNOT touch text that is **composed at runtime**
(no static source to overwrite).
### Resisters — composed per-glyph, no static source (NOT shipped)
- **In-game HUD `ステージ:X–Y` / `バッテリー:N`.** Drawn per-glyph as sprites.
**Proof it is composed, not stored:** a full 2 MB guest-RAM scan (live, in a
gameplay stage with the HUD on-screen) finds the katakana `ステージ`
(`58 83 65 83 5b 81 57 83`) and `バッテリー` (`6f 83 62 83 65 83 8a 83 5b 81`)
**only** at the static message-text addresses (`0x800709xx`…), every one
followed by a grammatical particle (を/が/の/は) — i.e. inside sentences, never
as a standalone HUD label. There is no `ステージ:` template
(no occurrence is followed by `:` = `46 81`), and no HUD string buffer in RAM.
So the label is emitted from **hardcoded font-tile indices** (MOJI.BIN glyphs),
not from any SJIS/string the source-patch could rewrite.
- **Stage-clear `CLEAR!!` banner.** No static source of ANY form: `クリア`
(`4e 83 8a 83 41 83`) appears only message-embedded ("…をクリアしていく"…);
there is **no** standalone `クリア`, **no** fullwidth `CLEAR`
(`63 82 6b 82 65 82 61 82 72 82`), and **no** ASCII `CLEAR`/`CLEAR!!` anywhere
in the EXE. It is also **not a baked sprite**: every graphic TIM on the disc
was extracted and rendered (see asset map) — the only pre-rendered text is the
**`TSUMU light` title logo** (`GRAPH1/4.BIN`, already English). So `CLEAR!!`
is composed per-glyph at runtime, same class as the HUD.
### `CLEAR!!` banner — ALREADY ENGLISH (no work needed)
Reaching a gameplay stage (attract demo, HUD on-screen) and screenshotting the
stage-clear moment shows the banner **already renders "CLEAR!!" in stylized
Latin letters** — it is not Japanese. Consistent with the static evidence: `クリア`
(`4e 83 8a 83 41 83`) appears only message-embedded ("…をクリアしていく"…), there
is no standalone `クリア` / fullwidth `CLEAR` / ASCII `CLEAR` in the EXE, and
the disc's only pre-rendered text graphic is the `TSUMU light` logo. The clear
banner is drawn from Latin glyphs the game already owns. **No translation
required** (the earlier "resister" assumption was wrong — corrected here).
Both resisters need the **per-glyph sprite-draw interception + glyph-index
remap** hook flagged in Appendix Y — a separate, larger effort: (1) crack the
MOJI.BIN font layout to map katakana → tile index, (2) pin the composition/draw
routine (Ghidra auto-analysis yields 0 functions on the raw dump; use the
generated C or a live gameplay draw-trace), (3) intercept the sprite draw and
remap indices to Latin **only for the HUD/banner draws** (a blanket VRAM font
swap would corrupt katakana in menus/messages, and `ステージ`→`STAGE` is a
4-vs-5 glyph mismatch). No fragile partial was shipped for these — doing so
without the scoped intercept would corrupt other katakana.
### In-game HUD `ステージ:X–Y` / `バッテリー:N` — RESISTER (characterized, NOT shipped)
The HUD label is the one genuinely-unshipped item. Rendering model, pinned via
the always-on GP0 ring (`gpu_frame_dump`, records every primitive with its
submitting PC + DMA `src_addr`):
- The katakana `ステージ` (`58 83 65 83 5b 81 57 83`) / `バッテリー`
(`6f 83 62 83 65 83 8a 83 5b 81`) exist in a full 2 MB live RAM scan **only** at
the static message-text addresses (`0x800709xx`…), each followed by a particle
(を/が/の/は) — never as a standalone HUD label, and there is no `ステージ:`
template. So there is **no static source the RAM source-patch could rewrite.**
- The game composites heavily: it averages **~6 draw primitives/frame**
(`gp0_draw` ÷ frames) and rebuilds only the animated foreground each frame
(character + a few blocks, ~8 textured `0x2C` quads at screen y ≥ 31, issued
via the BIOS DMA library from an OT at RAM `~0x138xxx`). The HUD sits at screen
y ≈ 8 and is **NOT among the per-frame draws** — it is composed **once at
stage-load** into the display/background and thereafter just shown.
- The stage-load compose is therefore the only place to intercept it, and it
happens before the GP0 ring's steady-state window; catching it needs a **fresh
stage load while observing** (force real gameplay past name-entry, or clear a
stage so the next one composes), then decoding whether the label is blitted as
CPU→VRAM glyph bitmaps (`0xA0`) or drawn as font-tile quads, and remapping that
specific compose — a scoped per-glyph/blit intercept, not a source-patch.
This remains the **per-glyph interception** effort flagged in Appendix Y. It was
NOT shipped: a clean, pixel-verified remap of the composited HUD wasn't achieved
in this pass, and a blanket VRAM font swap (the only "quick" alternative) would
corrupt katakana in menus/messages and can't handle the `ステージ`→`STAGE`
4-vs-5-glyph layout change. Per project Rule 5 (pixels or it's not done) and the
no-fragile-hacks rule, no partial was shipped. Next step for a reachable build:
force a fresh stage-load, dump the GP0 ring across the compose, and remap there.
### Disc asset map (all files extracted from `Tsumu Light (Japan).bin`)
ISO9660 root: `DOUGA.BIN` (FMV), `END.STR` (ending FMV), `FB_TEX.BIN` (4bpp block