A C64 game - Step 4

posted in New Old Things
Published May 07, 2011
Advertisement

Now we take a bigger step: Moving the sprite with the joystick. Since we want to make a real game we also allow to move the sprite over to the right side (in other words we'll take care of the extended x bit).

For clarification: The C64 has 8 hardware sprites. That's 8 objects of the size 24 x 21 pixels. They can be placed anywhere. The coordinates are stored in memory addresses. However since the X resolution is higher than 256 all the sprites 9th bit is stored in another memory location (which makes it highly annoying to work with).
Sprite coordinates are set in X, Y pairs via the memory locations 53248 (=X sprite 0), 53249 (=Y sprite 0), 53250 (=X sprite 1), etc. The extended sprite bits are stored in 53248 + 16.

Since I don't plan to allow sprites to go off screen in the game later there is no defined behaviour if you move the sprite off screen too far. It'll simply bounce back in once the coordinate wraps around.

The joystick ports can be checked via the memory locations 56320 (Port 2) or 56321 (Port 1). The lower 5 bits are cleared(!) if either up, down, left, right for fire is pressed.


This step shows:
-Joystick control
-Sprite extended x bit

step4.png.9d2bde3ed872055c4b87ff643693a904.png

Inside the GameLoop we add a call to the players control function:


          jsr PlayerControl

 

PlayerControl itself checks the joystick port (II) and calls the proper direction move routines. Note that the move routines themselves simply set the object index to 0 (for the player) and call a generic sprite move routine.
 


          ;------------------------------------------------------------
          ;check joystick (player control)
          ;------------------------------------------------------------
!zone PlayerControl
PlayerControl
          lda #$2
          bit $dc00
          bne .NotDownPressed
          jsr PlayerMoveDown
          
.NotDownPressed
          lda #$1
          bit $dc00
          bne .NotUpPressed
          jsr PlayerMoveUp
          
.NotUpPressed
          lda #$4
          bit $dc00
          bne .NotLeftPressed
          jsr PlayerMoveLeft
          
.NotLeftPressed
          lda #$8
          bit $dc00
          bne .NotRightPressed
          jsr PlayerMoveRight
          
.NotRightPressed
          rts
          
PlayerMoveLeft
          ldx #0
          jsr MoveSpriteLeft
          rts
          
PlayerMoveRight
          ldx #0
          jsr MoveSpriteRight
          rts
          
PlayerMoveUp
          ldx #0
          jsr MoveSpriteUp
          rts
          
PlayerMoveDown
          ldx #0
          jsr MoveSpriteDown
          rts

 

The sprite move routines are rather simple, update the position counter variables and set the actual sprite registers. A bit more complicated are the X move functions. If X reaches the wraparound, the extended x bit (the 9th bit) is looked up in a table and then added/removed.
 


          ;------------------------------------------------------------
          ;Move Sprite Left
          ;expect x as sprite index (0 to 7)
          ;------------------------------------------------------------
!zone MoveSpriteLeft
MoveSpriteLeft
          dec SPRITE_POS_X,x
          bpl .NoChangeInExtendedFlag
          lda BIT_TABLE,x
          eor #$ff
          and SPRITE_POS_X_EXTEND
          sta SPRITE_POS_X_EXTEND
          sta VIC_SPRITE_X_EXTEND
.NoChangeInExtendedFlag
          txa
          asl
          tay
          lda SPRITE_POS_X,x
          sta VIC_SPRITE_X_POS,y
          rts
          
          ;------------------------------------------------------------
          ;Move Sprite Right
          ;expect x as sprite index (0 to 7)
          ;------------------------------------------------------------
!zone MoveSpriteRight
MoveSpriteRight
          inc SPRITE_POS_X,x
          lda SPRITE_POS_X,x
          bne .NoChangeInExtendedFlag
          lda BIT_TABLE,x
          ora SPRITE_POS_X_EXTEND
          sta SPRITE_POS_X_EXTEND
          sta VIC_SPRITE_X_EXTEND
.NoChangeInExtendedFlag
          txa
          asl
          tay
          lda SPRITE_POS_X,x
          sta VIC_SPRITE_X_POS,y
          rts
          
          ;------------------------------------------------------------
          ;Move Sprite Up
          ;expect x as sprite index (0 to 7)
          ;------------------------------------------------------------
!zone MoveSpriteUp
MoveSpriteUp
          dec SPRITE_POS_Y,x
          txa
          asl
          tay
          lda SPRITE_POS_Y,x
          sta 53249,y
          rts
          
          ;------------------------------------------------------------
          ;Move Sprite Down
          ;expect x as sprite index (0 to 7)
          ;------------------------------------------------------------
!zone MoveSpriteDown
MoveSpriteDown
          inc SPRITE_POS_Y,x
          txa
          asl
          tay
          lda SPRITE_POS_Y,x
          sta 53249,y
          rts

step4.zip

Previous Step 3 Next Step 5

Previous Entry A C64 game - Step 3
Next Entry A C64 game - Step 5
0 likes 1 comments

Comments

cdoty
Handling the extended bit always seemed like a daunting task years ago.
May 24, 2011 08:31 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement