For this update, we're going to modify the Arena Loop to draw the Arena using the playfield. The new Arena loop has these new changes:
ArenaLoop: ; 27 - (currently 7 from bpl ArenaLoop) tya ; 2 29 - 2LK loop counter in A for testing and #%11 ; 2 31 - test for every 4th time through the loop, bne SkipX ; 2 33 (3 34) branch if not 4th time inx ; 2 35 - if 4th time, increase X so new playfield data is used SkipX: ; 35 - use 35 as it's the longest path here ... ; start of line 1 of the 2LK sta GRP1 ; 3 3 - @0-22, update player1 graphics lda ArenaPF0,x ; 4 7 - get current scanline's playfield pattern sta PF0 ; 3 10 - @0-22 and update it lda ArenaPF1,x ; 4 14 - get current scanline's playfield pattern sta PF1 ; 3 17 - @71-28 and update it lda ArenaPF2,x ; 4 21 - get current scanline's playfield pattern sta PF2 ; 3 24 - @60-39 ... ; start of line 2 of the 2LK sta GRP0 ; 3 3 - @0-22, update player0 graphics dey ; 2 5 - decrease the 2LK loop counter bne ArenaLoop ; 2 7 - (3 branch if there's more Arena to draw sty PF0 ; 3 10 - Y is 0, blank out playfield sty PF1 ; 3 13 - Y is 0, blank out playfield sty PF2 ; 3 16 - Y is 0, blank out playfield rts ; 6 22 - ReTurn from Subroutine
The first change is we're using X as an index into the playfield graphic data. We're changing X every fourth time thru the 2LK, so each byte of playfield data will be used over 8 scanlines. This saves a bit of ROM.
Second change is all 3 playfield registers (PF0, PF1 and PF2) are now updated, and they're only updated on line 1 of our 2LK.
Third change is on line 2, the bpl ArenaLoop is now a bne ArenaLoop else the bottom row of playfield data was only used for 2 scanlines instead of 8. We also blank out the playfield registers when we are done drawing the playfield. The bne change also impacted Overscan - TIM64T was originally set to 32, it's now set to 35.
The playfield data looks like this in jEdit:
and this onscreen:
Lastly we added some collision detection code. Some space was allocated in RAM:
;save player locations for playfield collision logic SavedX: ds 2 ; stored in $A1-A2 SavedY: ds 2 ; stored in $A3-A4
Then the Process Joystick routines save the current X and Y values before processing the joystick:
PJloop: ldy ObjectX,x ; save original X location so the player can be sty SavedX,x ; bounced back upon colliding with the playfield ldy ObjectY,x ; save original Y location so the player can be sty SavedY,x ; bounced back upon colliding with the playfield
Finally OverScan was modified to move the players back to their previous X and Y location if a collision was detected:
; Test if player collided with playfield bit CXP0FB ; N = player0/playfield, V=player0/ball bpl notP0PF ; if N is off, then player0 did not collide with playfield lda SavedX ; recall saved X sta ObjectX ; and move player back to it lda SavedY ; recall saved Y sta ObjectY ; and move player back to it notP0PF: bit CXP1FB ; N = player1/playfield, V=player1/ball bpl notP1PF ; if N is off, then player1 did not collide with playfield lda SavedX+1 ; recall saved X sta ObjectX+1 ; and move player back to it lda SavedY+1 ; recall saved Y sta ObjectY+1 ; and move player back to it notP1PF:
COLLECT TUTORIAL NAVIGATION