Update world & sprites in separate loops.

Also give shots a y-velocity.
This commit is contained in:
Colin McMillen 2015-05-30 22:43:27 -04:00
parent 25a2fb20ab
commit 611b4d20f2

View File

@ -16,8 +16,8 @@
; 0022: shot cooldown timer. ; 0022: shot cooldown timer.
; 0023-0024: index of next shot. ; 0023-0024: index of next shot.
; [gap] ; [gap]
; 0030-008F: {enable, x, y, x-velocity} per shot (max 16 shots). ; 0030-008F: {sprite, x, y, x-velocity, y-velocity, unused} per shot.
; I've reserved room so that these can be 6 bytes eventually. ; If sprite is 0, the shot is disabled.
; [gap] ; [gap]
; Sprite table buffers -- copied each frame to OAM during VBlank, using DMA. ; Sprite table buffers -- copied each frame to OAM during VBlank, using DMA.
; 0100-02FF: table 1 (4 bytes each: x/y coord, tile #, flip/priority/palette) ; 0100-02FF: table 1 (4 bytes each: x/y coord, tile #, flip/priority/palette)
@ -35,7 +35,7 @@
.define nextShotPtr $23 .define nextShotPtr $23
.define shotArray $30 .define shotArray $30
.define shotArrayLength 16 .define shotArrayLength 16
.define shotSize 4 .define shotSize 6
; TODO(mcmillen): verify that we can relocate these without messing things up. ; TODO(mcmillen): verify that we can relocate these without messing things up.
.define numSprites 128 .define numSprites 128
@ -321,6 +321,7 @@ MainLoop:
jsr JoypadRead jsr JoypadRead
jsr JoypadHandler jsr JoypadHandler
jsr UpdateWorld jsr UpdateWorld
jsr UpdateSprites
jsr FillSecondarySpriteTable jsr FillSecondarySpriteTable
jsr SetBackgroundColor jsr SetBackgroundColor
jmp MainLoop jmp MainLoop
@ -454,7 +455,10 @@ MaybeShoot:
bne ++ bne ++
ldx nextShotPtr ldx nextShotPtr
; Enable shot; set its position to player position. ; Enable shot; set its position to player position.
lda #1 ; TODO(mcmillen): loop through the array until we find an unused shot.
; TODO(mcmillen): it might be easier/faster to keep N arrays: one for each
; field of shot (shotSpriteArray, shotXArray, shotYArray, ...)
lda #8 ; Sprite number.
sta 0, X sta 0, X
lda playerX lda playerX
sta 1, X sta 1, X
@ -462,6 +466,8 @@ MaybeShoot:
sta 2, X sta 2, X
lda #6 ; x-velocity. lda #6 ; x-velocity.
sta 3, X sta 3, X
lda #0 ; y-velocity.
sta 4, X
; Update nextShotPtr. ; Update nextShotPtr.
.rept shotSize .rept shotSize
inx inx
@ -481,80 +487,44 @@ MaybeShoot:
UpdateWorld: UpdateWorld:
; TODO(mcmillen): separate out "update world" from "update sprite table".
; Zero out the scratch space for the secondary sprite table.
ldx #0
-
stz spriteTableScratchStart, X
inx
cpx #numSprites
bne -
; Update shot cooldown. ; Update shot cooldown.
lda shotCooldown lda shotCooldown
cmp #0 cmp #0
beq + beq +
dea dec A
sta shotCooldown sta shotCooldown
+ +
; Copy player coords into sprite table. ldx #0
lda playerX ; Update shot position.
sta $0100
lda playerY
sta $0101
; Set the sprite.
lda #0
sta $0102
; Set priority bits so that the sprite is drawn in front.
lda #%00110000
sta $0103
lda #%11000000 ; Enable large sprite.
sta spriteTableScratchStart
; Move shot coords and copy into sprite table.
ldx #0 ; Position in main sprite table.
ldy #0 ; Position in secondary scratch sprite table.
; To modify sprite table 2 - one bit set for each active shot.
; These bits will be *removed* from the sprite table entry.
stz $00
UpdateShot: UpdateShot:
lsr $00
lsr $00
lda shotArray, X lda shotArray, X
cmp #1 cmp #0
bne DisableShot beq ShotDone
; Add to the x-coordinate. If the carry bit is set, we went off the edge ; Add to the x-coordinate. If the carry bit is set, we went off the edge
; of the screen, so disable the shot. ; of the screen, so disable the shot.
lda shotArray + 3, X ; x-velocity. lda shotArray + 3, X ; x-velocity.
sta $01 sta $00
lda shotArray + 1, X lda shotArray + 1, X
clc clc
adc $01 adc $00
bcs DisableShot bcs DisableShot
sta shotArray + 1, X ; Store new x-coord. sta shotArray + 1, X ; Store new x-coord.
; Set up shot in sprite table. ; Add to the y-coordinate.
; TODO(mcmillen): we use X for indexing both into the shots table and the lda shotArray + 4, X ; y-velocity.
; sprites table, which is a problem as it assumes shotSize = 4. sta $00
lda shotArray + 1, X ; x lda shotArray + 2, X
; TODO(mcmillen): document that shots start at $110? ; no need for clc - if it was set above, we already jumped to DisableShot.
sta $0110, X adc $00
lda shotArray + 2, X ; y cmp #224
sta $0111, X bcs DisableShot
lda #8 ; which sprite? sta shotArray + 2, X ; Store new y-coord.
sta $0112, X
; Update secondary sprite table.
lda #%11000000
sta spriteTableScratchStart + 4, Y
jmp ShotDone jmp ShotDone
DisableShot: DisableShot:
; Disable it by setting x-position to 1 and setting the high x-bit. stz shotArray, X
lda #1
sta $110, X
ShotDone: ShotDone:
; TODO(mcmillen): in places where we .rept inx (etc), is it faster to use ; TODO(mcmillen): in places where we .rept inx (etc), is it faster to use
@ -562,7 +532,6 @@ ShotDone:
.rept shotSize .rept shotSize
inx inx
.endr .endr
iny
cpx #(shotArrayLength * shotSize) cpx #(shotArrayLength * shotSize)
bne UpdateShot bne UpdateShot
@ -583,6 +552,72 @@ ShotDone:
UpdateSprites:
; Zero out the scratch space for the secondary sprite table.
ldx #0
-
stz spriteTableScratchStart, X
inx
cpx #numSprites
bne -
ldx #0 ; Index into sprite table 1.
ldy #0 ; Index into sprite table 2.
; Copy player coords into sprite table.
lda playerX
sta spriteTableStart, X
lda playerY
sta spriteTableStart + 1, X
lda #0
sta spriteTableStart + 2, X
; Set priority bits so that the sprite is drawn in front.
lda #%00110000
sta spriteTableStart + 3, X
lda #%11000000 ; Enable large sprite.
sta spriteTableScratchStart, Y
.rept 4
inx
.endr
iny
; Now add shots.
sty $00 ; Save sprite table 2 index.
ldy #0 ; Index into shotArray.
-
lda shotArray, Y
cmp #0
beq + ; If not enabled, skip to next shot.
; Update sprite table 1.
sta spriteTableStart + 2, X ; sprite number
lda shotArray + 1, Y
sta spriteTableStart, X ; x
lda shotArray + 2, Y
sta spriteTableStart + 1, X ; y
; Update secondary sprite table.
phy ; Save shotArray index.
ldy $00
lda #%11000000
sta spriteTableScratchStart, Y
iny
sty $00
ply ; Restore shotArrayIndex.
.rept 4
inx
.endr
+
.rept shotSize
iny
.endr
cpy #(shotArrayLength * shotSize)
bne -
rts
FillSecondarySpriteTable: FillSecondarySpriteTable:
; The secondary sprite table wants 2 bits for each sprite: one to set the ; The secondary sprite table wants 2 bits for each sprite: one to set the
; sprite's size, and one that's the high bit of the sprite's x-coordinate. ; sprite's size, and one that's the high bit of the sprite's x-coordinate.