Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

XInput - Xbox 360 Controller API


  • Please log in to reply
57 replies to this topic
Daniel_
  • Members
  • 16 posts
  • Last active: Jun 21 2011 04:10 AM
  • Joined: 15 May 2011

I too ran into the message:
"Failed to initialize XInput: function not found."

I poured through the code myself and couldn't find anything wrong with it. After doing some heavy research I came across something and the answer hit me like a ton of bricks.

In the XInput_Init() function, GetProcAddress is used to get the function addresses of the XInputGetState, XInputSetState, and XInputGetCapabilities from the xinput1_3.dll. Unfortunately, GetProcAddress doesn't work in unicode.

For those of us that have installed the most recent version of AutoHotKey and/or are running on 64-bit systems are using the unicode version of AutoHotKey.

I installed the 32-bit ANSI version of AHK and XInput ran flawlessly. Looks like we 64-bit users need to find an alternative method instead of GetProcAddress or just use the 32-bit version of AHK.



Alright, I've installed 32bit ansi and ran the script posted by the naked general and...

I got rid of the "Failed to initialize XInput: function not found." message but the tooltip still showed no value, than i realised that...

my controller was not plugged... :lol: :lol: :lol: :lol:

It's working now, thanks man...
you're my saviour

JPFlash
  • Guests
  • Last active:
  • Joined: --
Not willing to give up on this, I kept doing research and found out that GetProcAddress is working fine, except that it is getting passed a unicode string instead of the expected ANSI string. As a result, it returns a NULL address and the error-checking reveals that the functions did not load.

DllCall() supports a few extra argument types such as AStr and WStr. AStr is an ANSI string type and WStr is a unicode string type. All that needs to be done is just adjust the argument type that gets passed in during DllCall() from "str" to "AStr" so that GetProcAddress is passed the ANSI string it needs.

Within XInput_Init():
_XInput_GetState        := DllCall("GetProcAddress" ,"uint",_XInput_hm ,"str","XInputGetState")
_XInput_SetState        := DllCall("GetProcAddress" ,"uint",_XInput_hm ,"str","XInputSetState")
_XInput_GetCapabilities := DllCall("GetProcAddress" ,"uint",_XInput_hm ,"str","XInputGetCapabilities")
Becomes:
_XInput_GetState        := DllCall("GetProcAddress" ,"uint",_XInput_hm ,"AStr","XInputGetState")
_XInput_SetState        := DllCall("GetProcAddress" ,"uint",_XInput_hm ,"AStr","XInputSetState")
_XInput_GetCapabilities := DllCall("GetProcAddress" ,"uint",_XInput_hm ,"AStr","XInputGetCapabilities")
Now it works fine on the 64-bit unicode version of AHK!

Additionally, my research led me to find that LoadLibrary has a unicode version called LoadLibraryW. After making the argument changes it didn't seem to matter which version of LoadLibrary was used, they both worked fine. However, I wonder which is best to use with the 64-bit unicode version of AHK. Any thoughts on that?

Example:
_XInput_hm := DllCall("LoadLibrary" ,"str",dll)

-or-

_XInput_hm := DllCall("LoadLibraryW" ,"str",dll)


nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
LoadLibraryW should allow you to pass a unicode string.

rohhbert2
  • Members
  • 4 posts
  • Last active: Nov 30 2011 12:14 PM
  • Joined: 28 Nov 2011
maybe somebody has a use for this, i stumbled upon it while searching for a tool to get deadzones in Richard Burns Rally ( and it worked )


-> third party open source drivers for the xbox controllers

<!-- m -->http://translate.goo...?s ... F~morii/<!-- m -->

<!-- m -->http://www.katch.ne.jp/~morii/<!-- m -->

chrweaver
  • Guests
  • Last active:
  • Joined: --
i'm trying to get this to work with SetTimer, but i can only get this to work with a loop.

for example, i would like to have a set timer that is persistent:

SetTimer, checkRTrig, 20
SetTimer, checkLTrig, 20

and it would do the following:

checkRTrig:
if (r trigger is down)
send {key}
return

checkLTrig:
if (l trigger is down)
send {diff. key}
return

any help is definitely appreciated! thank you!

JamixZol
  • Members
  • 54 posts
  • Last active: Jan 22 2014 04:35 AM
  • Joined: 26 Mar 2012
Here's a trigger test script I wrote a while back, I've commented where you would put the send keys for demonstration.
Notice the settimers at the top there, took some trial and error to get it right.
Hope it helps :D
XInput_Init() 

