Updated text renderer a bit

This commit is contained in:
Jonatan Nilsson 2019-06-19 15:07:02 +00:00
parent 8a6794b54e
commit c20a27f02e
10 changed files with 177 additions and 117 deletions

Binary file not shown.

BIN
assets/page1_backup.chr Normal file

Binary file not shown.

View file

@ -3,11 +3,6 @@ INCLUDE "game/text.asm"
SECTION "Game Loop", ROM0 SECTION "Game Loop", ROM0
GameLoop: GameLoop:
.wait
ld a, [rLY] ; Load the current vertical line being rendered
cp 144 ; Check if we're past VBlank (1 to 144 = carry bit set)
jr c, .wait ; Jump back to waitVBlank if rLY is less than 144
ld de, HelloWorldStr ld de, HelloWorldStr
call StartText call StartText
.mainloop .mainloop
@ -19,4 +14,6 @@ GameLoop:
Section "Hello wrold string", ROM0 Section "Hello wrold string", ROM0
HelloWorldStr: HelloWorldStr:
db "Hello, Worl'd.!?", 0 ; [ ]
db "...wake up...\n"
db "please wake up...", 0

View file

@ -9,24 +9,62 @@ textwriter_active: ds 1
SECTION "ram_textmap", ROM0,ALIGN[8] SECTION "ram_textmap", ROM0,ALIGN[8]
textwriter_map: textwriter_map:
; 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ; 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 db $50,$50,$50,$50,$50,$50,$50,$50,$50,$50,$50,$50,$50,$50,$50,$50 ; 0
; 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F ; 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 db $50,$50,$50,$50,$50,$50,$50,$50,$50,$50,$50,$50,$50,$50,$50,$50 ; 16
; 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F ; 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 db $50,$41,$50,$50,$50,$50,$50,$43,$50,$50,$50,$50,$42,$50,$3F,$50 ; 32
; 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F ; 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 db $35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$50,$50,$50,$50,$50,$40 ; 48
; 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F ; 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 db $50,$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 ; 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 db $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1A,$50,$50,$50,$50,$50 ; 80
; 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F ; 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 db $50,$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 ; 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 db $2A,$2B,$2C,$2D,$2E,$2F,$30,$31,$32,$33,$34,$50,$50,$50,$50,$50 ; 112
SECTION "TextWriter", ROM0 SECTION "TextWriter", ROM0
InitWindow:
; Fill first line in window with straight line
ld hl, _SCRN1
ld b, $20
ld a, $52
call Memfill
; Fill rest of the area with dark bg
ld b, $40
ld a, $50
call Memfill
; Fill last line in window with straight line
ld b, $20
ld a, $57
call Memfill
; Top left corner
ld hl, _SCRN1
ld [hl], $51
; Top right corner
ld hl, _SCRN1 + 19
ld [hl], $53
; Bottom Left corner
ld hl, _SCRN1 + $60
ld [hl], $56
; Bottom Right corner
ld hl, _SCRN1 + $60 + 19
ld [hl], $58
; Left line
ld hl, _SCRN1 + $20
ld [hl], $54
ld hl, _SCRN1 + $40
ld [hl], $54
; Right line
ld hl, _SCRN1 + $20 + 19
ld [hl], $55
ld hl, _SCRN1 + $40 + 19
ld [hl], $55
ret ; Return
; Start to print a string on screen ; Start to print a string on screen
; @param b - PosX on where to draw text ; @param b - PosX on where to draw text
; @param c - PosY on where to draw text ; @param c - PosY on where to draw text
@ -57,19 +95,20 @@ StartText:
DrawActiveText: DrawActiveText:
ld a, [textwriter_active] ; Check if text is currently active ld a, [textwriter_active] ; Check if text is currently active
and a and a
jr z, .exit jp z, .exit
; Delay writing a letter by 10 frames ; Delay writing a letter by 10 frames
ld a, [textwriter_curdelay] ld a, [textwriter_curdelay]
inc a inc a
ld [textwriter_curdelay], a ld [textwriter_curdelay], a
cp 20 cp 10
jr c, .exit jr c, .exit
; Reset the curdelay ; Reset the curdelay
ld a, 0 ld a, 0
ld [textwriter_curdelay], a ld [textwriter_curdelay], a
.startdrawtext
; Get the memory address pointing to the text currently being ; Get the memory address pointing to the text currently being
; displayed. This is stored in textwriter_curtext ; displayed. This is stored in textwriter_curtext
ld hl, textwriter_curtext ; Get the memory address of the pointer ld hl, textwriter_curtext ; Get the memory address of the pointer
@ -78,7 +117,7 @@ DrawActiveText:
ld e, [hl] ; Store the next byte address to e ld e, [hl] ; Store the next byte address to e
; We now have the current letter being drawn at [de] ; We now have the current letter being drawn at [de]
ld hl, _SCRN0 ; Load the top-left map position to our map ld hl, _SCRN1 ; Load the top-left map position to our map
ld a, [textwriter_posy] ld a, [textwriter_posy]
ld c, a ld c, a
ld a, [textwriter_posx] ld a, [textwriter_posx]
@ -108,22 +147,54 @@ DrawActiveText:
jr .movexaxis ; Repeat jr .movexaxis ; Repeat
.drawletter .drawletter
ld a, [de] ; Load the first byte in the string ld a, [de] ; Load the first byte in the string
ld bc, textwriter_map ld bc, textwriter_map ; Get the map for the ASCII->Tile map
ld c, a ld c, a ; Set the position of C to the ASCII byte of current character
ld a, [bc] ld a, [bc] ; Get the tile byte for the ASCII from the map
ld [hl], a ; Print the character byte directly onto the map ld [hl], a ; Print the byte to the map
ld a, [de] ld a, [de]
and a ; Check if we reached the end and a ; Check if we reached the end
jr nz, .continue jr nz, .checkNewline
; We have reached the end of the string, disable textwriter ; We have reached the end of the string, disable textwriter
ld b, 0 ; Disable repeater
ld a, 0 ld a, 0
ld [textwriter_active], a ld [textwriter_active], a
jr .continue ; Jump straight to continue. No need to check anything
.checkNewline
ld a, [de] ; Regrab the ascii byte we printed
cp a, $0A ; Check if it was a new line
jr nz, .checkRepeatOnce ; Jump to checkRepeatOnce if it wasn't a new line
; The byte we printed was a new line so we increment Y position
; and reset our X position.
ld a, 0 ; Usually we'd print into first position but since we're jumping
; into continue, continue will automatically increment x for us.
ld [textwriter_posx], a
ld a, [textwriter_posy]
inc a
ld [textwriter_posy], a
; We already know we printed empty character so we can skip checking
; if we need to repeat once again and just set the b flag
ld b, 1
jr .continue
.checkRepeatOnce
ld a, [bc] ; Regrab the tile we printer
ld b, 0 ; Use b as our marker if we should repeat once
; Check if we printed an empty letter
cp a, $50
jr nz, .continue
ld b, 1
.continue .continue
; Time to update our work ram ; Time to update our work ram
; Load the position pointer of current text to next letter inc de ; Increment de to next letter
; Load the position pointer of current text and update it to the next letter
ld hl, textwriter_curtext ld hl, textwriter_curtext
inc de ; Increment to next letter in string
ld a, d ld a, d
ld [hli], a ld [hli], a
ld a, e ld a, e
@ -135,56 +206,15 @@ DrawActiveText:
; Update the current letter being drawn in ram ; Update the current letter being drawn in ram
ld a, [textwriter_curletter] ld a, [textwriter_curletter]
inc a inc a
; Check if we need to repeat whole thing due to printing empty character
ld a, b
and b
jr nz, .startdrawtext
; We didn't print an empty
ld [textwriter_curletter], a ld [textwriter_curletter], a
.exit .exit
ld a, [textwriter_active] ld a, [textwriter_active]
ret 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

