Gamepad Queries über DirectInput: DualShock 4

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Jan125
Beiträge: 31
Registriert: 23.06.2013 06:26
Computerausstattung: Nicht lachen. Atom Z3775, 2GiB RAM, Win8.1.

Gamepad Queries über DirectInput: DualShock 4

Beitrag von Jan125 »

Hier mal eine kleine Prozedur zur Abfrage von Buttons auf einem DualShock 4. (Der schnellen Amazon-Lieferung sei dank. :P)

Code: Alles auswählen

Macro NextBit
  (#PB_Compiler_EnumerationValue-1)*2
EndMacro

Enumeration GAMEPAD_DS4 1
  #GAMEPAD_DS4_TOUCH
  #GAMEPAD_DS4_OPTIONS = NextBit
  #GAMEPAD_DS4_SHARE = NextBit
  #GAMEPAD_DS4_PS = NextBit
  
  #GAMEPAD_DS4_SQUARE = NextBit
  #GAMEPAD_DS4_CROSS = NextBit
  #GAMEPAD_DS4_CIRCLE = NextBit
  #GAMEPAD_DS4_TRIANGLE = NextBit
  
  #GAMEPAD_DS4_L1 = NextBit
  #GAMEPAD_DS4_R1 = NextBit
  #GAMEPAD_DS4_L2 = NextBit
  #GAMEPAD_DS4_R2 = NextBit
  
  #GAMEPAD_DS4_DPAD_X = NextBit
  #GAMEPAD_DS4_DPAD_Y = NextBit
  #GAMEPAD_DS4_DPAD_LEFT = NextBit
  #GAMEPAD_DS4_DPAD_DOWN = NextBit
  #GAMEPAD_DS4_DPAD_RIGHT = NextBit
  #GAMEPAD_DS4_DPAD_UP = NextBit
  
  #GAMEPAD_DS4_LSTICK_X = NextBit
  #GAMEPAD_DS4_LSTICK_Y = NextBit
  #GAMEPAD_DS4_LSTICK_Z = NextBit
  #GAMEPAD_DS4_LSTICK_LEFT = NextBit
  #GAMEPAD_DS4_LSTICK_DOWN = NextBit
  #GAMEPAD_DS4_LSTICK_RIGHT = NextBit
  #GAMEPAD_DS4_LSTICK_UP = NextBit
  
  #GAMEPAD_DS4_RSTICK_X = NextBit
  #GAMEPAD_DS4_RSTICK_Y = NextBit
  #GAMEPAD_DS4_RSTICK_Z = NextBit
  #GAMEPAD_DS4_RSTICK_LEFT = NextBit
  #GAMEPAD_DS4_RSTICK_DOWN = NextBit
  #GAMEPAD_DS4_RSTICK_RIGHT = NextBit
  #GAMEPAD_DS4_RSTICK_UP = NextBit
EndEnumeration

UndefineMacro NextBit

Procedure.l GetDS4State(JoystickID.l, Query.l, Mode.l = #PB_Absolute, Treshold.l = 0)
  ;Joystick: The ID of the joystick to be queried.
  ;Query: The button/pad-query. LSTICK, RSTICK, and DPAD axes will return -1(000) on UP and LEFT-events. DPAD returns Y-inverted data, this procedure compensates for that.
  ;Mode: #PB_Absolute: Returns 1, 0, or -1. #PB_Relative: Returns a value between -1000 and 1000.
  ;Treshold: If Mode is #PB_Relative, only return a value if its absolute value is equal to or greater than Treshold. A value of ~100+ is recommended.
  Protected ReturnValue.l = 0
  Select Query
    Case #GAMEPAD_DS4_TOUCH
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 14)
        Case #PB_Relative
          ReturnValue = JoystickButton(JoystickID, 14)*1000
      EndSelect
      
    Case #GAMEPAD_DS4_OPTIONS
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 10)
        Case #PB_Relative
          ReturnValue = JoystickButton(JoystickID, 10)*1000
      EndSelect
      
    Case #GAMEPAD_DS4_SHARE
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 9)
        Case #PB_Relative
          ReturnValue = JoystickButton(JoystickID, 9)*1000
      EndSelect
      
    Case #GAMEPAD_DS4_PS
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 13)
        Case #PB_Relative
          ReturnValue = JoystickButton(JoystickID, 13)*1000
      EndSelect
      
    Case #GAMEPAD_DS4_SQUARE
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 1)
        Case #PB_Relative
          ReturnValue = JoystickButton(JoystickID, 1)*1000
      EndSelect
      
    Case #GAMEPAD_DS4_CROSS
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 2)
        Case #PB_Relative
          ReturnValue = JoystickButton(JoystickID, 2)*1000
      EndSelect
      
    Case #GAMEPAD_DS4_CIRCLE
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 3)
        Case #PB_Relative
          ReturnValue = JoystickButton(JoystickID, 3)*1000
      EndSelect
      
    Case #GAMEPAD_DS4_TRIANGLE
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 4)
        Case #PB_Relative
          ReturnValue = JoystickButton(JoystickID, 4)*1000
      EndSelect
      
    Case #GAMEPAD_DS4_L1
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 5)
        Case #PB_Relative
          ReturnValue = JoystickButton(JoystickID, 5)*1000
      EndSelect
      
    Case #GAMEPAD_DS4_R1
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 6)
        Case #PB_Relative
          ReturnValue = JoystickButton(JoystickID, 6)*1000
      EndSelect
      
    Case #GAMEPAD_DS4_L2
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 7)
        Case #PB_Relative
          ReturnValue = ((JoystickAxisX(JoystickID, 1, #PB_Relative)+1000)/2)
      EndSelect
      
    Case #GAMEPAD_DS4_R2
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 8)
        Case #PB_Relative
          ReturnValue = ((JoystickAxisY(JoystickID, 1, #PB_Relative)+1000)/2)
      EndSelect
      
    Case #GAMEPAD_DS4_LSTICK_X
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickAxisX(JoystickID, 0, #PB_Absolute)
        Case #PB_Relative
          ReturnValue = JoystickAxisX(JoystickID, 0, #PB_Relative)
      EndSelect
      
    Case #GAMEPAD_DS4_LSTICK_Y
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickAxisY(JoystickID, 0, #PB_Absolute)
        Case #PB_Relative
          ReturnValue = JoystickAxisY(JoystickID, 0, #PB_Relative)
      EndSelect
      
    Case #GAMEPAD_DS4_LSTICK_Z
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 11)
        Case #PB_Relative
          ReturnValue = JoystickButton(JoystickID, 11)*1000
      EndSelect
      
    Case #GAMEPAD_DS4_LSTICK_LEFT
      Select Mode
        Case #PB_Absolute
          ReturnValue = Bool(JoystickAxisX(JoystickID, 0, #PB_Absolute) < 0)
        Case #PB_Relative
          ReturnValue = -JoystickAxisX(JoystickID, 0, #PB_Relative)*Bool(JoystickAxisX(JoystickID, 0, #PB_Relative) < 0)
      EndSelect
      
    Case #GAMEPAD_DS4_LSTICK_DOWN
      Select Mode
        Case #PB_Absolute
          ReturnValue = Bool(JoystickAxisY(JoystickID, 0, #PB_Absolute) > 0)
        Case #PB_Relative
          ReturnValue = JoystickAxisY(JoystickID, 0, #PB_Relative)*Bool(JoystickAxisY(JoystickID, 0, #PB_Relative) > 0)
      EndSelect
      
    Case #GAMEPAD_DS4_LSTICK_RIGHT
      Select Mode
        Case #PB_Absolute
          ReturnValue = Bool(JoystickAxisX(JoystickID, 0, #PB_Absolute) > 0)
        Case #PB_Relative
          ReturnValue = JoystickAxisX(JoystickID, 0, #PB_Relative)*Bool(JoystickAxisX(JoystickID, 0, #PB_Relative) > 0)
      EndSelect
      
    Case #GAMEPAD_DS4_LSTICK_UP
      Select Mode
        Case #PB_Absolute
          ReturnValue = Bool(JoystickAxisY(JoystickID, 0, #PB_Absolute) < 0)
        Case #PB_Relative
          ReturnValue = -JoystickAxisY(JoystickID, 0, #PB_Relative)*Bool(JoystickAxisY(JoystickID, 0, #PB_Relative) < 0)
      EndSelect
      
    Case #GAMEPAD_DS4_RSTICK_X
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickAxisZ(JoystickID, 0, #PB_Absolute)
        Case #PB_Relative
          ReturnValue = JoystickAxisZ(JoystickID, 0, #PB_Relative)
      EndSelect
      
    Case #GAMEPAD_DS4_RSTICK_Y
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickAxisZ(JoystickID, 1, #PB_Absolute)
        Case #PB_Relative
          ReturnValue = JoystickAxisZ(JoystickID, 1, #PB_Relative)
      EndSelect
      
    Case #GAMEPAD_DS4_RSTICK_Z
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickButton(JoystickID, 12)
        Case #PB_Relative
          ReturnValue = JoystickButton(JoystickID, 12)*1000
      EndSelect
      
    Case #GAMEPAD_DS4_RSTICK_LEFT
      Select Mode
        Case #PB_Absolute
          ReturnValue = Bool(JoystickAxisZ(JoystickID, 0, #PB_Absolute) < 0)
        Case #PB_Relative
          ReturnValue = -JoystickAxisZ(JoystickID, 0, #PB_Relative)*Bool(JoystickAxisZ(JoystickID, 0, #PB_Relative) < 0)
      EndSelect
      
    Case #GAMEPAD_DS4_RSTICK_DOWN
      Select Mode
        Case #PB_Absolute
          ReturnValue = Bool(JoystickAxisZ(JoystickID, 1, #PB_Absolute) > 0)
        Case #PB_Relative
          ReturnValue = JoystickAxisZ(JoystickID, 1, #PB_Relative)*Bool(JoystickAxisZ(JoystickID, 1, #PB_Relative) > 0)
      EndSelect
      
    Case #GAMEPAD_DS4_RSTICK_RIGHT
      Select Mode
        Case #PB_Absolute
          ReturnValue = Bool(JoystickAxisZ(JoystickID, 0, #PB_Absolute) > 0)
        Case #PB_Relative
          ReturnValue = JoystickAxisZ(JoystickID, 0, #PB_Relative)*Bool(JoystickAxisZ(JoystickID, 0, #PB_Relative) > 0)
      EndSelect
      
    Case #GAMEPAD_DS4_RSTICK_UP
      Select Mode
        Case #PB_Absolute
          ReturnValue = Bool(JoystickAxisZ(JoystickID, 1, #PB_Absolute) < 0)
        Case #PB_Relative
          ReturnValue = -JoystickAxisZ(JoystickID, 1, #PB_Relative)*Bool(JoystickAxisZ(JoystickID, 1, #PB_Relative) < 0)
      EndSelect
      
    Case #GAMEPAD_DS4_DPAD_X
      Select Mode
        Case #PB_Absolute
          ReturnValue = JoystickAxisX(JoystickID, 2, #PB_Absolute)
        Case #PB_Relative
          ReturnValue = JoystickAxisX(JoystickID, 2, #PB_Relative)
      EndSelect
      
    Case #GAMEPAD_DS4_DPAD_Y
      Select Mode
        Case #PB_Absolute
          ReturnValue = -JoystickAxisY(JoystickID, 2, #PB_Absolute)
        Case #PB_Relative
          ReturnValue = -JoystickAxisY(JoystickID, 2, #PB_Relative)
      EndSelect
      
    Case #GAMEPAD_DS4_DPAD_LEFT
      Select Mode
        Case #PB_Absolute
          ReturnValue = Bool(JoystickAxisX(JoystickID, 2, #PB_Absolute) < 0)
        Case #PB_Relative
          ReturnValue = -JoystickAxisX(JoystickID, 2, #PB_Relative)*Bool(JoystickAxisX(JoystickID, 2, #PB_Relative) < 0)
      EndSelect
      
    Case #GAMEPAD_DS4_DPAD_DOWN
      Select Mode
        Case #PB_Absolute
          ReturnValue = Bool(JoystickAxisY(JoystickID, 2, #PB_Absolute) < 0)
        Case #PB_Relative
          ReturnValue = -JoystickAxisY(JoystickID, 2, #PB_Relative)*Bool(JoystickAxisY(JoystickID, 2, #PB_Relative) < 0)
      EndSelect
      
    Case #GAMEPAD_DS4_DPAD_RIGHT
      Select Mode
        Case #PB_Absolute
          ReturnValue = Bool(JoystickAxisX(JoystickID, 2, #PB_Absolute) > 0)
        Case #PB_Relative
          ReturnValue = JoystickAxisX(JoystickID, 2, #PB_Relative)*Bool(JoystickAxisX(JoystickID, 2, #PB_Relative) > 0)
      EndSelect
      
    Case #GAMEPAD_DS4_DPAD_UP
      Select Mode
        Case #PB_Absolute
          ReturnValue = Bool(JoystickAxisY(JoystickID, 2, #PB_Absolute) > 0)
        Case #PB_Relative
          ReturnValue = JoystickAxisY(JoystickID, 2, #PB_Relative)*Bool(JoystickAxisY(JoystickID, 2, #PB_Relative) > 0)
      EndSelect
      
  EndSelect
  Select Mode
    Case #PB_Absolute
      ProcedureReturn ReturnValue
    Case #PB_Relative
      ProcedureReturn ReturnValue*Bool(Abs(ReturnValue) >= Treshold)
  EndSelect
EndProcedure

Procedure.l GetDS4StateOrKeyPushed(KeyboardEnabled.l, JoystickEnabled.l, KeyboardKey.l, Joystick.l, DS4Query.l, Mode.l = #PB_Absolute, Treshold.l = 0)
  Protected ReturnValue.l = 0
  Select Mode
    Case #PB_Absolute
      If KeyboardEnabled
        ReturnValue = Bool(KeyboardPushed(KeyboardKey) <> 0)
      EndIf
      If JoystickEnabled And ReturnValue = 0
        ReturnValue = GetDS4State(JoystickID, DS4Query, #PB_Absolute, Treshold)
      EndIf
    Case #PB_Relative
      If KeyboardEnabled
        ReturnValue = Bool(KeyboardPushed(KeyboardKey) <> 0)*1000
      EndIf
      If JoystickEnabled And ReturnValue = 0
        ReturnValue = GetDS4State(JoystickID, DS4Query, #PB_Relative, Treshold)
      EndIf
  EndSelect
  
  ProcedureReturn ReturnValue
EndProcedure

Procedure.l GetDS4StateConditional(JoystickEnabled.l, JoystickID.l, Query.l, Mode.l = #PB_Absolute, Treshold.l = 0)
  Protected ReturnValue.l = 0
  If JoystickEnabled
    ReturnValue = GetDS4State(JoystickID, Query, Mode, Treshold)
  EndIf
  ProcedureReturn ReturnValue
EndProcedure

CompilerIf #PB_Compiler_IsMainFile
  If InitJoystick()
  Repeat
    ExamineJoystick(0)
    Debug "RStick_X_Digital: "+GetDS4StateOrKeyPushed(0, 1, #PB_Key_Space, 0, #GAMEPAD_DS4_RSTICK_X, #PB_Absolute)
    Debug "RStick_X_Analog: "+GetDS4StateOrKeyPushed(0, 1, #PB_Key_Space, 0, #GAMEPAD_DS4_RSTICK_X, #PB_Relative, 100)
    Delay(50)
  ForEver
  EndIf
CompilerEndIf
Wer braucht schon Unicode? PB5.24LTS