• entries
104
102
• views
259546

# A C64 game - Step 9

2974 views

What are enemies if they just sit put and don't move at all? Therefore we now add the sub routine ObjectControl. ObjectControl loops through all objects (even the player) and jumps to the behaviour function depending on the object type. This incurs that the behaviour is tied to the object type. We provide a table with function pointers to every object's behaviour code (including the player).

ObjectControl takes the object type as index into the table and jumps to the target address. For now we have two enemy types, dumb moving up/down or left/right. For moving we reuse the previously created functions we already use for the player, namely ObjectMoveLeft/ObjectMoveRight etc.

Loop over all active objects and jump at their behaviour code. Note that we apply a nasty trick. Since jsr doesn't allow for indirect jumps we manually push the return address on the stack and then call indirect jmp. This allows for the behaviour code to return with rts.

;------------------------------------------------------------
;Enemy Behaviour
;------------------------------------------------------------
!zone ObjectControl
ObjectControl
ldx #0
.ObjectLoop
ldy SPRITE_ACTIVE,x
beq .NextObject

;enemy is active
dey
lda ENEMY_BEHAVIOUR_TABLE_LO,y
sta ZEROPAGE_POINTER_2
lda ENEMY_BEHAVIOUR_TABLE_HI,y
sta ZEROPAGE_POINTER_2 + 1

;set up return address for rts
lda #>( .NextObject - 1 )
pha
lda #<( .NextObject - 1 )
pha
jmp (ZEROPAGE_POINTER_2)

.NextObject
inx
cpx #8
bne .ObjectLoop
rts

The main game loop is now changed; removed the call of PlayerControl and added the call to ObjectControl:

;------------------------------------------------------------
;the main game loop
;------------------------------------------------------------
GameLoop
jsr WaitFrame
jsr ObjectControl
jmp GameLoop

The behaviour table is built from the behaviour code addresses. Actually we use two tables for high and low byte, this way we don't have to mess with the index. The < and > operators return the low and high byte of a 16 bit value.

ENEMY_BEHAVIOUR_TABLE_LO
!byte <PlayerControl
!byte <BehaviourDumbEnemyLR
!byte <BehaviourDumbEnemyUD

ENEMY_BEHAVIOUR_TABLE_HI
!byte >PlayerControl
!byte >BehaviourDumbEnemyLR
!byte >BehaviourDumbEnemyUD

The way these indirect jumps have always been done, is by simply modifying an existing JSR instruction:

[code]

lda TABLE_LO, y
sta .JumpPoint+1
lda TABLE_HI, y
sta .JumpPoint+2

.JumpPoint jsr \$1234
[/code]

Ah, neat! I never did assembly on the C64 back then, just started out 2007.

Always good to learn something new ;)

## Create an account

Register a new account