Jump to content

Joystick UDF


Ejoc
 Share

Recommended Posts

  • 1 month later...

Thank You so much Ejoc and Adam1213 for your posts!

They were a great help pointing me the direction on the creation of an utility for the Logitech G25 H-Shifter.

Now I can use the H-Shifter in games that don't support it by default!

In case anyone be interested: My link

*** Update: Released a new version in 2010-08-10

*** Update: Released a new version in 2010-11-23

o.

Edited by orepmetiur
Link to comment
Share on other sites

  • 1 year later...
  • 6 months later...

Hi all, I am a total newbie, so please excuse any errors !

I am trying to play Freelancer (normally keyboard+mouse control) with my Saitek X52 Pro HOTAS and it was suggested that Autoit would sort this out.

I am running Windows 7 64 bit.

I downloaded Autoit (latest version)

I downloaded the file at the top of this thread, placed it in the include folder.

Read that it only woked on earlier version of Autoit, so deleted the file contents and replaced with post 4 (I think).

I have tried every way I can to get it to run, but nothing at all is happening. No window or anything :-(

I guess I have done something wrong - please advise.

Regards,

FD

Link to comment
Share on other sites

I haven't got a clue, but I would try running the code from within the SciTE4AutoIt editor by pressing the F5 key. See if you get any errors. You don't need to place the code in the includes folder, and I think it's best not to mess around in there at all. Also the best place to ask for help on a subject like this is in the Help and Support forum (provide links and explain your problem - just don't discuss game automation - read the rules). Adding a joystick does not infringe the rules, so you are alright, but game related questions can sometimes go wrong (just a hint of advice). :)

This is an old thread, but I didn't immediately spot anything wrong with the code. I might have missed something.

Edited by czardas
Link to comment
Share on other sites

  • 2 years later...

Sorry for resurrecting an old thread.  I am running autoit ver. 3.3.14, I'm getting errors when I try to run this program.  "Error: DllStructSize(), DllStructSet(), DllStructPtr(), DllStructGet(), DllStructFree() undefined function."  I tried replacing with DllStructGetSize(), DllStructSetData(), DllStructGetPtr(), DllStructGetData() and DllClose(), but got another error "DllCall("Winmm.dll","int","joyGetPosEx",^ ERROR".  Anybody know how to get this working?

Link to comment
Share on other sites

Sorry for resurrecting an old thread.  I am running autoit ver. 3.3.14, I'm getting errors when I try to run this program.  "Error: DllStructSize(), DllStructSet(), DllStructPtr(), DllStructGet(), DllStructFree() undefined function."  I tried replacing with DllStructGetSize(), DllStructSetData(), DllStructGetPtr(), DllStructGetData() and DllClose(), but got another error "DllCall("Winmm.dll","int","joyGetPosEx",^ ERROR".  Anybody know how to get this working?

Dllclose is not needed. 

for the dll call just put int one line.

DllCall("Winmm.dll","int","joyGetPosEx","int",$iJoy,"ptr",DllStructGetPtr($lpJoy))

or set an space on , _

 DllCall("Winmm.dll","int","joyGetPosEx", _
            "int",$iJoy, _
            "ptr",DllStructGetPtr($lpJoy))

 

Saludos

Link to comment
Share on other sites

  • 1 year later...

