|
@ -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). |
|
|
|
|
|
; I've reserved room so that these can be 6 bytes eventually. |
|
|
|
|
|
|
|
|
; 0030-008F: {sprite, x, y, x-velocity, y-velocity, unused} per shot. |
|
|
|
|
|
; 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. |
|
|
|
|
|
lda playerX |
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
ldx #0 |
|
|
|
|
|
; Update shot position. |
|
|
UpdateShot: |
|
|
UpdateShot: |
|
|
lsr $00 |
|
|
|
|
|
lsr $00 |
|
|
|
|
|
lda shotArray, X |
|
|
lda shotArray, X |
|
|
cmp #1 |
|
|
|
|
|
bne DisableShot |
|
|
|
|
|
|
|
|
cmp #0 |
|
|
|
|
|
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. |
|
|
|
|
|
; TODO(mcmillen): we use X for indexing both into the shots table and the |
|
|
|
|
|
; sprites table, which is a problem as it assumes shotSize = 4. |
|
|
|
|
|
lda shotArray + 1, X ; x |
|
|
|
|
|
; TODO(mcmillen): document that shots start at $110? |
|
|
|
|
|
sta $0110, X |
|
|
|
|
|
lda shotArray + 2, X ; y |
|
|
|
|
|
sta $0111, X |
|
|
|
|
|
lda #8 ; which sprite? |
|
|
|
|
|
sta $0112, X |
|
|
|
|
|
|
|
|
; Add to the y-coordinate. |
|
|
|
|
|
lda shotArray + 4, X ; y-velocity. |
|
|
|
|
|
sta $00 |
|
|
|
|
|
lda shotArray + 2, X |
|
|
|
|
|
; no need for clc - if it was set above, we already jumped to DisableShot. |
|
|
|
|
|
adc $00 |
|
|
|
|
|
cmp #224 |
|
|
|
|
|
bcs DisableShot |
|
|
|
|
|
sta shotArray + 2, X ; Store new y-coord. |
|
|
|
|
|
|
|
|
; 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. |
|
|
|
|
|
lda #1 |
|
|
|
|
|
sta $110, X |
|
|
|
|
|
|
|
|
stz shotArray, 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. |
|
|