GSCats/terrain.s

592 lines
10 KiB
ArmAsm
Raw Normal View History

;
; terrain
;
; Created by Quinn Dunki on 7/29/17
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; renderTerrain
;
; No stack operations permitted here!
;
; Trashes all registers
2017-08-08 05:10:16 +00:00
;
renderTerrain:
FASTGRAPHICS
2017-11-01 19:42:52 +00:00
lda #0
sta SCRATCHL2 ; Row counter
2018-01-19 02:15:42 +00:00
lda #$5f1f ; 4 Point stack to end of affected VRAM
tcs ; 2
sec
2018-03-05 20:32:05 +00:00
lda #compiledTerrainEnd-VISIBLETERRAINWINDOW-4
sbc mapScrollPos
sta PARAML0
renderTerrainLoop:
2017-09-17 20:39:10 +00:00
; Note that DP register is normally $0000, so that is used as the BG/BG case
lda #$0011 ; BG/FG
ldx #$1111 ; FG/FG
2017-09-17 20:39:10 +00:00
ldy #$1100 ; FG/BG
jmp (PARAML0)
renderRowComplete:
2018-03-05 20:32:05 +00:00
lda PARAML0
sec
sbc #COMPILEDTERRAINROW
sta PARAML0
2017-11-01 19:42:52 +00:00
tsc
clc
adc #320
tcs
lda SCRATCHL2
inc
2018-01-19 02:15:42 +00:00
cmp lastCompiledTerrainY
beq renderRowCont
bcs renderTerrainDone
renderRowCont:
2017-11-01 19:42:52 +00:00
sta SCRATCHL2
bra renderTerrainLoop
renderTerrainDone:
SLOWGRAPHICS
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; craterTerrain
;
; PARAML0 = X pos of center in pixels from logical left terrain edge
; PARAML1 = Y pos of center in pixels from bottom terrain edge
2018-06-12 00:01:19 +00:00
; Y = Radius of circle, in pixels (minimum is 3)
;
; Trashes SCRATCHL
craterTerrain:
SAVE_AX
stz craterTerrainAccumulator
lda #TERRAINWIDTH ; Convert X pos to terrain-right byte count
sec
sbc PARAML0
2017-09-17 23:17:27 +00:00
sty SCRATCHL ; Center width in bytes
sbc SCRATCHL
2018-06-12 00:01:19 +00:00
sbc SCRATCHL
2017-09-13 16:56:34 +00:00
and #$fffe ; Force even
clc
adc #terrainData
sta PARAML0
2018-06-12 00:01:19 +00:00
tya
asl
tay
2017-09-13 16:56:34 +00:00
lda circleTable,y ; Look up circle data
sta SCRATCHL
2017-09-13 16:56:34 +00:00
2018-06-12 00:01:19 +00:00
tya ; Iterate over diameter words
2017-09-13 16:56:34 +00:00
asl
tay
craterTerrainLoop:
dey
dey
bmi craterTerrainDone
2017-09-18 19:51:01 +00:00
tya
clc
adc PARAML0 ; Clip to terrain edges
cmp #terrainData
bmi craterTerrainDone
cmp #terrainDataEnd
bpl craterTerrainLoop
lda (SCRATCHL),y ; Fetch circle Y value
clc
adc PARAML1 ; Convert to terrain-space
2017-09-18 19:51:01 +00:00
bmi craterTerrainZero
sta SCRATCHL2
sec
lda (PARAML0),y
sbc SCRATCHL2
bmi craterTerrainLoop
; Circle value is lower, so use that
clc
adc craterTerrainAccumulator ; Track total crater material
sta craterTerrainAccumulator
lda SCRATCHL2 ; Replace terrain height with cratered value
bmi craterTerrainZero ; Don't let it be negative
sta (PARAML0),y
bra craterTerrainLoop
2017-09-18 19:51:01 +00:00
craterTerrainZero: ; Circle went negative so clip to 0
lda #0
sta (PARAML0),y
bra craterTerrainLoop
craterTerrainDone:
lda #1
sta terrainDirty
RESTORE_AX
rts
craterTerrainAccumulator:
.word 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; clipTerrain
;
2018-03-05 20:32:05 +00:00
; Saves the compiled terrain data that we overwrite into
; a buffer at $E04000. We do this by shadowing the stack
; to that area and pushing.
;
clipTerrain:
SAVE_AXY
2018-03-05 20:32:05 +00:00
; Shadow stack into $E04000 to save clipped data fast
tsc
sta STACKPTR
lda #CLIPPEDTERRAINSTACK
tcs
sec
2018-03-05 20:32:05 +00:00
lda #COMPILEDTERRAINROW*MAXTERRAINHEIGHT-4
sbc mapScrollPos
tay
2018-03-05 20:32:05 +00:00
ldx #0
clipTerrainLoop:
lda compiledTerrain,y
2018-03-05 20:32:05 +00:00
pha
lda #$4cea ; NOP followed by JMP
sta compiledTerrain,y
2018-03-05 20:32:05 +00:00
iny
iny
lda compiledTerrain,y
2018-03-05 20:32:05 +00:00
pha
lda #renderRowComplete
sta compiledTerrain,y
tya
sec
2018-03-05 20:32:05 +00:00
sbc #COMPILEDTERRAINROW+2
tay
inx
cpx lastCompiledTerrainY
bcc clipTerrainLoop
beq clipTerrainLoop
2018-03-05 20:32:05 +00:00
; Put stack back where it belongs
tsc
sta clippedTerrainStackPtr
lda STACKPTR
tcs
RESTORE_AXY
rts
2017-08-06 20:26:31 +00:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; unclipTerrain
2017-08-06 20:26:31 +00:00
;
2018-03-05 20:32:05 +00:00
; Restores the compiled terrain data that we wrote
; to a buffer at $E04000. We do this by mapping the stack
; to $4000, then using stack-relative addressing to pull the data.
; We can't pop the data because it's all stored in reverse.
2017-08-06 20:26:31 +00:00
;
2018-03-05 20:32:05 +00:00
; On first move-left unclip every second row is unclipped incorrectly
unclipTerrain:
SAVE_AXY
2017-08-06 20:26:31 +00:00
2018-03-05 20:32:05 +00:00
phd
lda #(CLIPPEDTERRAINSTACK & $f000)
2018-03-05 20:32:05 +00:00
pha
pld ; Point direct page at our clip data
sec
2018-03-05 20:32:05 +00:00
lda #COMPILEDTERRAINROW*MAXTERRAINHEIGHT-4
sbc mapScrollPos
tay
2017-08-06 20:26:31 +00:00
sec ; Find stopping point for stack-relative addressing
2018-03-05 20:32:05 +00:00
lda clippedTerrainStackPtr
and #$0fff
sbc #3 ; -3 for starting offset
sta STACKPTR
lda #$0fff-3 ; Start at the bottom of the stack
2018-03-05 20:32:05 +00:00
tax
2018-03-05 20:32:05 +00:00
unclipTerrainLoop:
lda 2,x
sta compiledTerrain,y
2018-03-05 20:32:05 +00:00
iny
iny
2017-08-06 20:26:31 +00:00
2018-03-05 20:32:05 +00:00
lda 0,x
sta compiledTerrain,y
tya
sec
2018-03-05 20:32:05 +00:00
sbc #COMPILEDTERRAINROW+2
tay
dex ; Walk up the stack to reverse the data
dex
dex
dex
cpx STACKPTR ; When x hits the top of the stack, we're done
2018-03-05 20:32:05 +00:00
bne unclipTerrainLoop
pld
RESTORE_AXY
rts
2017-08-06 20:26:31 +00:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; compileTerrain
2017-08-06 20:26:31 +00:00
;
;
;
compileTerrain:
SAVE_AY
2017-08-06 20:26:31 +00:00
2017-11-01 19:42:52 +00:00
ldy #0
lda #compiledTerrain
sta PARAML0
stz compileTerrainRowStart
lda #TERRAINWIDTH
sta compileTerrainRowEnd
2017-08-06 20:26:31 +00:00
compileTerrainLoop:
sty PARAML1
jsr compileTerrainRow
2017-11-01 19:42:52 +00:00
iny
cpy #MAXTERRAINHEIGHT
beq compileTerrainDone
2017-08-06 20:26:31 +00:00
clc
lda #COMPILEDTERRAINROW
adc PARAML0
sta PARAML0
2017-08-06 20:26:31 +00:00
bra compileTerrainLoop
2017-08-06 20:26:31 +00:00
compileTerrainDone:
RESTORE_AY
rts
2017-08-06 20:26:31 +00:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; compileTerrainChunk
;
; compileTerrainRowStart = Start column to compile (logical terrainData index)
; compileTerrainRowEnd = Ending column to compile (logical terrainData index)
;
; Trashes A,Y, SCRATCHL, PARAML0, PARAML1
;
compileTerrainChunk:
; Clamp chunk to left and right terrain edges
lda compileTerrainRowStart
bmi compileTerrainChunkClampZero
compileTerrainChunkClampResume:
lda compileTerrainRowEnd
cmp #TERRAINWIDTH
bcs compileTerrainChunkClampHigh
compileTerrainChunkResume:
ldy #0
ldx #MAXTERRAINHEIGHT-1
stx SCRATCHL
sty PARAML0
; Compute the start of memory affected
lda #COMPILEDTERRAINROW
sta PARAML1
jsr mult16
clc
adc #compiledTerrain
sta PARAML0
compileTerrainChunkLoop:
sty PARAML1
jsr compileTerrainRow
iny
cpy SCRATCHL
beq compileTerrainChunkDone
clc
lda #COMPILEDTERRAINROW
adc PARAML0
sta PARAML0
bra compileTerrainChunkLoop
compileTerrainChunkDone:
rts
compileTerrainChunkClampZero:
stz compileTerrainRowStart
bra compileTerrainChunkClampResume
compileTerrainChunkClampHigh:
lda #TERRAINWIDTH-1
sta compileTerrainRowEnd
bra compileTerrainChunkResume
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; compileTerrainRow
;
; PARAML0 = Start of compiled row data
; PARAML1 = Row index
; compileTerrainRowStart = Start column to compile (logical terrainData index)
; compileTerrainRowEnd = Ending column to compile (logical terrainData index)
;
; Note: DA = PHX = FG/FG
2017-09-17 20:39:10 +00:00
; 48 = PHA = FG/BG
; 5A = PHY = BG/FG
2017-09-17 20:39:10 +00:00
; 0B = PHD = BG/BG
2017-09-13 16:56:34 +00:00
compileTerrainRow:
SAVE_AXY
lda compileTerrainRowStart ; Initialize horizontal counters
lsr
lsr
and #%11111100 ; Word-align it
tay
asl ; Logical counter is 4x compiled counter
asl
tax
lda compileTerrainRowEnd ; Convert end counter to compiled version
lsr
lsr
and #%11111100
sta compileTerrainRowEndCompiled
compileTerrainColumnLoop:
stz compileTerrainOpcode
2017-09-17 20:39:10 +00:00
; Check column 0
lda terrainData,x
cmp PARAML1
2017-09-17 20:39:10 +00:00
bcc compileTerrainColumn0BG
beq compileTerrainColumn0BG
2017-09-17 20:39:10 +00:00
; Column 0 is FG, so check column 1
inx
inx
lda terrainData,x
cmp PARAML1
2017-09-17 20:39:10 +00:00
bcc compileTerrainColumn1BG
beq compileTerrainColumn1BG
; Columns 0 and 1 are FG/FG, so PHX
lda #$00da
2017-09-13 16:56:34 +00:00
compileTerrainColumn2:
2017-09-17 20:39:10 +00:00
sta compileTerrainOpcode ; Cache results so far
; Check column 2
inx
inx
lda terrainData,x
cmp PARAML1
bcc compileTerrainColumn2BG
beq compileTerrainColumn2BG
; Column 2 is FG, so check column 3
inx
inx
lda terrainData,x
cmp PARAML1
2017-09-17 20:39:10 +00:00
bcc compileTerrainColumn3BG
beq compileTerrainColumn3BG
; Columns 2 and 3 are FG/FG, so PHX
lda compileTerrainOpcode
ora #$da00
compileTerrainColumnStore:
sta (PARAML0),y
inx
inx
iny
iny
cpy compileTerrainRowEndCompiled
bne compileTerrainColumnLoop
2017-08-06 20:26:31 +00:00
RESTORE_AXY
2017-08-06 20:26:31 +00:00
rts
2017-09-17 20:39:10 +00:00
compileTerrainColumn0BG:
2017-09-17 20:39:10 +00:00
; Column 0 is BG, so check column 1
inx
2017-09-17 20:39:10 +00:00
inx
lda terrainData,x
cmp PARAML1
bcc compileTerrainColumn01BG
beq compileTerrainColumn01BG
; Columns 0 and 1 are BG/FG, so PHA
lda #$0048
bra compileTerrainColumn2
compileTerrainColumn01BG:
; Columns 0 and 1 are BG/BG, so PHD
lda #$000b
bra compileTerrainColumn2
2017-09-17 20:39:10 +00:00
compileTerrainColumn1BG:
2017-09-17 20:39:10 +00:00
; Columns 0 and 1 are FG/BG, so PHY
lda #$005a
bra compileTerrainColumn2
2017-09-17 20:39:10 +00:00
compileTerrainColumn2BG:
; Column 2 is BG, so check column 3
inx
inx
lda terrainData,x
cmp PARAML1
bcc compileTerrainColumn23BG
beq compileTerrainColumn23BG
; Columns 2 and 3 are BG/FG, so PHA
lda compileTerrainOpcode
ora #$4800
bra compileTerrainColumnStore
2017-09-17 20:39:10 +00:00
compileTerrainColumn23BG:
; Columns 2 and 3 are BG, so PHD
lda compileTerrainOpcode
ora #$0b00
bra compileTerrainColumnStore
compileTerrainColumn3BG:
; Columns 2 and 3 are FG/BG, so PHY
lda compileTerrainOpcode
ora #$5a00
bra compileTerrainColumnStore
compileTerrainOpcode:
2017-08-06 20:26:31 +00:00
.word 0
compileTerrainRowStart:
.word 0
compileTerrainRowEnd:
.word 640
compileTerrainRowEndCompiled:
.word 0
2017-12-24 19:36:31 +00:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; prepareRowRendering:
;
; Set SCBs to match rendering mode of each terrain line
;
; Trashes SCRATCHL, SCRATCHL2
;
prepareRowRendering:
SAVE_AXY
ldx #199
stz SCRATCHL2
2018-01-19 02:15:42 +00:00
stz lastCompiledTerrainY
2017-12-24 19:36:31 +00:00
prepareRowRenderingLoop:
lda #0
PLAYERPTR_Y
sec
lda playerData+GO_POSY,y
sbc #GAMEOBJECTHEIGHT
; cmp SCRATCHL2
; bcc prepareRowRenderingCompileMode
; beq prepareRowRenderingCompileMode
2017-12-24 19:36:31 +00:00
; jsr enableFillMode
; bra prepareRowRenderingLoopNext
2017-12-24 19:36:31 +00:00
prepareRowRenderingCompileMode:
jsr disableFillMode
2018-01-19 02:15:42 +00:00
inc lastCompiledTerrainY
2017-12-24 19:36:31 +00:00
prepareRowRenderingLoopNext:
inc SCRATCHL2
dex
cpx #200-MAXTERRAINHEIGHT
bne prepareRowRenderingLoop
prepareRowRenderingDone:
2017-12-24 19:36:31 +00:00
RESTORE_AXY
rts
2017-08-06 20:26:31 +00:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; generateTerrain
2017-08-06 20:26:31 +00:00
;
2017-08-13 04:25:36 +00:00
; Trashes everything
2017-08-06 20:26:31 +00:00
;
generateTerrain:
ldy #0
2017-08-13 04:25:36 +00:00
ldx #0
lda #terrainData
2017-08-06 20:26:31 +00:00
sta SCRATCHL
generateTerrainLoop:
2017-08-13 04:25:36 +00:00
lda sineTable,x
lsr
lsr
clc
adc #30
2017-08-06 20:26:31 +00:00
sta (SCRATCHL),y
iny
iny
2017-08-13 04:25:36 +00:00
inx
inx
inx
inx
2017-08-13 04:25:36 +00:00
txa
and #$03ff
2017-08-13 04:25:36 +00:00
tax
2017-09-13 16:56:34 +00:00
cpy #TERRAINWIDTH
bne generateTerrainLoop
2017-08-06 20:26:31 +00:00
; lda #1 ; Debug values
; sta terrainData
; lda #2
; sta compiledTerrain-4
2017-08-06 20:26:31 +00:00
rts
compiledTerrain:
.repeat COMPILEDTERRAINROW * MAXTERRAINHEIGHT
.byte $42
.endrepeat
compiledTerrainEnd:
2018-03-05 20:32:05 +00:00
clippedTerrainStackPtr:
.word 0
2017-08-06 20:26:31 +00:00