Commit Graph

10 Commits

Author SHA1 Message Date
Matthew Stanley c6d12d76cd docs: Appendix Z — full 37-entry vram_patch coverage + palette-family notes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 01:51:23 -07:00
Matthew Stanley d78e7a784f text_xlate: [[vram_patch]] pre-rendered-strip layer + GP0-ring builder attribution
Two interlocking pieces from the Tsumu HUD/menu-label investigation:

- GP0 ring builder attribution (gpu.h/gpu.c/debug_server.c): op-0x80
  entries now carry a bounded guest-stack unwind (bld[6]) + copy-time
  $sp (csp); gpu_frame_dump emits func/ra per entry and csp+bld[] for
  copies. This cracked the HUD compose: whole label strips are
  MoveImaged from the glyph sheet (src 834/852,352 -> HUD cache y=32).

- [[vram_patch]] (text_xlate.cpp/.h + gpu.c hook): third translation
  layer for text that exists only as pre-rendered pixels in an
  uploaded texture asset (Tsumu HUD labels, menus, prompts live in
  the glyph-sheet image; the 144-glyph font has no katakana at all).
  On every GP0 0xA0 upload completion the configured rects are
  verified halfword-for-halfword against expected JP pixels and only
  then rewritten with the target-language pixels via the renderer
  facade (software/GL/supersample coherent). Re-applies on every
  re-upload; verify-fail leaves foreign assets untouched. Debug:
  xlate stats gains vram_patches/vram_applied; new "vpatch"
  force-apply subcommand for config iteration without rebuild.

Verified on-screen: HUD "STAGE: 1-1 / BATTERY: 100", pause menu
(CONTINUE/RESTART/GIVE UP/CHANGE CONTROLS, TARGET BATT), title-menu
strips. docs/STRING_TRANSLATION.md Appendix Z documents the model,
mechanism, authoring recipe, and remaining strip backlog.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 01:41:42 -07:00
Matthew Stanley 4806096cde docs: HUD reachability blockers (empty saves, static demo HUD)
Records the LOAD-GAME attempt outcome and why the HUD can't be finished
headless: both memcards are empty (0 used blocks) so LOAD GAME reaches no
stage; NEW GAME still hits the intractable name grid; and the attract
demo's HUD is composed once at stage-load and only displayed (never
per-frame-drawn as glyph quads in the full 554-3754 GP0 capture; its
values are static so there is no dynamic draw to intercept). The drawer
(0x8005443C) + font-tile scheme are cracked; capturing the HUD label's
own glyph quads needs real gameplay (dynamic HUD) reachable only via a
real save or driving past the name grid on an interactive build. No hook
shipped (no discriminator captured -> would risk non-HUD quads; Rule 5).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 18:30:16 -07:00
Matthew Stanley 7627978b8c docs: pin the per-glyph text drawer (0x8005443C) for the HUD remap
Live GP0-ring capture (on the name-entry screen, same per-glyph drawer
class as the HUD) cracked the mechanism for the eventual HUD index-remap:

- Drawer PC 0x8005443C draws one textured 0x2C quad per glyph via direct
  GP0, building prims in game RAM ~0x80092xxx; U,V into texpage 0x1E
  selects the font tile (CLUT 0x7C10).
- Texpage 0x1E holds hiragana AND Latin (the name-entry grid draws A-Z
  through this same drawer), so the Latin tile U,Vs the remap needs are
  readable straight off the grid's letter quads.
- Remaining blocker: catch the HUD's own stage-load compose to get its
  katakana source prims, then rewrite their U,V to Latin tiles (or hook
  0x8005443C to remap HUD-position glyph quads). Gated only on reaching a
  fresh stage-load (blind grid-confirm navigation didn't land headless; a
  reachable build clears it). No fragile partial shipped (Rule 5).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 18:12:32 -07:00
Matthew Stanley 4c19677b9e 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>
2026-07-05 18:07:42 -07:00
Matthew Stanley 938fc26f17 docs: per-glyph coverage pass — shipped labels + composed-HUD/CLEAR resisters
Records the outcome of the per-glyph translation pass (Buckets 1-3):

