diff --git a/assets/page1.chr b/assets/page1.chr index bdd1250..b98abcd 100644 Binary files a/assets/page1.chr and b/assets/page1.chr differ diff --git a/assets/page1_backup.chr b/assets/page1_backup.chr new file mode 100644 index 0000000..cb162dc Binary files /dev/null and b/assets/page1_backup.chr differ diff --git a/game/game.asm b/game/game.asm index 396c851..4263bf9 100644 --- a/game/game.asm +++ b/game/game.asm @@ -3,11 +3,6 @@ INCLUDE "game/text.asm" SECTION "Game Loop", ROM0 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 call StartText .mainloop @@ -19,4 +14,6 @@ GameLoop: Section "Hello wrold string", ROM0 HelloWorldStr: - db "Hello, Worl'd.!?", 0 + ; [ ] + db "...wake up...\n" + db "please wake up...", 0 diff --git a/game/text.asm b/game/text.asm index 25fde2b..dde4276 100644 --- a/game/text.asm +++ b/game/text.asm @@ -9,24 +9,62 @@ 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 + 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 +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 ; @param b - PosX on where to draw text ; @param c - PosY on where to draw text @@ -57,19 +95,20 @@ StartText: DrawActiveText: ld a, [textwriter_active] ; Check if text is currently active and a - jr z, .exit + jp z, .exit ; Delay writing a letter by 10 frames ld a, [textwriter_curdelay] inc a ld [textwriter_curdelay], a - cp 20 + cp 10 jr c, .exit ; Reset the curdelay ld a, 0 ld [textwriter_curdelay], a +.startdrawtext ; 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 @@ -78,7 +117,7 @@ DrawActiveText: 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 hl, _SCRN1 ; Load the top-left map position to our map ld a, [textwriter_posy] ld c, a ld a, [textwriter_posx] @@ -108,22 +147,54 @@ DrawActiveText: 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 bc, textwriter_map ; Get the map for the ASCII->Tile map + ld c, a ; Set the position of C to the ASCII byte of current character + ld a, [bc] ; Get the tile byte for the ASCII from the map + ld [hl], a ; Print the byte to the map ld a, [de] and a ; Check if we reached the end - jr nz, .continue + jr nz, .checkNewline + ; We have reached the end of the string, disable textwriter + ld b, 0 ; Disable repeater ld a, 0 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 ; 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 - inc de ; Increment to next letter in string ld a, d ld [hli], a ld a, e @@ -135,56 +206,15 @@ DrawActiveText: ; Update the current letter being drawn in ram ld a, [textwriter_curletter] 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 .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 - - diff --git a/main.asm b/main.asm index cab609e..663700a 100644 --- a/main.asm +++ b/main.asm @@ -59,11 +59,26 @@ Start: 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 - ld a, LCDCF_ON|LCDCF_BGON - ; ld a, %10000001 ; screen on = 8th bit, background display = 1st bit + ld a, LCDCF_ON|LCDCF_BGON|LCDCF_WINON|LCDCF_WIN9C00 ld [rLCDC], a ; Set the screen flags - ei ; Enable interrupts again? + + call WaitVBlank + jp GameLoop SECTION "Font", ROM0 diff --git a/main.o b/main.o index d1a1e9a..ab626f6 100644 Binary files a/main.o and b/main.o differ diff --git a/test.gb b/test.gb index 4fc280d..5725dee 100644 Binary files a/test.gb and b/test.gb differ diff --git a/test.map b/test.map index 26c0b98..1956e39 100644 --- a/test.map +++ b/test.map @@ -1,39 +1,40 @@ ROM Bank #0 (HOME): SECTION: $0200-$027F ($0080 bytes) ["ram_textmap"] $0200 = textwriter_map - SECTION: $0150-$01F5 ($00A6 bytes) ["TextWriter"] - $01D0 = DrawActiveText.exit - $01A2 = DrawActiveText.movexaxis - $0193 = DrawActiveText.moveyaxis - $01AA = DrawActiveText.drawletter - $01BA = DrawActiveText.continue - $01E6 = PrintString.movexaxis2 - $01D7 = PrintString.moveyaxis2 - $01EE = PrintString.start2 - $0150 = StartText - $016C = DrawActiveText - SECTION: $0061-$0074 ($0014 bytes) ["Game Loop"] - $0061 = GameLoop.wait - $006D = GameLoop.mainloop - $0061 = GameLoop - SECTION: $0075-$0085 ($0011 bytes) ["Hello wrold string"] - $0075 = HelloWorldStr - SECTION: $0031-$003C ($000C bytes) ["Tools"] - $003A = WaitVBlank - $0031 = Memcpy + SECTION: $1280-$136B ($00EC bytes) ["TextWriter"] + $1368 = DrawActiveText.exit + $1314 = DrawActiveText.movexaxis + $1305 = DrawActiveText.moveyaxis + $131C = DrawActiveText.drawletter + $1330 = DrawActiveText.checkNewline + $134E = DrawActiveText.continue + $1345 = DrawActiveText.checkRepeatOnce + $12F4 = DrawActiveText.startdrawtext + $12C1 = StartText + $12DD = DrawActiveText + $1280 = InitWindow + SECTION: $0031-$003E ($000E bytes) ["Game Loop"] + $0037 = GameLoop.mainloop + $0031 = GameLoop + SECTION: $0000-$001F ($0020 bytes) ["Hello wrold string"] + $0000 = HelloWorldStr + SECTION: $0020-$0030 ($0011 bytes) ["Tools"] + $0029 = Memfill + $002E = WaitVBlank + $0020 = Memcpy + $0029 = Memfill.repeatFill SECTION: $0040-$0040 ($0001 bytes) ["InterruptVblank"] SECTION: $0048-$0048 ($0001 bytes) ["InterruptLCDC"] SECTION: $0050-$0050 ($0001 bytes) ["InterruptTimer_Overflow"] SECTION: $0058-$0058 ($0001 bytes) ["InterruptSerial"] SECTION: $0060-$0060 ($0001 bytes) ["Interruptp1thru4"] SECTION: $0100-$014F ($0050 bytes) ["Header"] - SECTION: $0000-$0030 ($0031 bytes) ["Intro code"] - $0000 = Start - $0000 = Start.waitVBlank + SECTION: $0061-$00A1 ($0041 bytes) ["Intro code"] + $0061 = Start SECTION: $0280-$127F ($1000 bytes) ["Font"] $0280 = Page1 $1280 = Page1End - SLACK: $2E23 bytes + SLACK: $2DBF bytes WRAM Bank #0: SECTION: $C000-$C006 ($0007 bytes) ["ram_textwriter"] diff --git a/test.sym b/test.sym index 9646501..41425ae 100644 --- a/test.sym +++ b/test.sym @@ -1,24 +1,25 @@ ; File generated by rgblink 00:0200 textwriter_map -00:01D0 DrawActiveText.exit -00:01A2 DrawActiveText.movexaxis -00:0193 DrawActiveText.moveyaxis -00:01AA DrawActiveText.drawletter -00:01BA DrawActiveText.continue -00:01E6 PrintString.movexaxis2 -00:01D7 PrintString.moveyaxis2 -00:01EE PrintString.start2 -00:0150 StartText -00:016C DrawActiveText -00:0061 GameLoop.wait -00:006D GameLoop.mainloop -00:0061 GameLoop -00:0075 HelloWorldStr -00:003A WaitVBlank -00:0031 Memcpy -00:0000 Start -00:0000 Start.waitVBlank +00:1368 DrawActiveText.exit +00:1314 DrawActiveText.movexaxis +00:1305 DrawActiveText.moveyaxis +00:131C DrawActiveText.drawletter +00:1330 DrawActiveText.checkNewline +00:134E DrawActiveText.continue +00:1345 DrawActiveText.checkRepeatOnce +00:12F4 DrawActiveText.startdrawtext +00:12C1 StartText +00:12DD DrawActiveText +00:1280 InitWindow +00:0037 GameLoop.mainloop +00:0031 GameLoop +00:0000 HelloWorldStr +00:0029 Memfill +00:002E WaitVBlank +00:0020 Memcpy +00:0029 Memfill.repeatFill +00:0061 Start 00:0280 Page1 00:1280 Page1End 00:C002 textwriter_curletter diff --git a/tools.asm b/tools.asm index 0a8438b..b0017be 100644 --- a/tools.asm +++ b/tools.asm @@ -18,6 +18,22 @@ Memcpy: jr nz, Memcpy ; Loop back to Memcpy if not zero 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.