Simplify handling of secondary sprite table.

We now keep a buffer that has one byte per sprite, and later pack it
into the bitfield format wanted by OAM, instead of calculating the
bitfield manually during UpdateWorld
This commit is contained in:
Colin McMillen 2015-05-29 08:03:20 -04:00
parent 7a04a359fa
commit 36b54692c1

View File

@ -36,11 +36,12 @@
.define shotArrayLength 4 .define shotArrayLength 4
; 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 spriteTableStart $100 .define spriteTableStart $100
.define spriteTable1Size $200 .define spriteTable1Size $200
.define spriteTable2Start $300 ; TODO(mcmillen): use this. .define spriteTable2Start $300
.define spriteTableSize $220 .define spriteTableSize $220
.define spriteTableScratchStart $320
; Stores result to A. ; Stores result to A.
; Assumes 16-bit X & 8-bit A. ; Assumes 16-bit X & 8-bit A.
@ -266,7 +267,7 @@ InitializeSpriteTables:
; bits 0,2,4,6 - High bit of the sprite's x-coordinate. ; bits 0,2,4,6 - High bit of the sprite's x-coordinate.
; bits 1,3,5,7 - Toggle Sprite size: 0 - small size 1 - large size ; bits 1,3,5,7 - Toggle Sprite size: 0 - small size 1 - large size
; Setting all the high bits keeps the sprites offscreen. ; Setting all the high bits keeps the sprites offscreen.
lda #%0101010101010101 lda #$FFFF
- -
sta spriteTableStart, X sta spriteTableStart, X
inx inx
@ -302,6 +303,7 @@ MainLoop:
jsr JoypadDebug jsr JoypadDebug
jsr JoypadHandler jsr JoypadHandler
jsr UpdateWorld jsr UpdateWorld
jsr FillSecondarySpriteTable
jsr SetBackgroundColor jsr SetBackgroundColor
jmp MainLoop jmp MainLoop
@ -430,7 +432,6 @@ MaybeShoot:
cmp #0 cmp #0
bne ++ bne ++
ldx nextShotPtr ldx nextShotPtr
stx $0060
; Enable shot; set its position to player position. ; Enable shot; set its position to player position.
lda #1 lda #1
sta 0, X sta 0, X
@ -459,6 +460,14 @@ MaybeShoot:
UpdateWorld: UpdateWorld:
; TODO(mcmillen): separate out "update world" from "update sprite table". ; 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
@ -479,13 +488,11 @@ UpdateWorld:
lda #%00110000 lda #%00110000
sta $0103 sta $0103
; Clear x-MSB so that the sprite is displayed. ; Clear x-MSB so that the sprite is displayed.
lda spriteTable2Start lda #%01000000
and #%11111110 sta spriteTableScratchStart
ora #%00000010 ; ... and make it the large size. (32x32)
sta spriteTable2Start
; Move shot coords and copy into sprite table. ; Move shot coords and copy into sprite table.
ldx #0 ldy #0 ; Position in secondary scratch sprite table.
; To modify sprite table 2 - one bit set for each active shot. ; To modify sprite table 2 - one bit set for each active shot.
; These bits will be *removed* from the sprite table entry. ; These bits will be *removed* from the sprite table entry.
stz $00 stz $00
@ -512,9 +519,9 @@ UpdateShot:
lda #8 ; which sprite? lda #8 ; which sprite?
sta $0112, X sta $0112, X
lda $00 ; Update secondary sprite table.
ora #%01000000 lda #%01000000
sta $00 sta spriteTableScratchStart + 4, Y
jmp ShotDone jmp ShotDone
DisableShot: DisableShot:
@ -528,12 +535,9 @@ ShotDone:
.rept 4 .rept 4
inx inx
.endr .endr
cpx #16 iny
cpx #(4 * shotArrayLength)
bne UpdateShot 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 ; Make the background scroll. Horizontal over time; vertical depending on
; player's y-coordinate. ; player's y-coordinate.
@ -552,6 +556,42 @@ ShotDone:
FillSecondarySpriteTable:
; 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.
; It's annoying to deal with bitfields when thinking about business logic,
; so the spriteTableScratch array contains one byte for each sprite, in
; which the two most significant bits are the "size" and "upper x" bits.
; This function is meant to be called after UpdateWorld, and packs those
; bytes into the actual bitfield that the OAM wants for the secondary
; sprite table.
ldx #0 ; Index into input table.
ldy #0 ; Index into output table.
-
stz $00 ; Current byte; filled out by a set of 4 input table entries.
.rept 4
; For each byte, the lower-order bits correspond to the lower-numbered
; sprites; therefore we insert the current sprite's bits "at the top"
; and shift them right for each successive sprite.
lsr $00
lsr $00
lda spriteTableScratchStart, X
ora $00
sta $00
inx
.endr
; TODO(mcmillen): change the semantics of the scratch table so that
; "1" = "big"?
lda $00
eor #$FF
sta spriteTable2Start, Y
iny
cpx #numSprites
bne -
rts
SetBackgroundColor: SetBackgroundColor:
; The background-color bytes are (R, G, B), each ranging from [0-31]. ; The background-color bytes are (R, G, B), each ranging from [0-31].
; The palette color format is 15-bit: [0bbbbbgg][gggrrrrr] ; The palette color format is 15-bit: [0bbbbbgg][gggrrrrr]