And yet again a bigger step.
Of course we need lots of goodies from the killed enemies. We add items. Items are displayed as 2x2 block of characters. There's a new list of possible items with location added (ITEM_ACTIVE, etc.). The list also stores the original background behind the items.
To get an item spawned just walk beside one of the enemies (look in their direction) and keep fire pressed until it dies.
Note that the player cannot collect the items yet (that's up for the next step).
Inside the player subroutine FireShot we add another subroutine call after killing an enemy:
.EnemyKilled
jsr RemoveObject
jsr SpawnItem
SpawnItem itself resembles the AddObject routine. First we loop over the active item table (ITEM_ACTIVE) to find a free slot.
Once found we randomly chose the item type (for now there are two types). The ugly part below that stores the original character and color at the item position and puts the items char and color in its place. Remember the item is sized 2x2 chars, so we need to store 8 bytes overall. However to keep the code comfortable, we actually use 8 tables. This allows use to only work with the item index instead of manually accessing a second index. There's only two index registers after all.
;------------------------------------------------------------
;spawns an item at char position from object x
;X = object index
;------------------------------------------------------------
!zone SpawnItem
SpawnItem;find free item slot
ldy #0
.CheckNextItemSlot
lda ITEM_ACTIVE,y
cmp #ITEM_NONEbeq .FreeSlotFound
iny
cpy #ITEM_COUNTbne .CheckNextItemSlot
rts
.FreeSlotFound
jsr GenerateRandomNumber
and #$1
sta ITEM_ACTIVE,y
lda SPRITE_CHAR_POS_X,x
sta ITEM_POS_X,y
lda SPRITE_CHAR_POS_Y,x
sta ITEM_POS_Y,y
sty PARAM1
;find address in screen buffer...
tay
lda SCREEN_LINE_OFFSET_TABLE_LO,y
sta ZEROPAGE_POINTER_1
sta ZEROPAGE_POINTER_2
lda SCREEN_LINE_OFFSET_TABLE_HI,y
sta ZEROPAGE_POINTER_1 + 1
;...and for the color buffer
clc
adc #( ( SCREEN_COLOR - SCREEN_CHAR ) & 0xff00 ) >> 8
sta ZEROPAGE_POINTER_2 + 1
ldy SPRITE_CHAR_POS_X,x
ldx PARAM1
;store old background and put item;we do not take overlapping items in account yet!
lda (ZEROPAGE_POINTER_1),y
sta ITEM_BACK_CHAR_UL,x
lda (ZEROPAGE_POINTER_2),y
sta ITEM_BACK_COLOR_UL,x
lda ITEM_CHAR_UL,x
sta (ZEROPAGE_POINTER_1),y
lda ITEM_COLOR_UL,x
sta (ZEROPAGE_POINTER_2),y
iny
lda (ZEROPAGE_POINTER_1),y
sta ITEM_BACK_CHAR_UR,x
lda (ZEROPAGE_POINTER_2),y
sta ITEM_BACK_COLOR_UR,x
lda ITEM_CHAR_UR,x
sta (ZEROPAGE_POINTER_1),y
lda ITEM_COLOR_UR,x
sta (ZEROPAGE_POINTER_2),y
tya
clc
adc #39
tay
lda (ZEROPAGE_POINTER_1),y
sta ITEM_BACK_CHAR_LL,x
lda (ZEROPAGE_POINTER_2),y
sta ITEM_BACK_COLOR_LL,x
lda ITEM_CHAR_LL,x
sta (ZEROPAGE_POINTER_1),y
lda ITEM_COLOR_LL,x
sta (ZEROPAGE_POINTER_2),y
iny
lda (ZEROPAGE_POINTER_1),y
sta ITEM_BACK_CHAR_LR,x
lda (ZEROPAGE_POINTER_2),y
sta ITEM_BACK_COLOR_LR,x
lda ITEM_CHAR_LR,x
sta (ZEROPAGE_POINTER_1),y
lda ITEM_COLOR_LR,x
sta (ZEROPAGE_POINTER_2),y
rts