I use this UDF improved by Adam1213 for my program and it works fine. But for Windows 10 I need the Joystick DeviceID. It changes at every system start :(

I have found this another Joystick topic and used only the part for the ID. But it doesn't work.

#include <GUIConstants.au3>
#include <MsgBoxConstants.au3>

Local $JoyID

$JoyID = JoyGetID($JoyID)

MsgBox(262208, "TS", "The Joystick DeviceID is: " & $JoyID)

Exit

;**************************************************************
; Joystick Support by Norberto Gabriel Alvarez Raynald
; Made with AUTOIT V3.1.111 (I love it!)
; Contact: elgabionline-inbox@yahoo.com.ar
;**************************************************************

Func JoyMaxNumber() ;Maximum number of joysticks supported by system

    $Str_Dll_Winmm = DllStructCreate("int")
    $Dll_Winmm = DllOpen(@SystemDir & "\winmm.dll")
    $Joystick = DllCall($Dll_Winmm, "int", "joyGetNumDevs", "int", 0)

    Select
        Case @error
            $Str_Dll_Winmm = 0
            Return 0
        Case Else
            DllStructSetData($Str_Dll_Winmm, 1, $Joystick[0])
            $MaxNumber = DllStructGetData($Str_Dll_Winmm, 1)
            DllClose($Dll_Winmm)
            $Str_Dll_Winmm = 0
            Return $MaxNumber
    EndSelect

EndFunc   ;==>JoyMaxNumber

;**************************************************************
; JoyGetID ($Joy_number)
; $Joy_number: how You want get ID. Put a number, 1 or 2... to JoyMaxNumber ()
;~ Return -2 if Joystick not found or -3 if input param is wrong
; **********************************************************

Func JoyGetID($Joy_number) ;Get ID from Joystick driver (values between -1 and 15)

    $Max = (JoyMaxNumber() + 1)  ;MacG added 1 because of: "how You want get ID. Put a number, 1 or 2... to JoyMaxNumber ()"
    If $Max < $Joy_number Or Not StringIsDigit($Joy_number) Then Return -3
    If $Joy_number < 1 Then Return -3
    $Str_Dll_Winmm = DllStructCreate("int")
    $Dll_Winmm = DllOpen(@SystemDir & "\winmm.dll")
    $ID = DllCall($Dll_Winmm, "int", "joyGetPos", "int", $Joy_number - 1)

    Select
        Case @error
            $Str_Dll_Winmm = 0
            DllClose($Dll_Winmm)
            Return -2
        Case Else
            DllStructSetData($Str_Dll_Winmm, 1, $ID[0])
            $NumID = DllStructGetData($Str_Dll_Winmm, 1)
            DllClose($Dll_Winmm)
            $Str_Dll_Winmm = 0
            Return $NumID
    EndSelect

EndFunc   ;==>JoyGetID

 

Link to comment
Share on other sites

  • 3 months later...

Adam that script works perfectly, and it MADE MY DAY!

On ‎3‎/‎31‎/‎2007 at 2:21 AM, Adam1213 said:

 

Nice program but it did not work with Autoit 3.2, I fixed this. When I made it work its blinking (info on GUI) was really bad (fixed)

 

;____________________________________________________________________
;       Original program by Ejoc                                    ;
;       Improved by Adam1213 (autoit 3.2 compatiblity + improved labels         ;
;____________________________________________________________________

#include <GUIConstants.au3>

;_________________ SETUP_____________________________________
Local $joy,$coor,$h,$s,$msg

$joy    = _JoyInit()

dim $labels_text[8]=['X', 'Y', 'Z', 'R', 'U', 'V', 'POV', 'Buttons']
dim $labels_no=UBound($labels_text)
dim $labels[$labels_no]
dim $labels_value[$labels_no]
;__________ CONFIG ____________________________________________
;---------- Find the max length of the longest label --------------
$label_len=0
for $text in $labels_text
    $len=stringlen($text)
    if $len>$label_len then
        $label_len=$len
    endif
next
$label_len*=6
;_____________ GUI _______________________________________________
GUICreate('Joystick Test', 200, 200)
GUICtrlCreateLabel('Joystick', 40, 20, 100, 20)
    
for $i=0 to $labels_no-1
    GuiCtrlCreatelabel($labels_text[$i]&':', 10, 60+$i*12, $label_len, 12)
    $labels[$i]=GuiCtrlCreatelabel('', 10+$label_len, 60+$i*12, 70, 12)
    $labels_value[$i]=''
next
GUISetState()
;_____________________________________________________________________

while 1
    $coord=_GetJoy($joy,0)
    for $i=0 to UBound($coord)-1
        if $coord[$i]<>$labels_value[$i] then
            GUICtrlSetData($labels[$i], $coord[$i])
            $labels_value[$i]=$coord[$i]
        endif
    next
    sleep(10)
    $msg =GUIGetMSG()
    if $msg = $GUI_EVENT_CLOSE Then Exitloop
WEnd

$lpJoy=0 ; Joyclose

;======================================
;   _JoyInit()
;======================================
Func _JoyInit()
    Local $joy
    Global $JOYINFOEX_struct    = "dword[13]"

    $joy=DllStructCreate($JOYINFOEX_struct)
    if @error Then Return 0
    DllStructSetData($joy, 1, DllStructGetSize($joy), 1);dwSize = sizeof(struct)
    DllStructSetData($joy, 1, 255, 2)              ;dwFlags = GetAll
    return $joy
EndFunc

;======================================
;   _GetJoy($lpJoy,$iJoy)
;   $lpJoy  Return from _JoyInit()
;   $iJoy   Joystick # 0-15
;   Return  Array containing X-Pos, Y-Pos, Z-Pos, R-Pos, U-Pos, V-Pos,POV
;           Buttons down
;
;           *POV This is a digital game pad, not analog joystick
;           65535   = Not pressed
;           0       = U
;           4500    = UR
;           9000    = R
;           Goes around clockwise increasing 4500 for each position
;======================================
Func _GetJoy($lpJoy,$iJoy)
    Local $coor,$ret

    Dim $coor[8]
    DllCall("Winmm.dll","int","joyGetPosEx", _
            "int",$iJoy, _
            "ptr",DllStructGetPtr($lpJoy))

    if Not @error Then
        $coor[0]    = DllStructGetData($lpJoy,1,3)
        $coor[1]    = DllStructGetData($lpJoy,1,4)
        $coor[2]    = DllStructGetData($lpJoy,1,5)
        $coor[3]    = DllStructGetData($lpJoy,1,6)
        $coor[4]    = DllStructGetData($lpJoy,1,7)
        $coor[5]    = DllStructGetData($lpJoy,1,8)
        $coor[6]    = DllStructGetData($lpJoy,1,11)
        $coor[7]    = DllStructGetData($lpJoy,1,9)
    EndIf

    return $coor
EndFunc

 

Link to comment
Share on other sites

  • 1 year later...

Hey guys and gals.

 

I've been using this for years to monitor one controller at a time and it has worked great. Now I wanted to monitor more than one controller at a time but I've run into a snag.

Say I want a GUI that shows 8 controllers (0-7). The problem is that if less than 8 controllers are plugged in, the values for those (disconnected) controllers are exactly the same as the last connected controller.

Example, 2 controllers:

Controller 0 X = 45454

Controller 1 X = 23333

Controller 2 X = 23333

Controller 3 X = 23333

and so on.

 

With just one controller the values for controller 0 are shown for the rest of the controllers.

I'm not sure what I am missing here. Sure, I could check how many controllers are connected and simply not check the ones I then know are non existent, but the point of the program is that you can unplug and plug controllers in while it loops and it should update (and to be honest, I've not gotten any script that shows the number of connected controllers to work...).

How can I get it to @error out or just show 0 if the controller is not found instead of replicating the last good controllers coordinates?

Example snippet to show what I mean.

#Include <Array.au3>

Dim $coor[8]

; Setup some joystick stuff
Local $joy, $coor, $h, $s, $msg
$joy = _JoyInit()

while 1
    For $j = 0 to 7
        ConsoleWrite("Reading coords for joy " & $j & @CRLF)
        $coord = _GetJoy($joy, $j)
        _ArrayDisplay($coord)
        Sleep(1000)
    Next
WEnd

;======================================
;   _JoyInit()
;======================================
Func _JoyInit()
    Local $joy
    Global $JOYINFOEX_struct    = "dword[13]"

    $joy=DllStructCreate($JOYINFOEX_struct)
    if @error Then Return 0
    DllStructSetData($joy, 1, DllStructGetSize($joy), 1);dwSize = sizeof(struct)
    DllStructSetData($joy, 1, 255, 2)              ;dwFlags = GetAll
    return $joy
EndFunc

;======================================
;   _GetJoy($lpJoy,$iJoy)
;   $lpJoy  Return from _JoyInit()
;   $iJoy   Joystick # 0-15
;   Return  Array containing X-Pos, Y-Pos, Z-Pos, R-Pos, U-Pos, V-Pos,POV
;           Buttons down
;
;           *POV This is a digital game pad, not analog joystick
;           65535   = Not pressed
;           0       = U
;           4500    = UR
;           9000    = R
;           Goes around clockwise increasing 4500 for each position
;======================================
Func _GetJoy($lpJoy, $iJoy)

    DllCall("Winmm.dll", "int", "joyGetPosEx", _
            "int", $iJoy, _
            "ptr", DllStructGetPtr($lpJoy))

    ConsoleWrite("Status for " & $iJoy & ": " & @error & @CRLF)

    If Not @error Then
        $coor[0] = DllStructGetData($lpJoy, 1, 3)
        ;ConsoleWrite("0: " & $coor[0] & @CRLF)
        $coor[1] = DllStructGetData($lpJoy, 1, 4)
        ;ConsoleWrite("1: " & $coor[1] & @CRLF)
        $coor[2] = DllStructGetData($lpJoy, 1, 5)
        ;ConsoleWrite("2: " & $coor[2] & @CRLF)
        $coor[3] = DllStructGetData($lpJoy, 1, 6)
        ;ConsoleWrite("3: " & $coor[3] & @CRLF)
        $coor[4] = DllStructGetData($lpJoy, 1, 7)
        ;ConsoleWrite("4: " & $coor[4] & @CRLF)
        $coor[5] = DllStructGetData($lpJoy, 1, 8)
        ;ConsoleWrite("5: " & $coor[5] & @CRLF)
        $coor[6] = DllStructGetData($lpJoy, 1, 11)
        ;ConsoleWrite("6: " & $coor[6] & @CRLF)
        $coor[7] = DllStructGetData($lpJoy, 1, 9)
        ;ConsoleWrite("7: " & $coor[7] & @CRLF)
    EndIf

    Return $coor
EndFunc   ;==>_GetJoy

Another smaller issue, the first loop, it seems to not show the correct values for the controller. Values are all 32767, 65535 and 0 for the first loop.  Once it has looped once or so, the correct coordinates start to show. Since it loops all the time, this is not a problem but still a bit annoying =)