View file

@ -59,11 +59,26 @@ Start:
ld [rNR52], a ; Turn off sound ld [rNR52], a ; Turn off sound
ld a, 7
ld [rWX], a
ld a, (SCRN_Y - 32)
ld [rWY], a
; Reset OAM memory with zeros
ld hl, _OAMRAM ; Set position of OAM Ram to hl
ld a, 0 ; Fill that memory space with zero
ld b, $FEA0 - _OAMRAM ; Get the full size of the fill
call Memfill
; Initialize other stuff
call InitWindow
; Turn the screen on, display background ; Turn the screen on, display background
ld a, LCDCF_ON|LCDCF_BGON ld a, LCDCF_ON|LCDCF_BGON|LCDCF_WINON|LCDCF_WIN9C00
; ld a, %10000001 ; screen on = 8th bit, background display = 1st bit
ld [rLCDC], a ; Set the screen flags ld [rLCDC], a ; Set the screen flags
ei ; Enable interrupts again?
call WaitVBlank
jp GameLoop jp GameLoop
SECTION "Font", ROM0 SECTION "Font", ROM0

BIN
main.o

Binary file not shown.

BIN
test.gb

Binary file not shown.

View file

@ -1,39 +1,40 @@
ROM Bank #0 (HOME): ROM Bank #0 (HOME):
SECTION: $0200-$027F ($0080 bytes) ["ram_textmap"] SECTION: $0200-$027F ($0080 bytes) ["ram_textmap"]
$0200 = textwriter_map $0200 = textwriter_map
SECTION: $0150-$01F5 ($00A6 bytes) ["TextWriter"] SECTION: $1280-$136B ($00EC bytes) ["TextWriter"]
$01D0 = DrawActiveText.exit $1368 = DrawActiveText.exit
$01A2 = DrawActiveText.movexaxis $1314 = DrawActiveText.movexaxis
$0193 = DrawActiveText.moveyaxis $1305 = DrawActiveText.moveyaxis
$01AA = DrawActiveText.drawletter $131C = DrawActiveText.drawletter
$01BA = DrawActiveText.continue $1330 = DrawActiveText.checkNewline
$01E6 = PrintString.movexaxis2 $134E = DrawActiveText.continue
$01D7 = PrintString.moveyaxis2 $1345 = DrawActiveText.checkRepeatOnce
$01EE = PrintString.start2 $12F4 = DrawActiveText.startdrawtext
$0150 = StartText $12C1 = StartText
$016C = DrawActiveText $12DD = DrawActiveText
SECTION: $0061-$0074 ($0014 bytes) ["Game Loop"] $1280 = InitWindow
$0061 = GameLoop.wait SECTION: $0031-$003E ($000E bytes) ["Game Loop"]
$006D = GameLoop.mainloop $0037 = GameLoop.mainloop
$0061 = GameLoop $0031 = GameLoop
SECTION: $0075-$0085 ($0011 bytes) ["Hello wrold string"] SECTION: $0000-$001F ($0020 bytes) ["Hello wrold string"]
$0075 = HelloWorldStr $0000 = HelloWorldStr
SECTION: $0031-$003C ($000C bytes) ["Tools"] SECTION: $0020-$0030 ($0011 bytes) ["Tools"]
$003A = WaitVBlank $0029 = Memfill
$0031 = Memcpy $002E = WaitVBlank
$0020 = Memcpy
$0029 = Memfill.repeatFill
SECTION: $0040-$0040 ($0001 bytes) ["InterruptVblank"] SECTION: $0040-$0040 ($0001 bytes) ["InterruptVblank"]
SECTION: $0048-$0048 ($0001 bytes) ["InterruptLCDC"] SECTION: $0048-$0048 ($0001 bytes) ["InterruptLCDC"]
SECTION: $0050-$0050 ($0001 bytes) ["InterruptTimer_Overflow"] SECTION: $0050-$0050 ($0001 bytes) ["InterruptTimer_Overflow"]
SECTION: $0058-$0058 ($0001 bytes) ["InterruptSerial"] SECTION: $0058-$0058 ($0001 bytes) ["InterruptSerial"]
SECTION: $0060-$0060 ($0001 bytes) ["Interruptp1thru4"] SECTION: $0060-$0060 ($0001 bytes) ["Interruptp1thru4"]
SECTION: $0100-$014F ($0050 bytes) ["Header"] SECTION: $0100-$014F ($0050 bytes) ["Header"]
SECTION: $0000-$0030 ($0031 bytes) ["Intro code"] SECTION: $0061-$00A1 ($0041 bytes) ["Intro code"]
$0000 = Start $0061 = Start
$0000 = Start.waitVBlank
SECTION: $0280-$127F ($1000 bytes) ["Font"] SECTION: $0280-$127F ($1000 bytes) ["Font"]
$0280 = Page1 $0280 = Page1
$1280 = Page1End $1280 = Page1End
SLACK: $2E23 bytes SLACK: $2DBF bytes
WRAM Bank #0: WRAM Bank #0:
SECTION: $C000-$C006 ($0007 bytes) ["ram_textwriter"] SECTION: $C000-$C006 ($0007 bytes) ["ram_textwriter"]