- SHIPPED: stage/level/tutorial names (source-patch, f00631e/31ab3c2);
  name-entry prompt -> "YOUR NAME?" (source-patch, 31ba92d); name-entry
  Latin input confirmed NATIVE (grid already draws the font's A-Z/0-9).

- RESISTERS (not shipped, no fake): the in-game HUD (ステージ/バッテリー)
  and the CLEAR!! banner are composed per-glyph at runtime with NO static
  source address. Proven: a live 2 MB RAM scan finds ステージ/バッテリー
  only inside static message sentences (never a standalone HUD label,
  no ステージ: template); クリア/CLEAR/CLEAR exist nowhere as a
  standalone banner; and every disc graphic TIM was extracted+rendered —
  the only baked text is the already-English TSUMU light logo. So the
  source-patch (which needs a static address) cannot reach them; they
  require the scoped per-glyph sprite-draw index-remap hook (Appendix Y),
  a separate larger effort. Includes the full disc asset map.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 17:49:17 -07:00
Matthew Stanley b0f8a8518c docs: per-glyph text investigation (font index map, label storage, hook design)
Records the concrete findings for the deferred per-glyph HUD/menu/title
localization: the font glyph-index map (Latin A-Z=73-98, 0-9=105-114;
fullwidth Latin glyphs present, no injection needed), the static LE-SJIS
label storage in fixed-width space-padded slots (level names 0x80070755+,
tutorial/mode labels 0x80070300+), and the cleanest hook design (load-time
source patch: rewrite a label's katakana/hiragana SJIS to fullwidth-Latin
so the existing per-glyph routine draws English).

Not shipped: the verification bar is a rendered-English screenshot, and the
target screens (mode/level-select, in-game HUD) are unreachable in the
headless build — the attract never auto-plays the demo, and reaching them
needs completing the name-entry glyph grid (blind grid nav to the "End"
cell did not land). Committing a RAM-patch without that screenshot would be
unverified coverage. Remaining resisters (HUD runtime counter; title/CLEAR
sprites) documented.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 15:29:56 -07:00
Matthew Stanley d24d660774 docs: coverage status - 138-entry message table + reader limitation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 13:52:32 -07:00
Matthew Stanley c72e36d10e docs: record Phase-0 empirical findings for string translation
Fold the hard-won runtime findings into STRING_TRANSLATION.md: the
message-table text is little-endian 16-bit Shift-JIS (EXE menu labels are
big-endian); FE-FF/FF-FF/30-FC control framing; message text is
string-pointer-drawn (interceptable) but HUD/title/menu are per-glyph
sprites (need a separate glyph-index hook); struct-embedded NUL records
crash if replaced (apply gated to 0xFFFF-framed messages by default);
capture quality gate; verification status; open items for full coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 12:19:53 -07:00
Matthew Stanley bf4482b4c8 docs: spec on-the-fly string translation / localization framework
Implementation-ready design for capturing PSX source strings from memory
and substituting translated bytes on the fly, so JP-only titles (Tsumu
Light SLPS-02253 first) can be played in English or any language.

Adapts the author's proven n64recomp prior art (Pocket Monsters Stadium
JP): always-on capture ring keyed by FNV-1a64 content hash, a per-title
multilingual table, and a draw-time apply hook that repoints the string
arg at guest scratch so the original renderer draws the replacement (no
regen, unbounded length, dynamic args preserved).

Grounds the PSX design in real findings: Tsumu text is Shift-JIS (2-byte
fullwidth + 1-byte halfwidth kana) with 0xFFFF-framed message records;
in-EXE text block ~0x80070900-0x80072000 via pointer table at 0x80071474;
menu labels at 0x80010C5C/0x80010C94; font already has fullwidth Latin
(English renders with zero glyph injection). Hooks onto the psx_dispatch
chokepoint (fntrace_record census + g_psx_bios_hle_hook precedent), so no
per-function codegen and works in Release.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 11:04:47 -07:00