base:joystick_input_handling
no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | base:joystick_input_handling [2015-04-17 04:32] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Joystick Input Handling - general info and examples ====== | ||
+ | By default the C64 can handle up to 2 joysticks that are connected to the 9-pin game ports. Unlike analogue joysticks used with modern PC the common C64 Joysticks were usually " | ||
+ | |||
+ | The state of those switches can be read from the $dc00 (gameport 2) and $dc01 (port1) registers of CIA1, with the bits used as follows: | ||
+ | |||
+ | - - joystick up/forward | ||
+ | - - down/ | ||
+ | - - left | ||
+ | - - right | ||
+ | - - fire | ||
+ | |||
+ | C64's internal logic has it that if one of those switches is closed it will read 0, otherwise 1. For instance, if you want to branch somewhere if the firebutton of joystick was pressed the code should look like this: | ||
+ | |||
+ | < | ||
+ | lda $dc00 ;read gameport2 | ||
+ | and #$10 ; | ||
+ | beq is_pressed ;if =0 then button is down, not vice versa! | ||
+ | </ | ||
+ | |||
+ | Furthermore, | ||
+ | The above routine is ok to check certain single switches, but to process all at once the following routine by Bill Hindorf (published in the Programmer' | ||
+ | |||
+ | < | ||
+ | | ||
+ | dx .byte 0 | ||
+ | dy .byte 0 | ||
+ | |||
+ | djrr lda $dc00 ; get input from port 2 only | ||
+ | djrrb ldy #0 ; this routine reads and decodes the | ||
+ | ldx #0 ; joystick/ | ||
+ | lsr ; the accumulator. this least significant | ||
+ | bcs djr0 ; 5 bits contain the switch closure | ||
+ | dey ; information. if a switch is closed then it | ||
+ | djr0 lsr ; produces a zero bit. if a switch is open then | ||
+ | bcs djr1 ; it produces a one bit. The joystick dir- | ||
+ | iny ; ections are right, left, forward, backward | ||
+ | djr1 lsr ; bit3=right, bit2=left, bit1=backward, | ||
+ | bcs djr2 ; bit0=forward and bit4=fire button. | ||
+ | dex ; at rts time dx and dy contain 2's compliment | ||
+ | djr2 lsr ; direction numbers i.e. $ff=-1, $00=0, $01=1. | ||
+ | bcs djr3 ; dx=1 (move right), dx=-1 (move left), | ||
+ | inx ; dx=0 (no x change). dy=-1 (move up screen), | ||
+ | djr3 lsr ; dy=0 (move down screen), dy=0 (no y change). | ||
+ | stx dx ; the forward joystick position corresponds | ||
+ | sty dy ; to move up the screen and the backward | ||
+ | rts ; position to move down screen. | ||
+ | ; | ||
+ | ; at rts time the carry flag contains the fire | ||
+ | ; button state. if c=1 then button not pressed. | ||
+ | ; if c=0 then pressed. | ||
+ | </ | ||
+ | |||
+ | Now dx and dy can be used to change the player' | ||
+ | |||
+ | < | ||
+ | up .byte 0 | ||
+ | down .byte 0 | ||
+ | left .byte 0 | ||
+ | right .byte 0 | ||
+ | button .byte 0 | ||
+ | |||
+ | lda $dc00 ;read joystick port 2 | ||
+ | lsr ;get switch bits | ||
+ | ror up ; | ||
+ | lsr ; | ||
+ | ror down | ||
+ | lsr | ||
+ | ror left | ||
+ | lsr | ||
+ | ror right | ||
+ | lsr | ||
+ | ror button | ||
+ | rts | ||
+ | </ | ||
+ | |||
+ | The above routine generates a ' | ||
+ | |||
+ | < | ||
+ | ;isolate single fire-button taps: | ||
+ | |||
+ | bit button | ||
+ | bmi no_action | ||
+ | bvc no_action | ||
+ | |||
+ | jsr just_pressed ;else it has just been tapped, thus react | ||
+ | |||
+ | no_action ... | ||
+ | </ | ||
+ | |||
+ | ...or like this: | ||
+ | |||
+ | < | ||
+ | |||
+ | ;delayed reaction: | ||
+ | |||
+ | lda up ;check for stick forward movement: | ||
+ | bne no_action ;if <> 0 then stick wasn't held up long enough | ||
+ | ;else it was up the last 8 readouts: | ||
+ | dec up ;reset history to $ff for new delay | ||
+ | jsr up_action ;and call the appropriate routine | ||
+ | |||
+ | no_action ... | ||
+ | |||
+ | </ | ||
+ | |||
+ | To achieve user-friendly menu controls, the methods above could be combined to check for both ' |
base/joystick_input_handling.txt · Last modified: 2015-04-17 04:32 by 127.0.0.1