gameboy/game/text.asm

191 lines
6.7 KiB
NASM

SECTION "ram_textwriter", WRAM0
textwriter_curtext: ds 2
textwriter_curletter: ds 1
textwriter_posx: ds 1
textwriter_posy: ds 1
textwriter_curdelay: ds 1
textwriter_active: ds 1
SECTION "ram_textmap", ROM0,ALIGN[8]
textwriter_map:
; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 0
; 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 16
; 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
db $00,$41,$00,$00,$00,$00,$00,$43,$00,$00,$00,$00,$42,$00,$3F,$00 ; 32
; 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
db $35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$00,$00,$00,$00,$00,$40 ; 48
; 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
db $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0A,$0B,$0C,$0D,$0E,$0F ; 64
; 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
db $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1A,$00,$00,$00,$00,$00 ; 80
; 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
db $00,$1B,$1C,$1D,$1E,$1F,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29 ; 96
; 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
db $2A,$2B,$2C,$2D,$2E,$2F,$30,$31,$32,$33,$34,$00,$00,$00,$00,$00 ; 112
SECTION "TextWriter", ROM0
; Start to print a string on screen
; @param b - PosX on where to draw text
; @param c - PosY on where to draw text
; @param de - Address source string
; @return a - garbage
; @return b - PosX on where to draw text
; @return c - PosY on where to draw text
; @return hl - Workram position for text pointer
; @return de - Memory address to source string
StartText:
ld a, 0
ld [textwriter_curletter], a
ld [textwriter_curdelay], a
ld a, 1
ld [textwriter_active], a
ld [textwriter_posx], a
ld [textwriter_posy], a
ld hl, textwriter_curtext
ld a, d
ld [hli], a
ld a, e
ld [hl], a
dec hl
ret
; Draw text if one is currently active
; @return a - 0 if not active, 1 if active
DrawActiveText:
ld a, [textwriter_active] ; Check if text is currently active
and a
jr z, .exit
; Delay writing a letter by 10 frames
ld a, [textwriter_curdelay]
inc a
ld [textwriter_curdelay], a
cp 20
jr c, .exit
; Reset the curdelay
ld a, 0
ld [textwriter_curdelay], a
; Get the memory address pointing to the text currently being
; displayed. This is stored in textwriter_curtext
ld hl, textwriter_curtext ; Get the memory address of the pointer
ld d, [hl] ; Store the first byte address to d
inc hl ; Move to next byte
ld e, [hl] ; Store the next byte address to e
; We now have the current letter being drawn at [de]
ld hl, _SCRN0 ; Load the top-left map position to our map
ld a, [textwriter_posy]
ld c, a
ld a, [textwriter_posx]
ld b, a
.moveyaxis
; Our first objective is to position the text to correct position
; We do so shifting the position by $20 for each y axis
; and position by $01 for each x axis that needs movement
ld a, c ; Load the y position to our accumilator
and a ; Check if it's zero
jr z, .movexaxis ; Jump to x axis if it's zero and no moving necessary
ld a, l ; Load the first half of the destination position
add a, $20 ; Add $20 (one vertical line)
ld l, a ; Store the position back
ld a, h ; Grab the second part of the address
adc a, $00 ; Add only the accumilator
ld h, a ; Store the position back
dec c ; Decrement our y parameter
jr .moveyaxis ; Repeat
.movexaxis
; Now we check and move the position based on the x position
ld a, b ; Load the x position to our accimulator
and a ; Check if it's zero
jr z, .drawletter ; Jump to drawletter if it's zero already
inc hl ; Increment the map position by one since we need to move by x position
dec b ; Decrement our x parameter
jr .movexaxis ; Repeat
.drawletter
ld a, [de] ; Load the first byte in the string
ld bc, textwriter_map
ld c, a
ld a, [bc]
ld [hl], a ; Print the character byte directly onto the map
ld a, [de]
and a ; Check if we reached the end
jr nz, .continue
; We have reached the end of the string, disable textwriter
ld a, 0
ld [textwriter_active], a
.continue
; Time to update our work ram
; Load the position pointer of current text to next letter
ld hl, textwriter_curtext
inc de ; Increment to next letter in string
ld a, d
ld [hli], a
ld a, e
ld [hl], a
; Update the x position in ram
ld a, [textwriter_posx]
inc a
ld [textwriter_posx], a
; Update the current letter being drawn in ram
ld a, [textwriter_curletter]
inc a
ld [textwriter_curletter], a
.exit
ld a, [textwriter_active]
ret
; Print String on screen
; @param b - PosX on where to draw text
; @param c - PosY on where to draw text
; @param de - Address source string
; @return a
; @return b
; @return c
; @return hl - Destination memory in map
; @return hl = Address Target to the byte after the last byte on the target (garbage)
PrintString:
ld hl, _SCRN0 ; Load the top-left map position to our map
.moveyaxis2
; Our first objective is to position the text to correct position
; We do so shifting the position by $20 for each y axis
; and position by $01 for each x axis that needs movement
ld a, c ; Load the y position to our accumilator
and a ; Check if it's zero
jr z, .movexaxis2 ; Jump to x axis if it's zero and no moving necessary
ld a, l ; Load the first half of the destination position
add a, $20 ; Add $20 (one vertical line)
ld l, a ; Store the position back
ld a, b ; Grab the second part of the address
adc a, $00 ; Add only the accumilator
ld b, a ; Store the position back
dec c ; Decrement our y parameter
jr .moveyaxis2 ; Repeat
.movexaxis2
; Now we check and move the position based on the x position
ld a, b ; Load the x position to our accimulator
and a ; Check if it's zero
jr z, .start2 ; Jump to start2 if it's zero already
inc hl ; Increment the map position by one since we need to move by x position
dec b ; Decrement our x parameter
jr .movexaxis2 ; Repeat
.start2
ld a, [de] ; Load the first byte in the string
ld [hl], a ; Write the byte from the accumilator to the destination address
; Also increment destination by one.
; This effectively prints the character byte in accumilator
inc de ; Increment to next byte in string
inc hl
and a ; And together a with itself. This sets the flag
jr nz, .start2 ; Go back to start if we didn't just copy a zero.
ret