summaryrefslogtreecommitdiff
path: root/src/home/text_box.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/home/text_box.asm')
-rw-r--r--src/home/text_box.asm335
1 files changed, 335 insertions, 0 deletions
diff --git a/src/home/text_box.asm b/src/home/text_box.asm
new file mode 100644
index 0000000..3d3414c
--- /dev/null
+++ b/src/home/text_box.asm
@@ -0,0 +1,335 @@
+
+; copy c bytes of data from de to hl
+; if LCD on, copy during h-blank only
+SafeCopyDataDEtoHL: ; 1dca (0:1dca)
+ ld a, [wLCDC] ;
+ bit LCDC_ENABLE_F, a ;
+ jr nz, .lcd_on ; assert that LCD is on
+.lcd_off_loop
+ ld a, [de]
+ inc de
+ ld [hli], a
+ dec c
+ jr nz, .lcd_off_loop
+ ret
+.lcd_on
+ jp HblankCopyDataDEtoHL
+
+; returns v*BGMap0 + BG_MAP_WIDTH * e + d in hl.
+; used to map coordinates at de to a BGMap0 address.
+DECoordToBGMap0Address: ; 1ddb (0:1ddb)
+ ld l, e
+ ld h, $0
+ add hl, hl
+ add hl, hl
+ add hl, hl
+ add hl, hl
+ add hl, hl
+ ld a, l
+ add d
+ ld l, a
+ ld a, h
+ adc HIGH(v0BGMap0)
+ ld h, a
+ ret
+
+; Apply SCX and SCY correction to xy coordinates at de
+AdjustCoordinatesForBGScroll: ; 1deb (0:1deb)
+ push af
+ ldh a, [hSCX]
+ rra
+ rra
+ rra
+ and $1f
+ add d
+ ld d, a
+ ldh a, [hSCY]
+ rra
+ rra
+ rra
+ and $1f
+ add e
+ ld e, a
+ pop af
+ ret
+
+; Draws a bxc text box at de printing a name in the left side of the top border.
+; The name's text id must be at hl when this function is called.
+; Mostly used to print text boxes for talked-to NPCs, but occasionally used in duels as well.
+DrawLabeledTextBox: ; 1e00 (0:1e00)
+ ld a, [wConsole]
+ cp CONSOLE_SGB
+ jr nz, .draw_textbox
+ ld a, [wTextBoxFrameType]
+ or a
+ jr z, .draw_textbox
+; Console is SGB and frame type is != 0.
+; The text box will be colorized so a SGB command needs to be sent as well
+ push de
+ push bc
+ call .draw_textbox
+ pop bc
+ pop de
+ jp ColorizeTextBoxSGB
+
+.draw_textbox
+ push de
+ push bc
+ push hl
+ ; top left tile of the box
+ ld hl, wc000
+ ld a, TX_SYMBOL
+ ld [hli], a
+ ld a, SYM_BOX_TOP_L
+ ld [hli], a
+ ; white tile before the text
+ ld a, FW_SPACE
+ ld [hli], a
+ ; text label
+ ld e, l
+ ld d, h
+ pop hl
+ call CopyText
+ ld hl, wc000 + 3
+ call GetTextLengthInTiles
+ ld l, e
+ ld h, d
+ ; white tile after the text
+ ld a, TX_HALF2FULL
+ ld [hli], a
+ ld a, FW_SPACE
+ ld [hli], a
+ pop de
+ push de
+ ld a, d
+ sub b
+ sub $4
+ jr z, .draw_top_border_right_tile
+ ld b, a
+.draw_top_border_line_loop
+ ld a, TX_SYMBOL
+ ld [hli], a
+ ld a, SYM_BOX_TOP
+ ld [hli], a
+ dec b
+ jr nz, .draw_top_border_line_loop
+
+.draw_top_border_right_tile
+ ld a, TX_SYMBOL
+ ld [hli], a
+ ld a, SYM_BOX_TOP_R
+ ld [hli], a
+ ld [hl], TX_END
+ pop bc
+ pop de
+ push de
+ push bc
+ call InitTextPrinting
+ ld hl, wc000
+ call ProcessText
+ pop bc
+ pop de
+ ld a, [wConsole]
+ cp CONSOLE_CGB
+ jr z, .cgb
+; DMG or SGB
+ inc e
+ call DECoordToBGMap0Address
+ ; top border done, draw the rest of the text box
+ jr ContinueDrawingTextBoxDMGorSGB
+
+.cgb
+ call DECoordToBGMap0Address
+ push de
+ call CopyCurrentLineAttrCGB ; BG Map attributes for current line, which is the top border
+ pop de
+ inc e
+ ; top border done, draw the rest of the text box
+ jp ContinueDrawingTextBoxCGB
+
+; Draws a bxc text box at de to print menu data in the overworld.
+; Also used to print a text box during a duel.
+; When talking to NPCs, DrawLabeledTextBox is used instead.
+DrawRegularTextBox: ; 1e7c (0:1e7c)
+ ld a, [wConsole]
+ cp CONSOLE_CGB
+ jr z, DrawRegularTextBoxCGB
+ cp CONSOLE_SGB
+ jp z, DrawRegularTextBoxSGB
+; fallthrough
+
+DrawRegularTextBoxDMG: ; 1e88 (0:1e88)
+ call DECoordToBGMap0Address
+ ; top line (border) of the text box
+ ld a, SYM_BOX_TOP
+ lb de, SYM_BOX_TOP_L, SYM_BOX_TOP_R
+ call CopyLine
+; fallthrough
+
+; continue drawing a labeled or regular textbox on DMG or SGB:
+; body and bottom line of either type of textbox
+ContinueDrawingTextBoxDMGorSGB: ; 1e93 (0:1e93)
+ dec c
+ dec c
+.draw_text_box_body_loop
+ ld a, SYM_SPACE
+ lb de, SYM_BOX_LEFT, SYM_BOX_RIGHT
+ call CopyLine
+ dec c
+ jr nz, .draw_text_box_body_loop
+ ; bottom line (border) of the text box
+ ld a, SYM_BOX_BOTTOM
+ lb de, SYM_BOX_BTM_L, SYM_BOX_BTM_R
+; fallthrough
+
+; copies b bytes of data to sp-$1f and to hl, and returns hl += BG_MAP_WIDTH
+; d = value of byte 0
+; e = value of byte b
+; a = value of bytes [1, b-1]
+; b is supposed to be BG_MAP_WIDTH or smaller, else the stack would get corrupted
+CopyLine: ; 1ea5 (0:1ea5)
+ add sp, -BG_MAP_WIDTH
+ push hl
+ push bc
+ ld hl, sp+$4
+ dec b
+ dec b
+ push hl
+ ld [hl], d
+ inc hl
+.loop
+ ld [hli], a
+ dec b
+ jr nz, .loop
+ ld [hl], e
+ pop de
+ pop bc
+ pop hl
+ push hl
+ push bc
+ ld c, b
+ ld b, $0
+ call SafeCopyDataDEtoHL
+ pop bc
+ pop de
+ ; advance pointer BG_MAP_WIDTH positions and restore stack pointer
+ ld hl, BG_MAP_WIDTH
+ add hl, de
+ add sp, BG_MAP_WIDTH
+ ret
+
+; DrawRegularTextBox branches here on CGB console
+DrawRegularTextBoxCGB: ; 1ec9 (0:1ec9)
+ call DECoordToBGMap0Address
+ ; top line (border) of the text box
+ ld a, SYM_BOX_TOP
+ lb de, SYM_BOX_TOP_L, SYM_BOX_TOP_R
+ call CopyCurrentLineTilesAndAttrCGB
+; fallthrough
+
+; continue drawing a labeled or regular textbox on CGB:
+; body and bottom line of either type of textbox
+ContinueDrawingTextBoxCGB: ; 1ed4 (0:1ed4)
+ dec c
+ dec c
+.draw_text_box_body_loop
+ ld a, SYM_SPACE
+ lb de, SYM_BOX_LEFT, SYM_BOX_RIGHT
+ push hl
+ call CopyLine
+ pop hl
+ call BankswitchVRAM1
+ ld a, [wTextBoxFrameType] ; on CGB, wTextBoxFrameType determines the palette and the other attributes
+ ld e, a
+ ld d, a
+ xor a
+ call CopyLine
+ call BankswitchVRAM0
+ dec c
+ jr nz, .draw_text_box_body_loop
+ ; bottom line (border) of the text box
+ ld a, SYM_BOX_BOTTOM
+ lb de, SYM_BOX_BTM_L, SYM_BOX_BTM_R
+ call CopyCurrentLineTilesAndAttrCGB
+ ret
+
+; d = id of top left tile
+; e = id of top right tile
+; a = id of rest of tiles
+; Assumes b = SCREEN_WIDTH and that VRAM bank 0 is loaded
+CopyCurrentLineTilesAndAttrCGB: ; 1efb (0:1efb)
+ push hl
+ call CopyLine
+ pop hl
+; fallthrough
+
+CopyCurrentLineAttrCGB: ; 1f00 (0:1f00)
+ call BankswitchVRAM1
+ ld a, [wTextBoxFrameType] ; on CGB, wTextBoxFrameType determines the palette and the other attributes
+ ld e, a
+ ld d, a
+ call CopyLine
+ call BankswitchVRAM0
+ ret
+
+; DrawRegularTextBox branches here on SGB console
+DrawRegularTextBoxSGB: ; 1f0f (0:1f0f)
+ push bc
+ push de
+ call DrawRegularTextBoxDMG
+ pop de
+ pop bc
+ ld a, [wTextBoxFrameType]
+ or a
+ ret z
+; fallthrough
+
+ColorizeTextBoxSGB: ; 1f1b (0:1f1b)
+ push bc
+ push de
+ ld hl, wTempSGBPacket
+ ld de, AttrBlkPacket_TextBox
+ ld c, SGB_PACKET_SIZE
+.copy_sgb_command_loop
+ ld a, [de]
+ inc de
+ ld [hli], a
+ dec c
+ jr nz, .copy_sgb_command_loop
+ pop de
+ pop bc
+ ld hl, wTempSGBPacket + 4
+ ; set X1, Y1 to d, e
+ ld [hl], d
+ inc hl
+ ld [hl], e
+ inc hl
+ ; set X2, Y2 to d+b-1, e+c-1
+ ld a, d
+ add b
+ dec a
+ ld [hli], a
+ ld a, e
+ add c
+ dec a
+ ld [hli], a
+ ld a, [wTextBoxFrameType]
+ and $80
+ jr z, .send_packet
+ ; reset ATTR_BLK_CTRL_INSIDE if bit 7 of wTextBoxFrameType is set.
+ ; appears to be irrelevant, as the inside of a textbox uses the white color,
+ ; which is the same in all four SGB palettes.
+ ld a, ATTR_BLK_CTRL_LINE
+ ld [wTempSGBPacket + 2], a
+.send_packet
+ ld hl, wTempSGBPacket
+ call SendSGB
+ ret
+
+AttrBlkPacket_TextBox: ; 1f4f (0:1f4f)
+ sgb ATTR_BLK, 1 ; sgb_command, length
+ db 1 ; number of data sets
+ ; Control Code, Color Palette Designation, X1, Y1, X2, Y2
+ db ATTR_BLK_CTRL_INSIDE + ATTR_BLK_CTRL_LINE, 0 << 0 + 1 << 2, 0, 0, 0, 0 ; data set 1
+ ds 6 ; data set 2
+ ds 2 ; data set 3