Text windows
The text decoder in bank $C2 ($C2:57DF–$C2:6262) turns a string of bytes into glyphs drawn
pixel by pixel into a graphics buffer, a few characters per call. It is reached from other banks
through two fixed vectors, so the field and the scene mode share it. All of it is matched, its tables included.
See also: Scene engine, Field event scripts.
Calling it
Both entries work on a parameter block at $0200 (they set DP=$0200 themselves), which the
caller fills first: the string number and string table, the output buffer, the mode, and before
each step the number of characters to draw.
TextWin_Init($C2:57DF, throughBankC2_Entry0003) looks the string up in the table, sets state 0 and puts the pen at the left margin (or at 0 in some modes).TextWin_Step($C2:5823, throughBankC2_Entry0009) draws one step:TextWin_CheckStatusruns the handler of the current status (TextWin_StatusTable, statuses$00–$20), which says whether to go on; if so, the handler of the current state runs.
Two callers use it. In the scene mode, the label task (C2Scene_LabelWait, C2Scene_LabelDraw)
draws one character per frame. On the field, the message window step Field_Unk1F87 starts it
with Field_MsgStart ($C0:20F2: the string from the treasure string table at $DE:FF00 for a
treasure, else from the pointer Evt_OpB8_SetMsgPtr set; buffer $7E:F000, mode 0) and draws
one glyph a step with Field_MsgStep ($C0:2126), acting on the status each step leaves: a new
line, a new page, a timed wait, a wait ("for a press, probably") or the end. See
Field event scripts.
The string format
A string is a run of bytes at TextWin_TextPtr:
| Bytes | Meaning |
|---|---|
$A0–$FF |
A glyph, drawn by TextWin_DrawGlyph |
$21–$9F |
A dictionary entry (TextWin_DictPtrs, bank $DE): a sub-string of glyphs, drawn in state 1 |
$00–$20 |
A control code (TextWin_CodeTable, $C2:5903, 33 words) |
The hex digit table TextWin_HexGlyphs gives "0"–"9" as $D4–$DD and "A"–"F" as $A0–$A5,
so the banner reads $A0–$B9 as probably "A"–"Z" and $BA–$D3 as "a"–"z" (the names in ROM
read as words that way).
The control codes matched include:
$01,$02(TextWin_CodeWide): the next byte, with the code as its high byte, is a 16-bit glyph;$00and$04–$0C(TextWin_CodeSetStatus): setTextWin_Statusto the code, which ends the step (0 is idle, "probably the end"; 5–12 reset the pen);$03does the same after storing an argument byte;$0D,$0E,$0F(TextWin_CodeNum8/16/24): a number in decimal (3, 5 or 8 digits, leading zeros trimmed) or in hex, drawn in states 2 and 3;$11,$13–$1E,$20: names: the characters' names kept in bank$7E($13–$1A,$20, and$11with an argument), the party members by position ($1B–$1D,TextWin_CodeMemberName), and a fixed "Nadia" string ($1E,TextWin_CodeNadia);$12 $00/$12 $01(TextWin_ExtTechName,TextWin_ExtEnemyName): a tech or enemy name from the ROM name tables;$1F(TextWin_CodeItemName): the name of the item inTreasure_ItemId.
The states
| State | Handler | Draws |
|---|---|---|
| 0 | TextWin_State0 ($C2:58B2) |
Glyphs from the string; starts dictionary entries and control codes |
| 1 | TextWin_State1 ($C2:5BF5) |
A sub-string: a dictionary entry or a name |
| 2 | TextWin_State2 ($C2:5C3E) |
Number digits |
| 3 | TextWin_State3 ($C2:5C77) |
Number digits |
Each glyph drawn uses up one of TextWin_StepCount; when it runs out the step ends with
TextWin_StatusStepDone, and the next step goes on in the same state. Each of states 1–3 leaves
through a small exit table chosen by what is left of the sub-string and of the step.
Drawing a glyph
TextWin_DrawGlyph ($C2:5DC4) reads the glyph's 24 bytes from the font in bank $FF, shifts
them to the pen's pixel position within its 8-pixel tile column, and ORs them into the output
buffer: TextWin_Blit2bpp or TextWin_Blit4bpp by the mode, each with a table of eight shift
entry points. The pen then moves on by the glyph's width from TextWin_GlyphWidths (96 entries,
one per glyph $A0–$FF), so the font is proportional.
Numbers go through TextWin_Dec8, TextWin_Dec16 and TextWin_Dec24 ($C2:615E–$C2:6230),
which divide by powers of ten with shift-and-subtract loops (TextWin_DivBits,
TextWin_Div24Bits), and TextWin_HexByte for hex.
Quirks kept
TextWin_DrawGlyph indexes the width table with the glyph's low byte only, so a 16-bit glyph from
codes $01/$02 with a low byte under $A0 reads past the table. TextWin_StateTable's verified
header still calls its handlers unmatched; NEXT.md lists it as a stale header to fix at its
next edit.