diff options
Diffstat (limited to 'src/home/text_box.asm')
-rw-r--r-- | src/home/text_box.asm | 335 |
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 |