GSCats/terrain.s

352 lines
5.3 KiB
ArmAsm
Raw Normal View History

;
; terrain
;
; Created by Quinn Dunki on 7/29/17
;
2017-07-30 22:43:55 +00:00
TERRAINWIDTH = 640 ; In pixels
MAXTERRAINHEIGHT = 100 ; In pixels
COMPILEDTERRAINROW = TERRAINWIDTH/4+3 ; In words, +2 to make room for clipping jump at end of row
VISIBLETERRAINWIDTH = TERRAINWIDTH/4 ; In words- width minus jump return padding
VISIBLETERRAINWINDOW = 80 ; In words
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; renderTerrain
;
; No stack operations permitted here!
;
; Current implementation: X cycles per row
; Trashes all registers
2017-08-08 05:10:16 +00:00
;
renderTerrain:
FASTGRAPHICS
ldy #MAXTERRAINHEIGHT
lda #$9cff ; 4 Point stack to end of VRAM
tcs ; 2
sec
lda #compiledTerrainEnd-VISIBLETERRAINWINDOW-3
sbc mapScrollPos
sta PARAML0
renderTerrainLoop:
lda #$0000 ; Background
ldx #$1111 ; Foreground
jmp (PARAML0)
renderRowComplete:
lda PARAML0
sec
sbc #COMPILEDTERRAINROW
sta PARAML0
dey
bne renderTerrainLoop
SLOWGRAPHICS
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; clipTerrain
;
;
clipTerrain:
SAVE_AXY
sec
lda #COMPILEDTERRAINROW*MAXTERRAINHEIGHT-3
sbc mapScrollPos
tay
ldx #MAXTERRAINHEIGHT
clipTerrainLoop:
clc ; Compute buffer to for saved data
txa
asl
asl
adc #clippedTerrainData-4
sta PARAML0
2017-07-30 19:16:19 +00:00
lda compiledTerrain,y
sta (PARAML0) ; Preserve data we're overwriting
inc PARAML0
inc PARAML0
2017-07-30 19:16:19 +00:00
and #$ff00
ora #$004c ; jmp in low byte
sta compiledTerrain,y
iny
lda compiledTerrain,y
sta (PARAML0) ; Preserve data we're overwriting
lda #renderRowComplete
sta compiledTerrain,y
tya
sec
sbc #COMPILEDTERRAINROW+1
tay
dex
bne clipTerrainLoop
RESTORE_AXY
rts
2017-08-06 20:26:31 +00:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; unclipTerrain
2017-08-06 20:26:31 +00:00
;
;
unclipTerrain:
SAVE_AXY
2017-08-06 20:26:31 +00:00
sec
lda #COMPILEDTERRAINROW*MAXTERRAINHEIGHT-3
sbc mapScrollPos
tay
ldx #MAXTERRAINHEIGHT
2017-08-06 20:26:31 +00:00
unclipTerrainLoop:
clc ; Compute buffer that saved data is in
txa
asl
2017-08-06 20:26:31 +00:00
asl
adc #clippedTerrainData-4
sta PARAML0
lda (PARAML0)
sta compiledTerrain,y
inc PARAML0
inc PARAML0
iny
2017-08-06 20:26:31 +00:00
lda (PARAML0)
sta compiledTerrain,y
tya
sec
sbc #COMPILEDTERRAINROW+1
tay
dex
bne unclipTerrainLoop
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
ldy #MAXTERRAINHEIGHT-1
lda #compiledTerrain
sta PARAML0
2017-08-06 20:26:31 +00:00
compileTerrainLoop:
sty PARAML1
jsr compileTerrainRow
dey
bmi 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; compileTerrainRow
;
; PARAML0 = Start of compiled row data
; PARAML1 = Row index
;
compileTerrainRow:
SAVE_AXY
ldy #0
ldx #0
compileTerrainColumnLoop:
stz compileTerrainOpcode
; Right half
lda terrainData,x
cmp PARAML1
bcc compileTerrainColumnBGRight
beq compileTerrainColumnBGRight
lda #$00da
compileTerrainColumnLeft:
sta compileTerrainOpcode
inx
inx
lda terrainData,x
cmp PARAML1
bcc compileTerrainColumnBGLeft
beq compileTerrainColumnBGLeft
lda compileTerrainOpcode
ora #$da00
compileTerrainColumnStore:
sta (PARAML0),y
inx
inx
iny
iny
cpy #VISIBLETERRAINWIDTH
bne compileTerrainColumnLoop
2017-08-06 20:26:31 +00:00
RESTORE_AXY
2017-08-06 20:26:31 +00:00
rts
compileTerrainColumnBGRight:
lda #$0048
bra compileTerrainColumnLeft
compileTerrainColumnBGLeft:
lda compileTerrainOpcode
ora #$4800
bra compileTerrainColumnStore
compileTerrainOpcode:
2017-08-06 20:26:31 +00:00
.word 0
2017-08-13 21:56:23 +00:00
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
inx
inx
2017-08-13 04:25:36 +00:00
txa
and #$03ff
2017-08-13 04:25:36 +00:00
tax
cpy #TERRAINWIDTH/2
bne generateTerrainLoop
2017-08-06 20:26:31 +00:00
lda #1
sta terrainData
2017-08-06 20:26:31 +00:00
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; intersectRect
;
; A = non zero if rectangle is intersecting terrain
;
rectParams:
.word 0 ; x
.word 0 ; y 0=terrain bottom, +y=up
.word 0 ; w
.word 0 ; h
intersectRect:
phy
; Convert X to words and compute horizontal extent
; Note that X counts from right terrain edge
lda rectParams
clc
adc rectParams+4 ; Reverse rect horizontally
lsr ; Convert X to bytes
and #$fffe ; Force even
sta rectParams
lda #TERRAINWIDTH/2 ; Reverse X coordinate system
sec
sbc rectParams
sta rectParams
tay ; We'll need this later as an index into height data words
lsr rectParams+4 ; Convert width to bytes
sec
sbc rectParams+4 ; Convert width to extent
sta rectParams+4
; Convert height to vertical extent
lda rectParams+2
sec
sbc rectParams+6
sta rectParams+6
; Check Y bottom
intersectRectBottomLoop:
lda terrainData,y
cmp rectParams+6
bpl intersectRectYep
dey
dey
cpy rectParams+4
bpl intersectRectBottomLoop
lda #0
ply
rts
intersectRectYep:
lda #1
ply
rts
; Terrain data, stored as height values 4 pixels wide
terrainData:
2017-08-13 04:25:36 +00:00
.repeat TERRAINWIDTH/4 ; VISIBLETERRAINWIDTH
.word 0
.endrepeat
compiledTerrain:
.repeat COMPILEDTERRAINROW * MAXTERRAINHEIGHT
.byte 0
.endrepeat
compiledTerrainEnd:
clippedTerrainData:
.repeat MAXTERRAINHEIGHT
.byte 0,0,0,0 ; xx,jmp,addr
.endrepeat
2017-08-06 20:26:31 +00:00