The game more or less works now.

This commit is contained in:
Jeremy Rand 2017-07-21 21:38:21 -05:00
parent 5a63950400
commit 5dc5adb39b

View File

@ -37,13 +37,13 @@ COL_WHITE=3
CHAR_HEIGHT=10 CHAR_HEIGHT=10
NUM_CHAR_BITMAPS=3 NUM_CHAR_BITMAPS=3
CHAR_MAX_JUMPS=2 CHAR_MAX_JUMPS=2
CHAR_XPOS=2 CHAR_XPOS=3
CHAR_STATE_NONE=0 CHAR_STATE_NONE=0
CHAR_STATE_JUMPING=1 CHAR_STATE_JUMPING=1
CHAR_STATE_FALLING=2 CHAR_STATE_FALLING=2
JUMP_SPEED=$FF-4 JUMP_SPEED=5
GRAVITY=64 GRAVITY=64
GRID_YPOS=140 GRID_YPOS=140
@ -260,8 +260,8 @@ LINE191 = LINE190 + 1024
jsr drawCharacter jsr drawCharacter
jsr drawGrids jsr drawGrids
jsr updateCharacter
jsr updateGrid jsr updateGrid
jsr updateCharacter
lda shouldQuit lda shouldQuit
beq @nextframe beq @nextframe
@ -273,6 +273,32 @@ LINE191 = LINE190 + 1024
.endproc .endproc
.proc resetGame
lda #0
sta characterBitmap
sta characterY
sta characterOldY
sta characterNumJumps
sta characterYSpeed
sta characterYSpeedFrac
sta gridXShift
sta gridXPos
lda #COL_VIOLET
sta characterColour
lda #CHAR_HEIGHT
sta characterYBottom
sta characterOldYBottom
lda #CHAR_STATE_FALLING
sta characterState
jmp setLevelAddr
.endproc
.proc setLevelAddr .proc setLevelAddr
ldx level ldx level
lda levelsLo,x lda levelsLo,x
@ -291,6 +317,42 @@ LINE191 = LINE190 + 1024
.endproc .endproc
.proc gameOver
jsr drawCharacter
@loop:
lda KBD
bpl @loop
ldx KBDSTRB
cmp #$9b ; Compare to Escape
beq @quit
cmp #$d1 ; Compare to 'Q'
beq @quit
cmp #$f1 ; Compare to 'q'
beq @quit
jsr resetGame
jmp clearScreen
@quit:
lda #$01
sta shouldQuit
rts
.endproc
.proc levelWon
lda #COL_WHITE
sta characterColour
inc level
; This is weird but at this point, all of the logic we
; need to progress to the next level is in gameOver...
jmp gameOver
.endproc
.proc updateCharacter .proc updateCharacter
; Save the old character position so it can be erased ; Save the old character position so it can be erased
@ -362,23 +424,281 @@ lastButtonState: .BYTE $00
lda characterYBottom lda characterYBottom
sta characterOldYBottom sta characterOldYBottom
lda #0
sta ZPADDR6+1
lda characterState lda characterState
cmp #CHAR_STATE_NONE cmp #CHAR_STATE_NONE
bne @notStateNone beq @stateNone
cmp #CHAR_STATE_JUMPING
beq @stateJumping
jmp updateCharacterPosFalling
@stateNone:
jmp updateCharacterPosNone
@stateJumping:
jmp updateCharacterPosJumping
.endproc
.proc nextGridAtCharacter
lda ZPADDR6+1
bne @nextGrid
lda LEVELADDR
sta ZPADDR6
lda LEVELADDR+1
sta ZPADDR6+1
lda #$0
sta gridLeft
lda gridXPos
clc
adc #MAXXBYTE
sta screenRight
ldy #$1
lda (ZPADDR6),y
beq @noneFound
@gridLoop:
lda gridLeft
cmp screenRight
bcs @noneFound
ldy #$1
clc
adc (ZPADDR6),y
; If we got a carry, that means the width of the next grid plus
; the grid left overflowed 256. If that happens we are definitely
; not left of gridXPos. We just need to subtract gridXPos to get
; onto screen coords.
bcs @overflow
cmp gridXPos
bcc @nextGrid
sec
@overflow:
sbc gridXPos
tax
lda gridXShift
beq @skipRightAdjust
cmp #3
bcs @skipRightAdjust
dex
dex
@skipRightAdjust:
cpx #MAXXBYTE
bcc @rightIsNotOffScreen
ldx #MAXXBYTE
@rightIsNotOffScreen:
stx gridScreenRight
lda gridLeft
sec
sbc gridXPos
bpl @leftIsOnScreen
lda #$0
@leftIsOnScreen:
cmp #CHAR_XPOS+1
bcs @noneFound
lda gridScreenRight
cmp #CHAR_XPOS
bcs @foundOne
@nextGrid:
lda ZPADDR6
clc
adc #LEVEL_STRUCT_SIZE
bcc @doNotIncHiByte
inc ZPADDR6+1
@doNotIncHiByte:
sta ZPADDR6
ldy #$1
lda (ZPADDR6),y
beq @noneFound
ldy #$0
lda gridLeft
clc
adc (ZPADDR6),y
cmp screenRight
beq @L2
bcs @noneFound
@L2:
sta gridLeft
jmp @gridLoop
@noneFound:
sec
rts rts
@notStateNone: @foundOne:
cmp #CHAR_STATE_JUMPING clc
beq @jumping rts
; Locals
screenRight: .BYTE $00
gridLeft: .BYTE $00
.endproc
.proc updateCharacterPosNone
@loop:
jsr nextGridAtCharacter
bcs @floorGone
ldy #2
lda (ZPADDR6),y
cmp characterYBottom
bne @loop
ldy #4
lda (ZPADDR6),y
cmp characterColour
beq @checkForWin
jmp gameOver
@checkForWin:
ldy #LEVEL_STRUCT_SIZE+1
lda (ZPADDR6),y
bne @return
jmp levelWon
@floorGone:
lda #CHAR_STATE_FALLING
sta characterState
lda #0
sta characterYSpeed
sta characterYSpeedFrac
@return:
rts
.endproc
.proc updateCharacterPosJumping
; For jumping, we need to calculate the top first and check
; for collisions
lda characterY
sec
sbc characterYSpeed
bcc @hitCeiling
sta characterY
@loop:
jsr nextGridAtCharacter
bcs @didNotHitHead
ldy #2
lda (ZPADDR6),y
sta gridTop
ldy #3
lda (ZPADDR6),y
sta gridBottom
cmp characterOldY
bcc @wasBelowToStart
jmp @loop
@wasBelowToStart:
cmp characterY
bcc @loop
jmp @startFalling
@hitCeiling:
lda #$0
jmp @startFalling
@dropToBottomOfGrid:
lda gridBottom
@startFalling:
sta characterY
lda #0
sta characterYSpeed
sta characterYSpeedFrac
sta characterNumJumps
lda #CHAR_STATE_FALLING
sta characterState
jmp @updateYBottom
@didNotHitHead:
lda characterYSpeedFrac
clc
adc #GRAVITY
sta characterYSpeedFrac
bcc @updateYBottom
dec characterYSpeed
bne @updateYBottom
lda #CHAR_STATE_FALLING
sta characterState
@updateYBottom: ; Need to calculate characterYBottom now from characterY
lda characterY
clc
adc #CHAR_HEIGHT
sta characterYBottom
rts
; Locals
gridTop: .BYTE $00
gridBottom: .BYTE $00
.endproc
.proc updateCharacterPosFalling
; For falling, we need to calculate the bottom first and check ; For falling, we need to calculate the bottom first and check
; for collisions ; for collisions
lda characterYBottom lda characterYBottom
clc clc
adc characterYSpeed adc characterYSpeed
cmp gridY sta characterYBottom
bmi @didNotLand cmp #MAXY
lda gridY bcc @loop
lda #MAXY
sta characterYBottom
sec
sbc #CHAR_HEIGHT
sta characterY
jsr gameOver
rts
@loop:
jsr nextGridAtCharacter
bcs @didNotLand
ldy #3
lda (ZPADDR6),y
sta gridBottom
ldy #2
lda (ZPADDR6),y
cmp characterOldYBottom
bcs @wasAboveToStart
lda characterYBottom
sec
sbc #CHAR_HEIGHT
cmp gridBottom
bcc @dropToBottomOfGrid
jmp @loop
@wasAboveToStart:
cmp characterYBottom
beq @L1
bcs @loop
@L1:
sta characterYBottom sta characterYBottom
lda #0 lda #0
sta characterYSpeed sta characterYSpeed
@ -388,8 +708,13 @@ lastButtonState: .BYTE $00
sta characterState sta characterState
jmp @updateY jmp @updateY
@didNotLand: @dropToBottomOfGrid:
lda gridBottom
sec
sbc #CHAR_HEIGHT
sta characterYBottom sta characterYBottom
@didNotLand:
lda characterYSpeedFrac lda characterYSpeedFrac
clc clc
adc #GRAVITY adc #GRAVITY
@ -404,42 +729,8 @@ lastButtonState: .BYTE $00
sta characterY sta characterY
rts rts
@jumping: ; Locals
; For jumping, we need to calculate the top first and check gridBottom: .BYTE $00
; for collisions
lda characterY
clc
adc characterYSpeed
cmp gridY ; TODO - fix this compare
bmi @didNotHitHead
lda gridY
sta characterY
lda #0
sta characterYSpeed
sta characterYSpeedFrac
sta characterNumJumps
lda #CHAR_STATE_FALLING
sta characterState
jmp @updateYBottom
@didNotHitHead:
sta characterY
lda characterYSpeedFrac
clc
adc #GRAVITY
sta characterYSpeedFrac
bcc @updateYBottom
inc characterYSpeed
bmi @updateYBottom
lda #CHAR_STATE_FALLING
sta characterState
@updateYBottom: ; Need to calculate characterYBottom now from characterY
lda characterY
clc
adc #CHAR_HEIGHT
sta characterYBottom
rts
.endproc .endproc
@ -461,6 +752,7 @@ lastButtonState: .BYTE $00
.proc updateCharacterColour .proc updateCharacterColour
lda KBD lda KBD
bpl @return bpl @return
ldx KBDSTRB
cmp #$9b ; Compare to Escape cmp #$9b ; Compare to Escape
beq @quit beq @quit
cmp #$d1 ; Compare to 'Q' cmp #$d1 ; Compare to 'Q'
@ -468,7 +760,6 @@ lastButtonState: .BYTE $00
cmp #$f1 ; Compare to 'q' cmp #$f1 ; Compare to 'q'
beq @quit beq @quit
lda KBDSTRB
lda characterColour lda characterColour
cmp #COL_VIOLET cmp #COL_VIOLET
beq @changeToGreen beq @changeToGreen
@ -482,7 +773,6 @@ lastButtonState: .BYTE $00
rts rts
@quit: @quit:
lda KBDSTRB
lda #$01 lda #$01
sta shouldQuit sta shouldQuit
@ -535,7 +825,7 @@ lastButtonState: .BYTE $00
sty yPos sty yPos
ldy #CHAR_XPOS ldy #CHAR_XPOS
lda evenVal lda oddVal
and (ZPADDR1,x) and (ZPADDR1,x)
sta (ZPADDR0),y sta (ZPADDR0),y
inc ZPADDR1 inc ZPADDR1
@ -544,7 +834,7 @@ lastButtonState: .BYTE $00
@doNotIncHiByte1: @doNotIncHiByte1:
iny iny
lda oddVal lda evenVal
and (ZPADDR1,x) and (ZPADDR1,x)
sta (ZPADDR0),y sta (ZPADDR0),y
inc ZPADDR1 inc ZPADDR1
@ -581,17 +871,16 @@ yPos: .BYTE $00
@loop: @loop:
ldy #$1 ldy #$1
lda (LEVELADDR),y lda gridXPos
cmp gridXPos cmp (LEVELADDR),y
bpl @return bcc @return
; At this point, we know that this grid is not visible ; At this point, we know that this grid is not visible
; Check to see if the start of the next grid is left justified ; Check to see if the start of the next grid is left justified
; or off screen. ; or off screen.
ldy #LEVEL_STRUCT_SIZE ldy #LEVEL_STRUCT_SIZE
lda (LEVELADDR),y cmp (LEVELADDR),y
cmp gridXPos bcc @return
bpl @return
; At this point, we know that the gridXPos is at the start of ; At this point, we know that the gridXPos is at the start of
; the next grid or maybe past the start. Move the LEVELADDR ; the next grid or maybe past the start. Move the LEVELADDR
@ -651,7 +940,7 @@ yPos: .BYTE $00
; onto screen coords. ; onto screen coords.
bcs @overflow bcs @overflow
cmp gridXPos cmp gridXPos
bmi @nextGrid bcc @nextGrid
sec sec
@overflow: @overflow:
sbc gridXPos sbc gridXPos
@ -679,7 +968,7 @@ yPos: .BYTE $00
beq @gridRightZeroSpecialCase beq @gridRightZeroSpecialCase
dex dex
cmp #$3 cmp #$3
bpl @L1 bcs @L1
dex dex
jmp @L1 jmp @L1
@gridRightZeroSpecialCase: @gridRightZeroSpecialCase:
@ -687,7 +976,7 @@ yPos: .BYTE $00
bne @nextGrid bne @nextGrid
@L1: @L1:
cpx #MAXXBYTE cpx #MAXXBYTE
bmi @rightIsNotOffScreen bcc @rightIsNotOffScreen
ldx #MAXXBYTE ldx #MAXXBYTE
@rightIsNotOffScreen: @rightIsNotOffScreen:
stx gridScreenRight stx gridScreenRight
@ -703,9 +992,9 @@ yPos: .BYTE $00
jsr drawGrid jsr drawGrid
;@debugLoop: ;@debugLoop:
; lda KBD ; lda KBD
; bpl @debugLoop ; bpl @debugLoop
; lda KBDSTRB ; lda KBDSTRB
@nextGrid: @nextGrid:
lda ZPADDR6 lda ZPADDR6
@ -716,12 +1005,18 @@ yPos: .BYTE $00
@doNotIncHiByte: @doNotIncHiByte:
sta ZPADDR6 sta ZPADDR6
ldy #$1
lda (ZPADDR6),y
beq @return
ldy #$0 ldy #$0
lda gridLeft lda gridLeft
clc clc
adc (ZPADDR6),y adc (ZPADDR6),y
cmp screenRight cmp screenRight
bpl @return beq @L2
bcs @return
@L2:
sta gridLeft sta gridLeft
jmp @gridLoop jmp @gridLoop
@ -787,6 +1082,15 @@ gridLeft: .BYTE $00
and oddGrid,x and oddGrid,x
sta oddGridVal sta oddGridVal
ldy #LEVEL_STRUCT_SIZE+1
lda (ZPADDR6),y
bne @notLastGrid
lda evenVal
sta evenGridVal
lda oddVal
sta oddGridVal
@notLastGrid:
lda evenGridRight,x lda evenGridRight,x
and evenVal and evenVal
sta evenRightCap sta evenRightCap
@ -795,12 +1099,15 @@ gridLeft: .BYTE $00
sta oddRightCap sta oddRightCap
ldy gridScreenLeft ldy gridScreenLeft
beq @nextGridComponent beq @L1
cpx #$0 cpx #$0
beq @nextGridComponent beq @L1
jmp @L2
@L1:
jmp @nextGridComponent
; Draw the left cap ; Draw the left cap
@L2:
lda evenGridLeft,x lda evenGridLeft,x
and evenVal and evenVal
sta evenLeftCap sta evenLeftCap
@ -821,13 +1128,18 @@ gridLeft: .BYTE $00
and #$01 and #$01
bne @leftCapOdd1 bne @leftCapOdd1
lda evenLeftCap
and evenGridVal
tax
lda evenLeftMask lda evenLeftMask
and (ZPADDR0),y and (ZPADDR0),y
ora evenLeftCap ora evenLeftCap
ldx evenGridVal
jmp @nextLeftCapComponent jmp @nextLeftCapComponent
@leftCapOdd1: @leftCapOdd1:
lda oddLeftCap
and oddGridVal
tax
lda oddLeftMask lda oddLeftMask
and (ZPADDR0),y and (ZPADDR0),y
ora oddLeftCap ora oddLeftCap
@ -842,18 +1154,22 @@ gridLeft: .BYTE $00
and #$01 and #$01
bne @leftCapOdd2 bne @leftCapOdd2
lda evenLeftCap
and evenGridVal
tax
lda evenLeftMask lda evenLeftMask
and (ZPADDR0),y and (ZPADDR0),y
ora evenLeftCap ora evenLeftCap
ldx evenGridVal
jsr drawGridComponent jsr drawGridComponent
jmp @drawBodyComponents jmp @drawBodyComponents
@leftCapOdd2: @leftCapOdd2:
lda oddLeftCap
and oddGridVal
tax
lda oddLeftMask lda oddLeftMask
and (ZPADDR0),y and (ZPADDR0),y
ora oddLeftCap ora oddLeftCap
ldx oddGridVal
jsr drawGridComponent jsr drawGridComponent
@drawBodyComponents: @drawBodyComponents:
@ -938,90 +1254,6 @@ oddRightCap: .BYTE $00
.endproc .endproc
.proc drawGridOld
ldy gridY
lda loAddrs,y
sta ZPADDR0
lda page1HiAddrs,y
sta ZPADDR0+1
iny
lda loAddrs,y
sta ZPADDR1
lda page1HiAddrs,y
sta ZPADDR1+1
iny
lda loAddrs,y
sta ZPADDR2
lda page1HiAddrs,y
sta ZPADDR2+1
iny
lda loAddrs,y
sta ZPADDR3
lda page1HiAddrs,y
sta ZPADDR3+1
iny
lda loAddrs,y
sta ZPADDR4
lda page1HiAddrs,y
sta ZPADDR4+1
iny
lda loAddrs,y
sta ZPADDR5
lda page1HiAddrs,y
sta ZPADDR5+1
ldx gridXShift
ldy gridColour
lda colourEvenLookup,y
sta evenVal
and evenGrid,x
sta evenGridVal
lda colourOddLookup,y
sta oddVal
and oddGrid,x
sta oddGridVal
ldy #0
@L1:
lda evenVal
sta (ZPADDR0),y
sta (ZPADDR5),y
lda evenGridVal
sta (ZPADDR1),y
sta (ZPADDR2),y
sta (ZPADDR3),y
sta (ZPADDR4),y
iny
lda oddVal
sta (ZPADDR0),y
sta (ZPADDR5),y
lda oddGridVal
sta (ZPADDR1),y
sta (ZPADDR2),y
sta (ZPADDR3),y
sta (ZPADDR4),y
iny
cpy #MAXXBYTE
bne @L1
rts
; Locals
evenVal: .BYTE $00
oddVal: .BYTE $00
evenGridVal: .BYTE $00
oddGridVal: .BYTE $00
.endproc
.proc clearScreen .proc clearScreen
ldx #0 ldx #0
ldy #0 ldy #0
@ -1193,23 +1425,22 @@ characterBitmap3:
.BYTE $0c, $00 .BYTE $0c, $00
characterBitmapLo: characterBitmapLo:
.LOBYTES characterBitmap1, characterBitmap2, characterBitmap3 .LOBYTES characterBitmap3, characterBitmap2, characterBitmap1
characterBitmapHi: characterBitmapHi:
.HIBYTES characterBitmap1, characterBitmap2, characterBitmap3 .HIBYTES characterBitmap3, characterBitmap2, characterBitmap1
characterColour: .BYTE COL_VIOLET characterColour: .BYTE COL_VIOLET
characterBitmap: .BYTE $00 characterBitmap: .BYTE $00
characterY: .BYTE GRID_YPOS-CHAR_HEIGHT characterY: .BYTE 0
characterYBottom: .BYTE GRID_YPOS characterYBottom: .BYTE CHAR_HEIGHT
characterOldY: .BYTE GRID_YPOS-CHAR_HEIGHT characterOldY: .BYTE 0
characterOldYBottom: .BYTE GRID_YPOS characterOldYBottom: .BYTE CHAR_HEIGHT
characterState: .BYTE CHAR_STATE_NONE characterState: .BYTE CHAR_STATE_FALLING
characterNumJumps: .BYTE $00 characterNumJumps: .BYTE $00
characterYSpeed: .BYTE $00 characterYSpeed: .BYTE $00
characterYSpeedFrac: .BYTE $00 characterYSpeedFrac: .BYTE $00
gridColour: .BYTE COL_VIOLET
gridY: .BYTE GRID_YPOS gridY: .BYTE GRID_YPOS
gridXShift: .BYTE $00 gridXShift: .BYTE $00
gridXPos: .BYTE $00 gridXPos: .BYTE $00
@ -1218,7 +1449,7 @@ gridScreenRight: .BYTE $00
shouldQuit: .BYTE $00 shouldQuit: .BYTE $00
level: .BYTE $00 level: .BYTE $0
; A level consists of the following for each grid: ; A level consists of the following for each grid:
; Byte 0 - Offset of the start of this grid from the previous grid's start ; Byte 0 - Offset of the start of this grid from the previous grid's start
@ -1228,31 +1459,36 @@ level: .BYTE $00
; Byte 4 - Grid colour ; Byte 4 - Grid colour
; The end of a level has a grid width of 0 ; The end of a level has a grid width of 0
level1: level1:
.BYTE 0, 200, 140, 140+GRID_HEIGHT, COL_VIOLET .BYTE 0, 80, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE 210, 100, 140, 140+GRID_HEIGHT, COL_VIOLET .BYTE 90, 80, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE 110, 100, 140, 140+GRID_HEIGHT, COL_VIOLET .BYTE 90, 80, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE 100, 30, 140, 140+GRID_HEIGHT, COL_GREEN .BYTE 90, 40, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE 4, 10, 100, 100+GRID_HEIGHT, COL_VIOLET .BYTE 40, $00, $00, $00, $00
.BYTE 50, 10, 140, 140+GRID_HEIGHT, COL_GREEN
.BYTE 30, 10, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE 30, 10, 140, 140+GRID_HEIGHT, COL_GREEN
.BYTE 30, 100, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE 120, 100, 140, 140+GRID_HEIGHT, COL_GREEN
.BYTE 120, 100, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE 120, 100, 140, 140+GRID_HEIGHT, COL_GREEN
.BYTE 120, 100, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE 120, 100, 140, 140+GRID_HEIGHT, COL_GREEN
.BYTE 120, 100, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE 120, 100, 140, 140+GRID_HEIGHT, COL_GREEN
.BYTE 120, $00, $00, $00, $00
level2: level2:
.BYTE $00, 100, 140, 140+GRID_HEIGHT, COL_VIOLET .BYTE 0, 80, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE $00, $00, $00, $00, $00 .BYTE 90, 80, 140, 140+GRID_HEIGHT, COL_GREEN
.BYTE 90, 80, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE 90, 40, 140, 140+GRID_HEIGHT, COL_GREEN
.BYTE 40, $00, $00, $00, $00
level3:
.BYTE 0, 80, 80, 80+GRID_HEIGHT, COL_VIOLET
.BYTE 60, 80, 100, 100+GRID_HEIGHT, COL_GREEN
.BYTE 60, 80, 120, 120+GRID_HEIGHT, COL_VIOLET
.BYTE 60, 40, 140, 140+GRID_HEIGHT, COL_GREEN
.BYTE 40, $00, $00, $00, $00
level4:
.BYTE 0, 80, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE 60, 80, 120, 120+GRID_HEIGHT, COL_VIOLET
.BYTE 60, 80, 140, 140+GRID_HEIGHT, COL_VIOLET
.BYTE 60, 40, 120, 120+GRID_HEIGHT, COL_VIOLET
.BYTE 40, $00, $00, $00, $00
levelsLo: levelsLo:
.LOBYTES level1, level2, 0 .LOBYTES level1, level2, level3, level4, 0
levelsHi: levelsHi:
.HIBYTES level1, level2, 0 .HIBYTES level1, level2, level3, level4, 0