Penetrator-apple2/src/apple2/terrain.inc

403 lines
10 KiB
PHP

;-----------------------------------------------------------------------------
; terrain.inc
; Part of penetrator, the zx spectrum game, made for Apple II
;
; Stefan Wessels, 2019
; This is free and unencumbered software released into the public domain.
;-----------------------------------------------------------------------------
.segment "CODE"
;-----------------------------------------------------------------------------
.proc terrainShow
zaIndex = tempBlock + 1
zaWorldBot = tempBlock + 2
zaWorldTop = tempBlock + 3
zaSide = tempBlock + 4
ldy #WORLD_START ; start row
lda #(WORLD_END - WORLD_START + 1) ; no of rows to clear
ldx backLayer ; inactive (back) layer
jsr drawClearRows ; clean the part where the world must draw
lda terrainOrigin
lsr
sta zScreenCol
ldy bufferDraw ; make enemyBuffer relative to screen col 0
dey ; but back up 1 to the last drawn height
lda worldBBuffer, y ; prime the drawing with these heights
sta zaWorldBot ; as the last height is where the col 0
lda worldTBuffer, y ; draw needs to come from
sta zaWorldTop
iny ; get back to col 0 equivalent index
sty zaIndex ; and save this index
loop:
lda #0
sta zaSide
lda worldBBuffer, y
ldy zaWorldBot ; get the last height
sta zaWorldBot ; save new bottom as last
jsr terrainDrawLeftColumn
inc zaSide
ldy zaIndex
lda worldTBuffer, y
ldy zaWorldTop ; get the last height
sta zaWorldTop ; save new bottom as last
cmp #9
bcc :+
jsr terrainDrawLeftColumn
:
lda #0
sta zaSide
inc zaIndex
ldy zaIndex
lda worldBBuffer, y
ldy zaWorldBot ; get the last height
sta zaWorldBot ; save new bottom as last
jsr terrainDrawRightColumn
inc zaSide
ldy zaIndex
lda worldTBuffer, y
ldy zaWorldTop ; get the last height
sta zaWorldTop ; save new bottom as last
cmp #9
bcc :+
jsr terrainDrawRightColumn
:
ldy zaIndex
cpy bufferInsert
beq done
iny
sty zaIndex
inc zScreenCol
bne loop
done:
clc
rts
.endproc
;-----------------------------------------------------------------------------
; y is last height, a is new height
.proc terrainDrawLeftColumn
zaSide = tempBlock + 4
zaDiff = tempBlock + 5
zaDir = tempBlock + 6 ; 2 bytes used
sty zaDiff
sec
sbc zaDiff ; get the delta (new - old)
tax ; save delta in x
bcs eqdown ; new .ge. old
up: ; new < old so go up
lda rowL, y
adc zScreenCol
sta writeUpStart + 1
lda rowH, y
adc zVramH
sta writeUpStart + 2
lda #%00000011 ; start with a 2 pixel flat area
writeUpStart:
sta PLACEHOLDER
dey ; go 1 row up
inx
beq skup ; if at new height now, skip the "up line" portion
:
lda rowL, y ; draw the "up line" portion now
adc zScreenCol
sta writeUp + 1
lda rowH, y
adc zVramH
sta writeUp + 2
lda #%00000100 ; write a single pixel up the rows
writeUp:
sta PLACEHOLDER
dey ; row up
inx
bne :- ; keep going till old .eq. new
skup:
lda rowL, y ; finish off the transition
adc zScreenCol
sta writeUpEnd + 1
lda rowH, y
adc zVramH
sta writeUpEnd + 2
lda #%00001000 ; by writing a pixel to connect to new
writeUpEnd:
sta PLACEHOLDER ; (which will become old, in next column, to draw from)
lda #$ff
ldx zaSide
sta zaDir, x
rts
eqdown:
clc ; carry still set from subtract
beq eq ; if new .eq. old it's a flat line
down: ; new > old so go down - see up, same but inc|dec is reversed
lda rowL, y
adc zScreenCol
sta writeDownStart + 1
lda rowH, y
adc zVramH
sta writeDownStart + 2
lda #%00000011
writeDownStart:
sta PLACEHOLDER
iny
dex
beq skdn
:
lda rowL, y
adc zScreenCol
sta writeDown + 1
lda rowH, y
adc zVramH
sta writeDown + 2
lda #%00000100
writeDown:
sta PLACEHOLDER
iny
dex
bne :-
skdn:
lda rowL, y
adc zScreenCol
sta writeDownEnd + 1
lda rowH, y
adc zVramH
sta writeDownEnd + 2
lda #%00001000
writeDownEnd:
sta PLACEHOLDER
lda #$01
ldx zaSide
sta zaDir, x
rts
eq: ; flat line from old to new when equal
lda rowL, y
adc zScreenCol
sta writeFlat + 1
lda rowH, y
adc zVramH
sta writeFlat + 2
lda #%00001111
writeFlat: ; 4 pixels in a line
sta PLACEHOLDER
lda #$00
ldx zaSide
sta zaDir, x
rts
.endproc
;-----------------------------------------------------------------------------
; y is last height, a is new height
.proc terrainDrawRightColumn
zaSide = tempBlock + 4
zaDiff = tempBlock + 5
zaDir = tempBlock + 6 ; 2 bytes used
zaSaveX = tempBlock + 8
sty zaDiff
sec
sbc zaDiff ; get the delta (new - old)
tax ; save delta in x
bcc up
jmp eqdown ; new .ge. old
up: ; new < old so go up
lda rowL, y
adc zScreenCol
sta writeUpStart + 1
sta writeUpStart + 4
lda rowH, y
adc zVramH
sta writeUpStart + 2
sta writeUpStart + 5
lda #%00010000 ; start with a 2 pixel flat area
writeUpStart:
ora PLACEHOLDER
sta PLACEHOLDER
dey ; go 1 row up
inx
beq skup ; if at new height now, skip the "up line" portion
stx zaSaveX
ldx zaSide
lda zaDir, x
ldx zaSaveX
cmp #1
bne fastUp
clc
:
lda rowL, y ; draw the "up line" portion now
adc zScreenCol
sta writeUp + 1
sta writeUp + 4
lda rowH, y
adc zVramH
sta writeUp + 2
sta writeUp + 5
lda #%00100000 ; write a single pixel up the rows
writeUp:
ora PLACEHOLDER
sta PLACEHOLDER
dey ; row up
inx
bne :- ; keep going till old .eq. new
beq skup
fastUp:
clc
:
lda rowL, y ; draw the "up line" portion now
adc zScreenCol
sta writeUpFast + 1
lda rowH, y
adc zVramH
sta writeUpFast + 2
lda #%00100000 ; write a single pixel up the rows
writeUpFast:
sta PLACEHOLDER
dey ; row up
inx
bne :- ; keep going till old .eq. new
skup:
lda rowL, y ; finish off the transition
adc zScreenCol
sta writeUpEnd + 1
sta writeUpEnd + 4
lda rowH, y
adc zVramH
sta writeUpEnd + 2
sta writeUpEnd + 5
lda #%01000000 ; by writing a pixel to connect to new
writeUpEnd:
ora PLACEHOLDER
sta PLACEHOLDER ; (which will become old, in next column, to draw from)
rts
eqdown:
clc ; carry still set from subtract
bne down ; if new .eq. old it's a flat line
jmp eq
down: ; new > old so go down - see up, same but inc|dec is reversed
lda rowL, y
adc zScreenCol
sta writeDownStart + 1
sta writeDownStart + 4
lda rowH, y
adc zVramH
sta writeDownStart + 2
sta writeDownStart + 5
lda #%00010000
writeDownStart:
ora PLACEHOLDER
sta PLACEHOLDER
iny
dex
beq skdn
stx zaSaveX
ldx zaSide
lda zaDir, x
ldx zaSaveX
cmp #$ff
bne fastDown
clc
:
lda rowL, y
adc zScreenCol
sta writeDown + 1
sta writeDown + 4
lda rowH, y
adc zVramH
sta writeDown + 2
sta writeDown + 5
lda #%00100000
writeDown:
ora PLACEHOLDER
sta PLACEHOLDER
iny
dex
bne :-
beq skdn
fastDown:
clc
:
lda rowL, y
adc zScreenCol
sta writeDownFast + 1
lda rowH, y
adc zVramH
sta writeDownFast + 2
lda #%00100000
writeDownFast:
sta PLACEHOLDER
iny
dex
bne :-
skdn:
lda rowL, y
adc zScreenCol
sta writeDownEnd + 1
sta writeDownEnd + 4
lda rowH, y
adc zVramH
sta writeDownEnd + 2
sta writeDownEnd + 5
lda #%01000000
writeDownEnd:
ora PLACEHOLDER
sta PLACEHOLDER
rts
eq: ; flat line from old to new when equal
lda rowL, y
adc zScreenCol
sta writeFlat + 1
sta writeFlat + 4
lda rowH, y
adc zVramH
sta writeFlat + 2
sta writeFlat + 5
lda #%01110000
writeFlat: ; 4 pixels in a line
ora PLACEHOLDER
sta PLACEHOLDER
rts
.endproc