Threshold = 64 ; for trigger deadzones
	
; I recomend the set to 1 here, works better than "ON" flag
SetTimer, TRIGGERWATCH, 1
SetTimer, GOOD_VIBRATIONS, 1

#include xinput.ahk ; the goods
;~ #include JSON.ahk ; Uncomment if JSON is not in your standard lib 
return

Esc::
ExitApp ; GTFO
return

TRIGGERSTATE:
; Keys to bind to triggers.
LT_Key = Null
RT_Key = Null

LastRT := LastLT := 0
XInput_Init()
    Loop, 4 {
        if XInput_GetState(A_Index-1, State)=0 {
            LT := json(State,"bLeftTrigger")
            RT := json(State,"bRightTrigger")
            BT := json(State,"wButtons")
            ;~ XInput_SetState(A_Index-1, LT*257, RT*257) ; VIBRATE!
        }
	}
return

TRIGGERWATCH:
gosub TRIGGERSTATE ; redundantly redundant
if (LT > Threshold and RT > Threshold) ;Both triggers are held
vibewait := 10 [color=#FF0000]; this is where the send logic can be placed[/color]
if (LT <= Threshold and RT <= Threshold) ;No triggers are held
vibewait := 9 [color=#FF0000]; and here[/color]
if (LT > Threshold and RT <= Threshold) ;Left trigger is held
vibewait := 4 [color=#FF0000]; and here[/color]
if (LT <= Threshold and RT > Threshold) ;Right trigger is held
vibewait := 8 [color=#FF0000][color=#FF0000]; and here[/color][/color]

Tooltip I'M AN ANOYING TOOLTIP! `n`nLTrigger-%LT%     RTrigger-%RT%`n  Button Info-%BT%`nvibewait-%vibewait%

return

GOOD_VIBRATIONS:
; these vibration routines were pulled from my WoW health rumble script http://www.autohotkey.com/community/viewtopic.php?t=75729

If vibewait < 9
{
		Loop, 4 { 
			if XInput_GetState(A_Index-1, State)=0 {  
				XInput_SetState(A_Index-1, vibewait*4000, vibewait*8000) ;MAX 65535
				sleep 100
				XInput_SetState(A_Index-1, vibewait*8191, vibewait*16383) ;MAX 65535
				sleep 250
				XInput_SetState(A_Index-1, vibewait*8000, vibewait*4000) ;MAX 65535
				sleep 100
				XInput_SetState(A_Index-1, vibewait*16383, vibewait*8191) ;MAX 65535 big 16383 low 8191
				Sleep 250
				XInput_SetState(A_Index-1, vibewait*4000, vibewait*8000) ;MAX 65535
				sleep 100
				XInput_SetState(A_Index-1, vibewait*8191, vibewait*16383) ;MAX 65535
				sleep 250
				XInput_SetState(A_Index-1, 0, 0) ;MAX 65535
				sleep 2000/vibewait
													} 
				}
}
If vibewait > 9
{
	; you have died of dysentery
ISDEAD = YUP!
		Loop, 4 { 
			if XInput_GetState(A_Index-1, State)=0 {  
				XInput_SetState(A_Index-1, vibewait*10, vibewait*500) ;MAX 65535
				sleep 500
				XInput_SetState(A_Index-1, vibewait*500, vibewait*1000) ;MAX 65535
				sleep 500
				XInput_SetState(A_Index-1, vibewait*1000, vibewait*4000) ;MAX 65535
				sleep 500
				XInput_SetState(A_Index-1, vibewait*4000, vibewait*1000) ;MAX 65535 big 16383 low 8191
				Sleep 500
				XInput_SetState(A_Index-1, vibewait*1000, vibewait*500) ;MAX 65535
				sleep 500
				XInput_SetState(A_Index-1, vibewait*500, vibewait*10) ;MAX 65535
				sleep 500
				XInput_SetState(A_Index-1, 0, 0) ;MAX 65535
				sleep 10000/vibewait
				XInput_SetState(A_Index-1, vibewait*500, vibewait*10) ;MAX 65535
				sleep 500
				XInput_SetState(A_Index-1, vibewait*1000, vibewait*500) ;MAX 65535
				sleep 500
				XInput_SetState(A_Index-1, vibewait*4000, vibewait*1000) ;MAX 65535 big 16383 low 8191
				sleep 500
				XInput_SetState(A_Index-1, vibewait*1000, vibewait*4000) ;MAX 65535
				Sleep 500
				XInput_SetState(A_Index-1, vibewait*500, vibewait*1000) ;MAX 65535
				sleep 500
				XInput_SetState(A_Index-1, vibewait*10, vibewait*500) ;MAX 65535
				sleep 500
				XInput_SetState(A_Index-1, 0, 0) ;MAX 65535
				sleep 10000/vibewait
													} 
				}
return
}
else
{
		Loop, 4 { 
			if XInput_GetState(A_Index-1, State)=0 {  
				XInput_SetState(A_Index-1, 0, 0) ;MAX 65535
													} 
				} 
}
return

My code is built and tested for: AutoHotkey_L
Tools:Notify()Builder Dropiler
Libs:RFN Achieve
sಠಠn

Snypa
  • Guests
  • Last active:
  • Joined: --
with xInput api, are you able to map a key to a axis value? A quick example bring, g:: JoyX 95%, JoyY 60% ?, If so, can you give a example

JamixZol
  • Members
  • 54 posts
  • Last active: Jan 22 2014 04:35 AM
  • Joined: 26 Mar 2012
As far as I know, the _SetState() function applies only to the rumble feature of the controller. This lib and the scripts presented in this thread are for detecting and responding to user input from the controller. I know some work has been done with PPJoy HERE which is a joystick virtualizer, but I can't speak to the extent of what it can do personally.
My code is built and tested for: AutoHotkey_L
Tools:Notify()Builder Dropiler
Libs:RFN Achieve
sಠಠn

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
My first post now includes two versions of XInput.ahk: the original version which uses JSON, and a new version which uses AutoHotkey_L objects.

XBox360Pad
  • Members
  • 1 posts
  • Last active: Nov 01 2012 11:57 PM
  • Joined: 01 Nov 2012
Where can I get this script? The download link is broken. The version I found elsewhere in an google code repository doesn't work.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Links updated.

FYI, I've never used a Google Code repository...

loosenut
  • Members
  • 2 posts
  • Last active: Jul 25 2013 04:59 AM
  • Joined: 13 Jul 2013

Sorry if this comment is inappropriate for reviving this thread, but I wanted to make sure you saw it, Lexikos. 

 

I managed to XInput to work with GetCapabilities:

#include XInput.ahk
XInput_Init()
output := XInput_GetCapabilities(0,XINPUT_FLAG_GAMEPAD)
For key, value in output["Vibration"]
    MsgBox %key% = %value%

This outputs "wLeftMotorSpeed = 255" and "wRightMotorSpeed = 255" with the 360 controller connected, nothing if it is not.  So far so good.

 

However, I tried a bunch of the other scripts posted on the boards, including the Nerd Vibes one, but none of them get the vibration going.

 

So I tried playing with code in XInput.ahk, to simplify it and put it in a standalone script.  This is what I wrote:

LeftMotorSpeed := 32000
RightMotorSpeed := 16000
MotorSpeed := LeftMotorSpeed|RightMotorSpeed<<16

Loop,4 {
        DllCall("XInput1_3.dll\XInputSetState","uint",A_Index-1,"uint*",MotorSpeed)
}

You'd think it would make it vibrate, but all it does is make the ring light blink in the "1" quadrant on the controller.  Any thoughts on what I'm doing wrong?  I'm running Win 8, and I've tried both the unicode and the x32 versions of AHK.



Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

Note that XInputSetState has already been wrapped in XInput.ahk as XInput_SetState(UserIndex, LeftMotorSpeed, RightMotorSpeed).  You need to load the dll before calling the function, otherwise it will be unloaded automatically after the function returns.  XInput_Init() does this and also pre-resolves the dll functions, for performance.

 

 

I'm running Win 8, and I've tried both the unicode and the x32 versions of AHK.

 

Note (trivial):

  • The 32-bit architecture on which AutoHotkey runs is "x86", which is based on the Intel 8086 CPU.  64-bit is "x86-64" or just "x64" (sometimes "amd64").  There is no "x32".
  • AutoHotkey has three versions: ANSI 32-bit, Unicode 32-bit and Unicode 64-bit.

I presume you meant that you tried both Unicode 32-bit and ANSI 32-bit.  XInput.ahk should work on any of the three versions.  Your DllCall is also correct for any of the three versions.



loosenut
  • Members
  • 2 posts
  • Last active: Jul 25 2013 04:59 AM
  • Joined: 13 Jul 2013
You need to load the dll before calling the function, otherwise it will be unloaded automatically after the function returns.

 

That's strictly a performance issue, right?  I mean, shouldn't my code work without that?

 

Right - x86, thanks. :)



Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

No.