Thanks!

Edited by Turranius
Link to comment
Share on other sites

  • 1 year later...

Hello,

Am I the only one who have a problem with joyGetPosEx function ?

I think, since upgrade to windows 10, joyGetPosEx works only if a window of our own process is active.

Tell me if i'm lonely with this problem or if someone know how to bypass this restriction.

Test program :

#include <GUIConstants.au3>

Opt("GUIOnEventMode", 1)
Opt("MustDeclareVars", 1)

Global $joy
Global $gui
Global $edit
Global $size = [600, 240]
Global $oldData = ""

$gui = GUICreate("joy", $size[0], $size[1])
GUISetOnEvent($GUI_EVENT_CLOSE, quit, $gui)
$edit = GUICtrlCreateEdit("", 0, 0, $size[0], $size[1], 0)
GUICtrlSetState($edit, $GUI_DISABLE)
GUICtrlSetFont($edit, Default, Default, Default, "Courier")
GUISetState(@SW_SHOW, $gui)

$joy =      _JoyInit()
OnAutoItExitRegister(_exit_joy)

While 1
    Local $txt = "Bouton |"
    Local $touches[8][0]
    Local $padValid[UBound($touches, 1)]
    For $i = 0 To UBound($touches, 1) - 1
        Local $tches = processPad($i)
        $padValid[$i] = Not(@error)
        ReDim $touches[UBound($touches, 1)][UBound($tches, 1)]
        For $j = 0 To UBound($tches, 1) - 1
            $touches[$i][$j] = $tches[$j]
        Next
        If($padValid[$i]) Then
            $txt &= " Pad " & $i & " |"
        EndIf
    Next
    $txt &= @CRLF
    For $i = 0 To UBound($touches, 2) - 1
        $txt &= StringFormat("%6s", $i) & " |"
        For $j = 0 To UBound($touches, 1) - 1
            If($padValid[$j]) Then
                $txt &= "   " & ($touches[$j][$i] ? "1" : " ") & "   |"
            EndIf
        Next
        $txt &= @CRLF
    Next
    If($oldData <> $txt) Then
        $oldData = $txt
        GUICtrlSetData($edit, $txt)
    EndIf
    Sleep(1)
WEnd

Func processPad($num)
    Local $array =  _GetJoy($joy, $num)
    Local $touches[16]
    Local $isPadValid = StringLen($array[6]) > 0
    $touches[0] = BitAND($array[7], 1) <> 0
    $touches[1] = BitAND($array[7], 2) <> 0
    $touches[2] = BitAND($array[7], 4) <> 0
    $touches[3] = BitAND($array[7], 8) <> 0
    $touches[4] = BitAND($array[7], 16) <> 0
    $touches[5] = BitAND($array[7], 32) <> 0
    $touches[6] = BitAND($array[7], 64) <> 0
    $touches[7] = BitAND($array[7], 128) <> 0
    $touches[8] = BitAND($array[7], 256) <> 0
    $touches[9] = BitAND($array[7], 512) <> 0
    $touches[10] = BitAND($array[7], 1024) <> 0
    $touches[11] = BitAND($array[7], 2048) <> 0
    $touches[12] = $isPadValid And $array[6] < 9000 Or $array[6] > 27000 And $array[6] < 65535
    $touches[13] = $isPadValid And $array[6] > 0 And $array[6] < 18000
    $touches[14] = $isPadValid And $array[6] > 9000 And $array[6] < 27000
    $touches[15] = $isPadValid And $array[6] > 18000 And $array[6] < 36000
    Return SetError(Not($isPadValid), 0, $touches)
