Page 1 of 1
Question about reading input
Posted: Mon Nov 13, 2006 3:37 pm
by cooper
Hello all. I finally got NSF playback to work with ca65, and I'm currently trying to make a simple program that allows you to change songs by pressing left or right on the D-pad. I'm having issues coming up with the logic for making the left and right directions only skipping one track. I'm trying to make it so that regardless of how long you hold down left or right, it will only increment, or decrement 1 track. All of the methods I have tried so far either crash, or the song number will constantly get bigger or smaller as you have the direction pressed. Can anyone provide some psuedocode for ideas on how to do this? Sorry if I'm not being clear.
Posted: Mon Nov 13, 2006 3:48 pm
by commodorejohn
Wait until left or right is pressed.
Make the appropriate changes.
Wait until the pressed button is not pressed (or, easier, wait until no buttons are pressed.)
Repeat.
Posted: Mon Nov 13, 2006 3:56 pm
by Disch
keep track only of when the button is pressed and not when it's being held down. You can do this by recording a "previous button state" variable and comparing it to the current button state.
Assuming each button is represented as a single bit in a byte:
Code: Select all
LDA current_buttons
STA previous_buttons
JSR read_joy_data_from_4016_and_put_in_current_buttons
LDA previous_buttons
EOR #$FF
AND current_buttons
STA buttons_just_pressed
What I'm doing here is ANDing the current buttons with the inverse of the previous buttons... so that buttons which were not previously down will be masked out.
To visualize this... say that the player just pressed the left button (so previous_buttons=$00 and current_buttons=$40)
Code: Select all
LDA previous_buttons ; $00
EOR #$FF ; $FF
AND current_buttons ; $40
Now let's say that left is being held down (so previous_buttons=$40 and current_buttons=$40)
Code: Select all
LDA previous_buttons ; $40
EOR #$FF ; $BF
AND current_buttons ; $00
even though current_buttons is $40, the $40 is being dropped by the AND operation.
-- edit: changed around that first code segment to make it easier to understand --
-- edit again --
and because I'm bored... here's a sample routine to read joy data and put it in current_buttons:
Code: Select all
read_joy_data_from_4016_and_put_in_current_buttons:
LDX #$09
STX $4016 ; set strobe (only bit 0 significant)
DEX
STX $4016 ; clear strobe X now=8
: LDA $4016 ; get key state
LSR A ; move button state into C flag
ROR current_buttons ; roll C into current_buttons var
DEX
BNE :- ; rinse and repeat 8 times -- for each button
RTS
Posted: Mon Nov 13, 2006 11:05 pm
by Memblers
Here's a macro I use for all my button presses.
Code: Select all
;---------------------------------------------------------
; Check Controller
; (macro: controller button,branch,(optional)branch
;---------------------------------------------------------
.macro controller button,not_pressed,button_held
.ifblank button_held
lda joy1
and #button
beq not_pressed
.endif
.ifnblank button_held
lda joy1
and #button
beq not_pressed
and joy1old
bne button_held
.endif
.endmacro
;---------------------------------------------------------
To make it skip when it's held, I do this:
controller a_button,not_a,not_a
;do something for A press
not_a:
(a_button and all the others are just defined as single bits like %10000000)
Before reading the controller every frame I simply copy the joy1 variable into joy1old.
Posted: Wed Nov 15, 2006 6:22 am
by cooper
Disch and Memblers, thank you so much. It is working perfect now. I don't think I could have ever figured that out without your help. Cheers!
Posted: Thu Nov 16, 2006 4:47 am
by No Carrier
Cooper, do you have a test ROM? I'd love to check this out.
NC
Posted: Sat Nov 18, 2006 5:40 pm
by cooper
Sure thing. I'm trying to get a few visualation things working. Once this is finalized I'll put the source and rom up for you.