Last time I wrote code to put a hero sprite onscreen. In my first (pre-sprite) video demo, I had room changes triggered directly by player input. Today I’m going to recode the input handler to alter the hero instead, specifically the hero’s direction.
Joypad revisited
I posted my joypad reading code in a previous post, but here it is again for easy reference:
update_joypad_data: ;props to blargg for A-only joypad read.
lda joypad1
sta joypad1_old
lda #%01111111
sta joypad1
sta $4016
asl a
sta $4016
@loop:
lda $4016
and #$03 ;props to Disch for Famicom support
cmp #$01
ror joypad1 ;right, left, down, up, start, select, B, A
bcs @loop
lda joypad1_old
eor #$FF
and joypad1
sta joypad1_pressed ;this tracks off-to-on transitions.
lda joypad1
eor #$FF
and joypad1_old
sta joypad1_released ;this tracks on-to-off transitions
rts
Before, I was checking joypad_pressed to determine whether or not to change a room. This was so that if the player held down a button, it would only change rooms once (instead of once per frame held). But now that I’m going to be using input to control the sprite, it makes more sense to check joypad1 and use every frame’s input. If the player holds down the d-pad, the sprite should keep moving.
But I’m not quite ready to move yet!
Changing Direction
I want to rewrite my input handler so that it takes d-pad input and uses it to set the hero’s direction. This sounds pretty straightforward, but there are some special cases I need to be wary of: what happens if the player presses left+right? or up+down? This isn’t likely to happen on a real controller, but most people play Nintendo games on emulators these days. If you don’t protect against these strange key combinations, you open yourself up to some pretty bizarre glitches, like the Zelda 2 acceleration glitch (commentator talks about it around the 4:20 mark):
I’m going to work around this problem by assigning a single direction to these weird combinations. But first we need to look at our input. In my joypad reading routine above, I store the button states in a variable called joypad1. The left 4 bits of joypad1 will hold the d-pad states and the right 4 bits will hold the states of the other four buttons. First I want to isolate the d-pad bits:
lda joypad1
and #$F0
beq @end
lsr
lsr
lsr
lsr
;now the d-pad button states are in the right nibble.
;do change direction stuff here.
@end:
rts
The right nibble of the A register now holds the d-pad button states. Next I will build a look-up table, assigning a direction to each possible combination of d-pad presses. Let’s look at the combinations. There are sixteen possibilities in all:
0000xxxx
||||
|||+--up
||+---down
|+----left
+-----right
0000 = no arrows pressed (will never happen)
0001 = up
0010 = down
0011 = up+down
0100 = left
0101 = left+up
0110 = left+down
0111 = left+up+down
1000 = right
1001 = right+up
1010 = right+down
1011 = right+up+down
1100 = right+left
1101 = right+left+up
1110 = right+left+down
1111 = right+left+down+up
The highlighted ones are the problem combinations. I will need to assign a single, specific direction to them. For example in the case of right+left, I will just choose one: left. Let’s turn this into a lookup table. Recall that I have a set of constants assigning a value to each direction (for indexing into CHR lookup tables among other things):
;direction indexes for tables
SPRITE_UP = $00
SPRITE_DOWN = $01
SPRITE_LEFT = $02
SPRITE_RIGHT = $03
SPRITE_UP_LEFT = $04
SPRITE_UP_RIGHT = $05
SPRITE_DOWN_LEFT = $06
SPRITE_DOWN_RIGHT = $07
Now I will make a lookup table assigning these constant values to the various button combinations:
direction_change_table:
.byte $FF ;0000 dummy value
.byte SPRITE_UP ;0001, up
.byte SPRITE_DOWN ;0010, down
.byte SPRITE_UP ;0011, up+down
.byte SPRITE_LEFT ;0100, left
.byte SPRITE_UP_LEFT ;0101, left+up
.byte SPRITE_DOWN_LEFT ;0110, left+down
.byte SPRITE_UP_LEFT ;0111, left+up+down
.byte SPRITE_RIGHT ;1000, right
.byte SPRITE_UP_RIGHT ;1001, right+up
.byte SPRITE_DOWN_RIGHT ;1010, right+down
.byte SPRITE_DOWN_RIGHT ;1011, right+up+down
.byte SPRITE_LEFT ;1100, left+right
.byte SPRITE_UP_RIGHT ;1101, left+right+up
.byte SPRITE_DOWN_RIGHT ;1110, left+right+down
.byte SPRITE_DOWN_LEFT ;1111, left+right+up+down
Now all button combinations have a single direction associated with each of them. All that I have left to do is read from this table and set the hero’s direction, like so:
handle_joypad:
lda joypad1
and #$F0
beq @end
lsr
lsr
lsr
lsr
tay ;right nibble has the d-pad button states. use as index
lda direction_change_table, y
sta hero_direction
@end:
rts
Changing the sprite
The rest of the work is already done for me. I already have a routine update_hero_sprite (see last post) that takes hero_direction and uses it to index into some CHR lookup tables. I don’t have to change anything to get the new sprites to display. It works! (you can see the input in the bottom left of each picture):
If I press up, the sprite faces up.
Pressing down+right makes her face southeast
Left+Right gets mapped to left.
up+down+left+right
Conclusion
My hero sprite is now capable of looking in 8 directions. I use a lookup table to assign a specific direction to each possible d-pad button combination. The next step is to actually move her in the direction she is facing. And when she is moving, I will want to animate her. Stay tuned!






