split totaltorender into linesleft and tilesleft, makes rendering code simpler and faster

This commit is contained in:
2018-12-30 16:02:03 +01:00
parent eb63517a49
commit 798e11c1d4

View File

@@ -74,16 +74,18 @@ Start:
ldh [Rendered], a ldh [Rendered], a
ldh [Video], a ldh [Video], a
; set total to render to 0 so that interrupts don't start rendering ; set lines and tiles left to 0 to avoid rendering in interrupts
ldh [TotalToRender], a ldh [LinesLeft], a
ldh [TotalToRender + 1], a ldh [TilesLeft], a
; enable v-blank interrupt ; enable v-blank interrupt
ld a, IEF_VBLANK ld a, IEF_VBLANK
ld [rIE], a ld [rIE], a
; enable interrupts ; enable interrupts while clearing interrupt flags
xor a
ei ei
ldh [rIF], a
; wait for v-blank ; wait for v-blank
halt halt
@@ -129,26 +131,28 @@ Start:
call MemoryCopy call MemoryCopy
; set total to render to start rendering ; set total to render to start rendering
ld a, LOW(20 * 18) ld a, 18
ldh [TotalToRender], a ldh [LinesLeft], a
ld a, HIGH(20 * 18) ld a, 20
ldh [TotalToRender + 1], a ldh [TilesLeft], a
; enable screen but don't display anything yet
ld a, LCDCF_ON
ld [rLCDC], a
; enable h-blank interrupt in lcd stat ; enable h-blank interrupt in lcd stat
ld a, STATF_MODE00 ld a, STATF_MODE00
ld [rSTAT], a ld [rSTAT], a
; enable screen but don't display anything yet
ld a, LCDCF_ON
ld [rLCDC], a
.mainloop .mainloop
; enable v-blank and lcd stat interrupt for h-blank ; enable v-blank and lcd stat interrupt for h-blank
di di
ld a, IEF_VBLANK; | IEF_LCDC ld a, IEF_VBLANK | IEF_LCDC
ld [rIE], a ld [rIE], a
xor a
ei ei
ldh [rIF], a
.topleft .topleft
; handle top left corner ; handle top left corner
@@ -288,28 +292,30 @@ Start:
inc [hl] inc [hl]
; wait end of rendering ; wait end of rendering
.waitRenderHigh .waitLines
; check high byte of TotalToRender ; check high byte of TotalToRender
ldh a, [TotalToRender + 1] ldh a, [LinesLeft]
or a or a
jr z, .waitRenderLow jr z, .waitTiles
halt halt
jr .waitRenderHigh jr .waitLines
.waitRenderLow .waitTiles
; check low byte of TotalToRender ; check low byte of TotalToRender
ldh a, [TotalToRender] ldh a, [TilesLeft]
or a or a
jr z, .swap jr z, .swap
halt halt
jr .waitRenderLow jr .waitTiles
.swap .swap
; enable only v-blank interrupt ; enable only v-blank interrupt
di di
ld a, IEF_VBLANK ld a, IEF_VBLANK
ld [rIE], a ld [rIE], a
xor a
ei ei
ldh [rIF], a
; wait v-blank ; wait v-blank
halt halt
@@ -365,11 +371,11 @@ Start:
ldh [Rendered], a ldh [Rendered], a
ldh [Video], a ldh [Video], a
; set total to render to start rendering ; set total to render to restart rendering
ld a, LOW(20 * 18) ld a, 20
ldh [TotalToRender], a ldh [TilesLeft], a
ld a, HIGH(20 * 18) ld a, 18
ldh [TotalToRender + 1], a ldh [LinesLeft], a
jp .mainloop jp .mainloop
@@ -555,60 +561,39 @@ Conway:
SECTION "V-Blank Interrupt Handler", ROM0[$40] SECTION "V-Blank Interrupt Handler", ROM0[$40]
VBlankInterruptHandler: VBlankInterruptHandler:
; save a ; save registers
push af push af
push de
; set max number of cells to render push bc
ld a, 64 push hl
ldh [MaxRender], a
; render ; render
jp Render jp Render
SECTION "LCD Stat Interrupt Handler", ROM0[$48] SECTION "LCD Stat Interrupt Handler", ROM0[$48]
LCDStatInterruptHandler: LCDStatInterruptHandler:
; save a ; save registers
push af push af
push de
; set max number of cells to render push bc
ld a, 1 push hl
ldh [MaxRender], a
; render ; render
jp Render jp Render
SECTION "Render", ROM0 SECTION "Render", ROM0
Render: Render:
; save registers ; check there are lines to render
push de ldh a, [LinesLeft]
push bc
push hl
; load counter into b
ldh a, [MaxRender]
ld b, a
; check there is more than 255 bytes to render left
ldh a, [TotalToRender + 1]
and a
jr nz, .render
; check there is anything at all to render
ldh a, [TotalToRender]
and a and a
jr z, .exit jr z, .exit
; check we're not trying to render more than what's left to render ; check there are tiles to render
cp a, b ldh a, [TilesLeft]
jr nc, .render and a
jr z, .exit
; render only what's left to
ld b, a
.render .render
; save render count so that we can decrement total later
push bc
; load buffer pointer into DE ; load buffer pointer into DE
ld hl, Rendered ld hl, Rendered
ld a, [hl+] ld a, [hl+]
@@ -621,22 +606,26 @@ Render:
ld h, [hl] ld h, [hl]
ld l, a ld l, a
; set c to number of tiles before next line ; set c to point to tiles left to render
ld a, l .nextline
and a, $E0 ld c, LOW(TilesLeft)
add a, 20
sub a, l
ld c, a
.loop .loop
; check we can still render
ldh a, [rSTAT]
and a, STATF_BUSY
jr nz, .finish
; copy one byte ; copy one byte
ld a, [de] ld a, [de]
ld [hl+], a ld [hl+], a
inc de inc de
; check if we need to go to next line ; loop while there are tiles to render
dec c ld a, [$FF00+c]
jr nz , .countdown dec a
ld [$FF00+c], a
jr nz, .loop
; go to next line ; go to next line
push de push de
@@ -645,12 +634,20 @@ Render:
pop de pop de
ld c, 20 ld c, 20
; loop over if not finished ; loop while there are lines to render
.countdown ld c, LOW(LinesLeft)
dec b ld a, [$FF00+c]
jr nz, .loop dec a
ld [$FF00+c], a
jr z, .finish
ld a, 20
ldh [TilesLeft], a
jr .nextline
; save incremented video and buffer pointers ; save incremented video and buffer pointers
.finish
ld a, l ld a, l
ldh [Video], a ldh [Video], a
ld a, h ld a, h
@@ -661,30 +658,16 @@ Render:
ld a, d ld a, d
ldh [Rendered + 1], a ldh [Rendered + 1], a
; restore max render
pop bc
; decrement total to render
ldh a, [TotalToRender]
sub a, b
ldh [TotalToRender], a
jr nc, .exit
ld hl, TotalToRender + 1
dec [hl]
.exit .exit
; restore registers ; restore registers saved in interrupt handler
pop hl pop hl
pop bc pop bc
pop de pop de
; restore A saved in interrupt handler
pop af pop af
; return from v-blank or lcd interrupt ; return from v-blank or lcd interrupt
reti reti
; automata buffers with 4 cells per byte ; automata buffers with 4 cells per byte
; 2x2 bytes per cell, bit ordering: ; 2x2 bytes per cell, bit ordering:
; ___ ___ ; ___ ___
@@ -707,8 +690,8 @@ Cells: ds 9
Result: ds 1 Result: ds 1
SECTION "Render Memory", HRAM SECTION "Render Memory", HRAM
MaxRender: ds 1 ; max number of tiles to render before leaving LinesLeft: ds 1 ; number of lines left to render
TotalToRender: ds 2 ; total number of tiles to render left TilesLeft: ds 1 ; number of tiles left to render in current line
Video: ds 2 ; pointer to tilemap Video: ds 2 ; pointer to tilemap
Rendered: ds 2 ; pointer to bufferX Rendered: ds 2 ; pointer to bufferX
@@ -754,22 +737,22 @@ BitsSet:
SECTION "Default Map", ROM0 SECTION "Default Map", ROM0
DefaultMap: DefaultMap:
; 20x18 map with a glider on the top left corner ; 20x18 map with a glider on the top left corner
db 1, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 9,12, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 db 0, 1, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 db 0, 9,12, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 db 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 5, 0,10,10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 1,12, 6, 2,12, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0,12, 4, 0,12, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 5, 0,10,10, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 1, 0, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0