diff --git a/pewpew.asm b/pewpew.asm index 160d71c..418c019 100644 --- a/pewpew.asm +++ b/pewpew.asm @@ -14,7 +14,9 @@ ; [gap] ; 0020-0021: (x, y) coordinates of player. ; 0022: shot cooldown timer. -; 0030-0032: enable / x / y of shot. +; 0023-0024: index of next shot. +; [gap] +; 0030-003F: {enable, x, y, unused} per shot (max 4 shots). ; ; 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) @@ -29,6 +31,7 @@ .define playerX $20 .define playerY $21 .define shotCooldown $22 +.define nextShotPtr $23 .define shotData $30 ; TODO(mcmillen): verify that we can relocate these without messing things up. @@ -139,7 +142,6 @@ LoadPaletteAndTileData: ; Now, BG3 palette data. ; Palette entries for BG3 start at 0. - ; TODO(mcmillen): BG2 started at 32, but maybe that's only in mode 0? ldx #0 lda #0 sta CGADDR @@ -256,10 +258,9 @@ InitializeSpriteTables: lda #$01 - sta spriteTableStart, X - inx - inx - inx - inx + .rept 4 + inx + .endr cpx #spriteTable1Size bne - @@ -290,6 +291,10 @@ InitializeWorld: sta playerX lda #((224 - 32) / 2) sta playerY + + ; Next shot pointer starts at the beginning. + ldx #shotData + stx nextShotPtr rts @@ -436,23 +441,37 @@ MaybeShoot: ; If the cooldown timer is non-zero, don't shoot. lda shotCooldown cmp #0 - bne + + bne ++ + ldx nextShotPtr + stx $0060 ; Enable shot; set its position to player position. lda #1 - sta shotData + sta 0, X lda playerX - sta shotData + 1 + sta 1, X lda playerY - sta shotData + 2 + sta 2, X + ; Update nextShotPtr. + .rept 4 + inx + .endr + cpx #$0040 ; TODO(mcmillen): use a constant. + bne + + ldx #shotData ++ + stx nextShotPtr + ; Set cooldown timer. lda #16 sta shotCooldown -+ +++ rts UpdateWorld: + ; TODO(mcmillen): separate out "update world" from "update sprite table". + ; Update shot cooldown. lda shotCooldown cmp #0 @@ -478,51 +497,57 @@ UpdateWorld: ora #%00000010 ; ... and make it the large size. (32x32) sta spriteTable2Start - ; Move shot coords. - ldx $0 - lda shotData - cmp #1 - bne DisableShot - - lda shotData + 1 - ; TODO(mcmillen): do this with an add, then check the carry bit? - .rept 6 - ina - cmp #$00 ; If it wraps around, disable it. - bne + - stz shotData -+ - .endr - sta shotData + 1 ; Store new x-coord. - - ; See if sprite is still enabled after move. - lda shotData + ; Move shot coords and copy into sprite table. + ldx #0 + ; 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: + lsr $00 + lsr $00 + lda shotData, X cmp #1 bne DisableShot + ; Add to the x-coordinate. If the carry bit is set, we went off the edge + ; of the screen, so disable the shot. + lda shotData + 1, X + clc + adc #6 ; x velocity + bcs DisableShot + sta shotData + 1, X ; Store new x-coord. + + ; Set up shot in sprite table. + lda shotData + 1, X ; x + ; TODO(mcmillen): document that shots start at $110? + sta $0110, X + lda shotData + 2, X ; y + sta $0111, X + lda #8 ; which sprite? + sta $0112, X - ; Set up shot sprite. - lda shotData + 1 ; x - sta $0104 - lda shotData + 2 ; y - sta $0105 - lda #8 ; which sprite - sta $0106 - - lda $0300 - and #%11111011 ; Display it. - ora #%00001000 ; and set it to large size. - sta $0300 + lda $00 + ora #%01000000 + sta $00 jmp ShotDone DisableShot: ; Disable it by setting x-position to 1 and setting the high x-bit. lda #1 - sta $104 - lda $0300 - ora #%00000100 - sta $0300 + sta $110, X ShotDone: + ; TODO(mcmillen): in places where we .rept inx (etc), is it faster to use + ; actual addition? + .rept 4 + inx + .endr + cpx #16 + bne UpdateShot + ; Set the enable/disable (and size) bits of the shot sprites. + lda #$ff + eor $00 + sta $0301 + ; Make the background scroll. Horizontal over time; vertical depending on ; player's y-coordinate. lda vBlankCounter