EndFunc

Func _JoyInit()
    Local $joy
    Global $JOYINFOEX_struct    = "dword[13]"
    $joy    = DllStructCreate($JOYINFOEX_struct)
    if @error Then Return 0
    DllStructSetData($joy,1,DllStructGetSize($joy),1);dwSize = sizeof(struct)
    DllStructSetData($joy,1,255,2)                  ;dwFlags = GetAll
    return $joy
EndFunc

Func _GetJoy($lpJoy, $iJoy)
    Local $ret
    Local $coor[9]

    $ret = DllCall("Winmm.dll", "int", "joyGetPosEx", "int", $iJoy, "ptr", DllStructGetPtr($lpJoy))

    If(Not(@error) And $ret[0] == 0) Then
        $coor[0]    = DllStructGetData($lpJoy,1,3)
        $coor[1]    = DllStructGetData($lpJoy,1,4)
        $coor[2]    = DllStructGetData($lpJoy,1,5)
        $coor[3]    = DllStructGetData($lpJoy,1,6)
        $coor[4]    = DllStructGetData($lpJoy,1,7)
        $coor[5]    = DllStructGetData($lpJoy,1,8)
        $coor[6]    = DllStructGetData($lpJoy,1,11)
        $coor[7]    = DllStructGetData($lpJoy,1,9)
        $coor[8]    = DllStructGetData($lpJoy,1,10)
    EndIf
    return $coor
EndFunc

Func _exit_joy()
    $joy = 0
EndFunc

Func quit()
    Exit
EndFunc

Try to press buttons on your pad with and without having focus on window

Edited by TommyDDR
_GUIRegisterMsg (Register more than 1 time the same Msg), _Resize_Window (GUICtrlSetResizing for children windows), _GUICtrlSetOnHover (Link a function when mouse go on, left, clic down, clic up, on a control), _InputHeure (Create an input for hour contain), _GUICtrlCalendar (Make a complete calendar), _GUICtrlCreateGraphic3D (Create a 3D graph), _ArrayEx.au3 (Array management), _GUIXViewEx.au3 (List/Tree View management).
Link to comment
Share on other sites

  • 1 year later...
On 4/24/2020 at 7:36 PM, TommyDDR said:

Hello,

Am I the only one who have a problem with joyGetPosEx function ?

I think, since upgrade to windows 10, joyGetPosEx works only if a window of our own process is active.

Tell me if i'm lonely with this problem or if someone know how to bypass this restriction.

I'm having the same problem on Windows 10.

On Windows 10, the joystick code appears to only work if one of our AutoIT GUI windows is active and focused. It doesn't appear to work otherwise.

Edited by Terrafire
Link to comment
Share on other sites

  • 1 year later...

Hi all,

I am aware this is many years old, but as I couldn't find sufficient information on how to use dinput.dll I made a start for my simple joystick tool from this thread. So I thought it would be nice to share the result with you.

I even created a readme and an icon for the exe. I doubt it is required to explain how to create an exe from the script so I just upload those three files. And I also think that you don't need example batch files to explain how to set environment variables. 😉

Thank you all for your help, not only from this thread...

readme.txt SimJoP.au3 SimJoP.ico

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...