View file

@ -1,24 +1,25 @@
; File generated by rgblink ; File generated by rgblink
00:0200 textwriter_map 00:0200 textwriter_map
00:01D0 DrawActiveText.exit 00:1368 DrawActiveText.exit
00:01A2 DrawActiveText.movexaxis 00:1314 DrawActiveText.movexaxis
00:0193 DrawActiveText.moveyaxis 00:1305 DrawActiveText.moveyaxis
00:01AA DrawActiveText.drawletter 00:131C DrawActiveText.drawletter
00:01BA DrawActiveText.continue 00:1330 DrawActiveText.checkNewline
00:01E6 PrintString.movexaxis2 00:134E DrawActiveText.continue
00:01D7 PrintString.moveyaxis2 00:1345 DrawActiveText.checkRepeatOnce
00:01EE PrintString.start2 00:12F4 DrawActiveText.startdrawtext
00:0150 StartText 00:12C1 StartText
00:016C DrawActiveText 00:12DD DrawActiveText
00:0061 GameLoop.wait 00:1280 InitWindow
00:006D GameLoop.mainloop 00:0037 GameLoop.mainloop
00:0061 GameLoop 00:0031 GameLoop
00:0075 HelloWorldStr 00:0000 HelloWorldStr
00:003A WaitVBlank 00:0029 Memfill
00:0031 Memcpy 00:002E WaitVBlank
00:0000 Start 00:0020 Memcpy
00:0000 Start.waitVBlank 00:0029 Memfill.repeatFill
00:0061 Start
00:0280 Page1 00:0280 Page1
00:1280 Page1End 00:1280 Page1End
00:C002 textwriter_curletter 00:C002 textwriter_curletter

View file

@ -18,6 +18,22 @@ Memcpy:
jr nz, Memcpy ; Loop back to Memcpy if not zero jr nz, Memcpy ; Loop back to Memcpy if not zero
ret ret
Memfill:
; Fill an area in memory at position hl with value a for b amount of times
;
; @param hl - Starting address in memory to fill
; @param a - The value to fill said address space with
; @param b - How many bytes we should fill starting from said address space
; @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
.repeatFill
ld [hli], a
dec b
jr nz, .repeatFill
ret
;; ;;
; Waits for the vblank ISR to increment the count of vertical blanks. ; Waits for the vblank ISR to increment the count of vertical blanks.