Implement PrintLetterDelay with wOptions text speed; default MEDIUM

Faithful translation of home/print_text.asm:PrintLetterDelay. Reads per-
character frame delay from wOptions bits 3-0 (FAST=1 / MEDIUM=3 / SLOW=5
frames). Exits early on A/B held. No-op when BIT_TEXT_DELAY is unset
(TextCommandProcessor sets it) or BIT_NO_TEXT_DELAY in wStatusFlags5.

TextCommandProcessor (text.asm): saves wLetterPrintingDelayFlags on entry,
sets BIT_TEXT_DELAY to activate delay for the session, restores on TX_END.
Mirrors the push af / set BIT_TEXT_DELAY / pop af pattern from the SM83 source.

init.asm: initialises wLetterPrintingDelayFlags = BIT_FAST_TEXT_DELAY and
wOptions = TEXT_DELAY_MEDIUM (3 frames/char) at startup, matching InitOptions
from engine/menus/main_menu.asm. The OPTIONS menu is not yet implemented;
the speed selection is wired to wOptions but unwired from any menu — change
wOptions to TEXT_DELAY_FAST/SLOW to select a different speed once that menu
is built.

gb_memmap.inc: add W_OPTIONS (0xD354), BIT_FAST_TEXT_DELAY/BIT_TEXT_DELAY/
BIT_NO_TEXT_DELAY, TEXT_DELAY_FAST/MEDIUM/SLOW/MASK constants.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Gj9B8K48MbP27sZYybWVt
This commit is contained in:
Happyarch
2026-06-23 19:27:28 -04:00
parent 25af446ac5
commit c3e656d9b2
3 changed files with 67 additions and 3 deletions

View File

@@ -362,9 +362,24 @@ W_IGNORE_INPUT_COUNTER equ 0xD139 ; wIgnoreInputCounter — counts down 30
; Current-map script flags
W_CURRENT_MAP_SCRIPT_FLAGS equ 0xD125 ; wCurrentMapScriptFlags
; Letter-printing delay flags (text engine)
; Letter-printing delay and text speed options (text engine)
; Pret ref: constants/ram_constants.asm, engine/menus/main_menu.asm:InitOptions
W_OPTIONS equ 0xD354 ; wOptions bits 3-0 = text speed
W_LETTER_PRINTING_DELAY equ 0xD357 ; wLetterPrintingDelayFlags
; wLetterPrintingDelayFlags bit indices
BIT_FAST_TEXT_DELAY equ 0 ; 1=read speed from wOptions; 0=always 1 frame/char
BIT_TEXT_DELAY equ 1 ; 1=delay enabled; TextCommandProcessor sets this per session
; wStatusFlags5 bit for text delay suppression
BIT_NO_TEXT_DELAY equ 6 ; 1=skip all per-char delay (cutscenes, auto-scroll)
; wOptions text speed values (pret ref: constants/ram_constants.asm TEXT_DELAY_*)
TEXT_DELAY_FAST equ 1 ; 1 frame per character
TEXT_DELAY_MEDIUM equ 3 ; 3 frames per character (default)
TEXT_DELAY_SLOW equ 5 ; 5 frames per character
TEXT_DELAY_MASK equ 0x0F ; bits 3-0 of wOptions hold text speed
; Current map identity
W_CUR_MAP equ 0xD35D ; wCurMap (1 byte)
W_CURRENT_TILE_BLOCK_MAP_VIEW_PTR equ 0xD35E ; wCurrentTileBlockMapViewPointer (2 bytes)

View File

@@ -138,6 +138,11 @@ Init:
call ClearSprites
mov byte [ebp + IO_LCDC], LCDC_DEFAULT_VAL
; Default text options (pret ref: engine/menus/main_menu.asm:InitOptions).
; OPTIONS menu not yet implemented; speed stays at MEDIUM until it is.
mov byte [ebp + W_LETTER_PRINTING_DELAY], (1 << BIT_FAST_TEXT_DELAY)
mov byte [ebp + W_OPTIONS], TEXT_DELAY_MEDIUM
%ifdef SKIP_TITLE
jmp EnterMap ; test build: skip title screen, go straight to overworld
%else

View File

@@ -246,10 +246,45 @@ TextBoxBorder:
ret
; ---------------------------------------------------------------------------
; PrintLetterDelay — stub. Original delays per-character for text animation.
; Phase 2: prints instantly.
; PrintLetterDelay — wait per-character delay based on the text speed setting.
; Pret ref: home/print_text.asm:PrintLetterDelay.
;
; Reads delay frame count from wOptions bits 3-0 (TEXT_DELAY_FAST/MEDIUM/SLOW = 1/3/5).
; Exits early if A or B is held. No-op if BIT_TEXT_DELAY is not set in
; wLetterPrintingDelayFlags (TextCommandProcessor sets it) or if BIT_NO_TEXT_DELAY
; is set in wStatusFlags5 (cutscenes, auto-scroll).
; All registers preserved.
; ---------------------------------------------------------------------------
PrintLetterDelay:
push eax
push ecx
movzx eax, byte [ebp + W_STATUS_FLAGS_5]
test al, (1 << BIT_NO_TEXT_DELAY) ; cutscene/auto-scroll: skip delay
jnz .done
movzx eax, byte [ebp + W_LETTER_PRINTING_DELAY]
test al, (1 << BIT_TEXT_DELAY) ; delay enabled by TextCommandProcessor?
jz .done
movzx ecx, byte [ebp + H_JOY_HELD]
test cl, PAD_A | PAD_B
jnz .one_frame ; button held: skip to one-frame exit
test al, (1 << BIT_FAST_TEXT_DELAY) ; use wOptions speed or fixed 1-frame?
jz .one_frame
movzx ecx, byte [ebp + W_OPTIONS]
and cl, TEXT_DELAY_MASK ; isolate speed bits (1, 3, or 5)
jz .done ; speed 0: instant (not used in practice)
jmp .count_down
.one_frame:
mov cl, 1
.count_down:
call DelayFrame ; renders frame + updates H_JOY_HELD
movzx eax, byte [ebp + H_JOY_HELD]
test al, PAD_A | PAD_B
jnz .done ; button held: abort remaining delay
dec cl
jnz .count_down
.done:
pop ecx
pop eax
ret
; ---------------------------------------------------------------------------
@@ -640,6 +675,13 @@ TextCommandProcessor:
push eax
push ecx
push edx
; Pret ref: home/text.asm:TextCommandProcessor — save delay flags, enable delay.
; PrintLetterDelay gates on BIT_TEXT_DELAY; TextCommandProcessor sets it for the
; duration of this text session and restores the original value at TX_END.
movzx eax, byte [ebp + W_LETTER_PRINTING_DELAY]
push eax ; save original wLetterPrintingDelayFlags
or al, (1 << BIT_TEXT_DELAY)
mov [ebp + W_LETTER_PRINTING_DELAY], al
.next_cmd:
movzx eax, byte [ebp + esi]
@@ -687,6 +729,8 @@ TextCommandProcessor:
jmp .next_cmd ; unknown command: skip
.done:
pop eax
mov [ebp + W_LETTER_PRINTING_DELAY], al ; restore saved wLetterPrintingDelayFlags
pop edx
pop ecx
pop eax