Joystick-Abfrage leicht gemacht

Wer mit einem 8bit Atari eine Joystick-Steuerung programmieren möchte, der steht vor dem Problem, den jeweiligen Zustand des Joystick abzufragen. Nun scheinen die Werte für die einzelnen Joystickbewegungen alles andere als logisch. Wer aber seinen Joystick schon mal aufgeschraubt hat, der weiß, es gibt für jede (Haupt-) Richtung einen Schalter und damit im entsprechenden Register ein Bit. Wird der Schalter gedrückt, geht das jeweilige Bit auf 0:

               oben 
      | 1010 | 1110 | 0110 |
links | 1011 | 1111 | 0111 | rechts 
      | 1001 | 1101 | 0101 |
               unten 

Damit ergeben sich folgende Richtungs-Werte bei der Joystick-Abfrage:

               oben 
      |  10  |  14  |   6  |
links |  11  |  15  |   7  | rechts 
      |   9  |  13  |   5  |
               unten 

Normalerweise will man ja eigentlich für die Horizontale und für die Vertikale nur wissen, muss ich eins weiter rücken, eins zurück oder einfach stehen bleiben. Unter der Berücksichtigung der Werte für die Diagonale kommt man schnell auf 8 IF-THEN Abfragen. Aber es geht auch anders:

Für Basic habe ich mal folgende Lösung in einem Buch gesehen:

S=STICK(0)
VSTICK=-(S=6)-(S=10)-(S=14)+(S=5)+(S=9)+(S=13)
REM N ist die Nummer des Joystick
HSTICK=PTRIG(2*N+1)-PTRIG(2*N)
REM Die Knöpfe des Drehregler entspricht den Joystick-Schaltern für Links und Rechts

Für Action habe ich zwei kleine Funktionen geschrieben:

Int FUNC HSTICK(INT joyq)
  joyq==RSH 2
  IF joyq > 1 THEN
    joyq==-3
  FI
RETURN (joyq)
 
Int FUNC VSTICK(INT joyq)
  joyq==&$F3
  IF joyq > 1 THEN
    joyq==-3
  FI
RETURN (joyq)

Beide oben genannte Lösungen haben eins gemein: Sie liefern im Ergebnis jeweils -1, 0 oder 1; man bekommt also genau die Informationen, die man eigenlich braucht.

Evolution des Actioncodes:
Version 2
kommt ohne IF-THEN aus und sollte damit schneller sein als #1:

Int FUNC HSTICK(INT joyq)
  INT aw  
 
  joyq==RSH 2
  aw=joyq &$FD
  joyq== RSH 1
  aw=aw-joyq
RETURN (aw)
 
Int FUNC VSTICK(INT joyq)
  INT aw 
 
  joyq ==&$F3
  aw=joyq &$FD
  joyq== RSH 1
  aw=aw-joyq
RETURN (aw)

Version 3
Komplett als Inline-Assembler und damit die momentan effizienteste Version.

;liefert +1 rechts -1 links und 0 für center
INT FUNC HSTICK=*(BYTE joyq)
[ $A2 $00 $A0 $00 $4A $4A $18 $4A
  $B0 $02 $CA $88 $4A $B0 $01 $E8
  $86 $A0 $84 $A1 $60 ]
 
;liefert +1 unten -1 oben und 0 für center
INT FUNC VSTICK=*(BYTE joyq)
[ $A2 $00 $A0 $00 $29 $F3 $18 $4A
  $B0 $02 $CA $88 $4A $B0 $01 $E8
  $86 $A0 $84 $A1 $60 ]

Schreib was...