Difference between revisions of "Reading Controllers"
|Line 182:||Line 182:|
== Conclusion ==
== Conclusion ==
Revision as of 07:32, 5 December 2019
Wait for controller movement
The simplest use of hand controller is to just pause and wait for a movement, this subroutine does just that, you call it with:
; your program, waiting for any user input ; wait for controller movement pi wait.4.controller.input ; when either hand control has been moved in some direction ; program continues.... ; here's the actual subroutine, copy and paste to your program where convenient wait.4.controller.input: ; see if one of the hand controllers has moved clr ; clear accumulator outs 0 ; enable input from both hand controllers outs 1 ; clear latch of port of right hand controller ins 1 ; fetch inverted data from right hand controller com ; re-invert controller data (a %1 now means active) bnz wait.4.controller.input.end ; if no movement then input is 0 -> no branch ; check the other controller clr ; clear accumulator outs 4 ; clear latch of port of left hand controller ins 4 ; fetch inverted data from left hand controller com ; re-invert controller data (a %1 now means active) bnz wait.4.controller.input.end ; if anything was %1 jump to end of subroutine br wait.4.controller.input ; otherwise re-test until we have some movement wait.4.controller.input.end: pop ; return from subroutine
Controller directions in the register
After the hand controller data has been read you can invert it back since it is inverted when output from the controller buffer - we do that to get the real data back and because it might be easier to work with later on. The 8 bits is stored in Accumulator (A) and the bits mean this:
direction bit 0 right bit 1 left bit 2 backward bit 3 forward bit 4 counterclockwise bit 5 clockwise bit 6 pull up bit 7 push down
So if we get the value %10000000 that means the hand controller read is being pushed down.
Port-data %00000001 right %00000010 left %00000100 backward %00001000 forward %00010000 counterclockwise %00100000 clockwise %01000000 pull up %10000000 push down Combinations are possible to: %10000010 push down + left There are combinations that are impossible with a normal fully functional controller since they are opposite directions: %11000000 push down + pull up The "Jet Stick" however could do this as the fire button is parallel to the push down function.
After reading the controller/s you can store the result in a register (or in available RAM) for use later or check directly which direction was chosen. Let's suppose you have a game where you can move forward, backward, right or left with the right hand controller. If we store the result of the controller in register 8, this is how to do it:
Store result for later use
store.right.controller.input: clr outs 0 outs 1 ; check right hand controller ins 1 com ; re-invert controller data lr 8, A ; store result in register 8 store.right.controller.input.end: Later in the program we can load the movement and mask away the directions we're interested in. ; program program ; ... lr A, 8 ; copy register 8 to Ackumulator ni %00001111 ; AND result and only keep the last nibble lr 8, A ; back up result in r8 again ; ... ; program continues We now have one of these bit patterns in r8: %00000000 no movement %00000001 right %00000010 left %00000100 backward %00000101 backward + right %00000110 backward + left %00001000 forward %00001001 forward + right %00001010 forward + left Nothing else is possible with your normal controller unless something is broken. The controller value can then be compared to the values above to decide what to do next, move the player perhaps.
This code reads the buttons, you can then mask this result similar to the hand controller:
; read buttons clr ; Needs to be cleared at least once in the code outs 0 ins 0 ; get input from port 0 com ; invert lr 4, A ; store button result in register 4 li 128 ; load timer value for debounce lr 5, A ; in register 5 debounce: ; this is a delay to wait until button contacts stops bouncing ds 5 bnz debounce ; decrease r5 until zero lr A, 4 ; load button result into Ackumulator again ni %00000010 ; mask out button #2 bnz main.buttons.used.two ; not zero means button 2 was pressed lr A, 4 ; load read result into A again ni %00000001 ; check if it was button #1 bnz main.buttons.used.one ; if that's not 0 it means button 1 was held br main.continue ; continue program
The intelligent reader has already figured out the rest of the inputs available:
%00000001 button 1 %00000010 button 2 %00000011 %00000100 button 3 %00000101 %00000110 %00000111 %00001000 button 4 %00001001 %00001010 %00001011 %00001100 button 4 + 3 %00001101 %00001110 %00001111 all buttons pressed Combinations are pretty clear.
Quickest controller read
readController: clr outs 0 outs 1 ins 1 pop
This one only reads data for right controller as port read is faster on the CPU where right controller is hooked up. Data is not inverted, for an active movement the bit is set to 0, any masking is done in the main program if needed.
Read right hand controller this way:
clr outs 0 outs 1 ins 1 com
Read left hand controller this way:
clr outs 4 ins 4 com
Read buttons with:
clr outs 0 ins 0 com ; you may need to debounce as described above
And you have the result in A