Get JoyStick trigger values separately using 'xinput1_3.dll'

Post your working scripts, libraries and tools
Posts: 2
Joined: 19 Mar 2020, 18:15

Get JoyStick trigger values separately using 'xinput1_3.dll'

Post by Endif_ » 19 Mar 2020, 18:44

The native JoyZ variable returns an ambiguous value. The value is 50 at default and the right trigger adds 50 and the left trigger subtracts 50.

So when no triggers are pressed, JoyZ = 50
When the right trigger is pressed, JoyZ = 100
When the left trigger is pressed, JoyZ = 0
When both triggers are pressed, JoyZ = 50

So there's no way to tell the difference between both triggers being pressed and no triggers being pressed.

This script is an example of how you can use the 'xinput1_3' Windows DLL to tell each trigger press independently.

Code: Select all

SetBatchLines, -1

; Thanks to tidbit in IRC for insights and ShatterCoder for his Google magic to link me to grayatrox's functions

XUSER_MAX_COUNT                      := 4 ; userIndex starts at 0, not 1 like I orginally assumed
dll := "xinput1_3.dll"
xLib := initController()
userIndex := 0

Gui, Add, Text, x2 y2 w15 h20 vtext1, Text1
Gui, Show, w200 h22, JoyDebug

SetTimer, ControllerRoutine, 10

leftTrigger := XInputGetStateEx("left",userIndex,xLib)
rightTrigger := XInputGetStateEx("right",userIndex,xLib)
triggers:=(leftTrigger > 10000 ? 1 : 0) . (rightTrigger > 10000 ? 1 : 0) ;Since other buttons are also mapped to the same byte in memory, you have to check if it's greater than 10000. Though the function will return a flexible value depending on how hard you press the triggers.
GuiControl,, text1, %triggers%

;~ 2GuiClose:

;Following functions written by grayatrox with a little of my own modification. Thanks a bunch grayatrox! Even though you probably weren't aware you helped me a bunch. :)

initController(dll = "xinput1_3.dll"){
    if (!xLib := DllCall("LoadLibrary", "str", dll)){
         Msgbox ERROR: Unable to load %dll%!
    return xLib

XInputGetStateEx(trigger,userIndex,byRef xLib){

    VarSetCapacity(XINPUT_STATE, 16, 0)
    xAddress := DllCall("GetProcAddress", "Uint", xLib, "Uint", 100)
    xResult := DllCall(xAddress, "Uint", userIndex, "Ptr", &XINPUT_STATE, "Char", leftTrigger, "Char", rightTrigger) ; assuming this dllcall is XInputGetStateEx

        return -1
	if (trigger = "left")
		triggerResult := NumGet(XINPUT_STATE, 5, "UShort")
    else if (trigger = "right")
		triggerResult := NumGet(XINPUT_STATE, 6, "UShort")

    return triggerResult

Return to “Scripts and Functions”