/* XInput by Lexikos
* Requires AutoHotkey 1.1+.
*/
/*
Function: XInput_Init
Initializes XInput.ahk with the given XInput DLL.
Parameters:
dll - The path or name of the XInput DLL to load.
*/
XInput_Init(dll:="")
{
global
if _XInput_hm
return
;======== CONSTANTS DEFINED IN XINPUT.H ========
; NOTE: These are based on my outdated copy of the DirectX SDK.
; Newer versions of XInput may require additional constants.
; Device types available in XINPUT_CAPABILITIES
XINPUT_DEVTYPE_GAMEPAD := 0x01
; Device subtypes available in XINPUT_CAPABILITIES
XINPUT_DEVSUBTYPE_GAMEPAD := 0x01
; Flags for XINPUT_CAPABILITIES
XINPUT_CAPS_VOICE_SUPPORTED := 0x0004
; Constants for gamepad buttons
XINPUT_GAMEPAD_DPAD_UP := 0x1
XINPUT_GAMEPAD_DPAD_DOWN := 0x2
XINPUT_GAMEPAD_DPAD_LEFT := 0x4
XINPUT_GAMEPAD_DPAD_RIGHT := 0x8
XINPUT_GAMEPAD_MENU := 0x10
XINPUT_GAMEPAD_VIEW := 0x20
XINPUT_GAMEPAD_LEFT_STICK := 0x40
XINPUT_GAMEPAD_RIGHT_STICK := 0x80
XINPUT_GAMEPAD_LEFT_BUMPER := 0x100
XINPUT_GAMEPAD_RIGHT_BUMPER := 0x200
XINPUT_GAMEPAD_XBOX := 0x400
XINPUT_GAMEPAD_A := 0x1000
XINPUT_GAMEPAD_B := 0x2000
XINPUT_GAMEPAD_X := 0x4000
XINPUT_GAMEPAD_Y := 0x8000
; Gamepad thresholds
XINPUT_GAMEPAD_LEFT_STICK_DEADZONE := 7849
XINPUT_GAMEPAD_RIGHT_STICK_DEADZONE := 8689
XINPUT_GAMEPAD_TRIGGER_THRESHOLD := 30
; Flags to pass to XInputGetCapabilities
XINPUT_FLAG_GAMEPAD := 0x00000001
;=============== END CONSTANTS =================
if (dll = "")
Loop %A_WinDir%\System32\XInput1_*.dll
dll := A_LoopFileName
if (dll = "")
dll := "XInput1_3.dll"
_XInput_hm := DllCall("LoadLibrary" ,"str",dll ,"ptr")
if !_XInput_hm
throw Exception("Failed to initialize XInput: " dll " not found.")
(_XInput_GetState := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"ptr",100 ,"ptr"))
|| (_XInput_GetState := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputGetState" ,"ptr"))
_XInput_SetState := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputSetState" ,"ptr")
_XInput_GetCapabilities := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputGetCapabilities" ,"ptr")
if !(_XInput_GetState && _XInput_SetState && _XInput_GetCapabilities)
{
XInput_Term()
throw Exception("Failed to initialize XInput: function not found.")
}
}
/*
Function: XInput_GetState
Retrieves the current state of the specified controller.
Parameters:
UserIndex - [in] Index of the user's controller. Can be a value from 0 to 3.
Returns:
The current state of the controller as an associative array.
ErrorLevel:
If the function succeeds, ErrorLevel is ERROR_SUCCESS (zero).
If the controller is not connected, ErrorLevel is ERROR_DEVICE_NOT_CONNECTED (1167).
If the function fails, ErrorLevel is an error code defined in Winerror.h.
http msdn.microsoft.com /en-us/library/ms681381.aspx Broken Link for safety
Remarks:
XInput.dll returns controller state as a binary structure:
http msdn.microsoft.com /en-us/library/microsoft.directx_sdk.reference.xinput_state Broken Link for safety
http msdn.microsoft.com /en-us/library/microsoft.directx_sdk.reference.xinput_gamepad Broken Link for safety
*/
XInput_GetState(UserIndex)
{
global _XInput_GetState
VarSetCapacity(xiState,16)
if ErrorLevel := DllCall(_XInput_GetState ,"uint",UserIndex ,"uint",&xiState)
return 0
return {
(Join,
dwPacketNumber: NumGet(xiState, 0, "UInt")
wButtons: NumGet(xiState, 4, "UShort")
bLeftTrigger: NumGet(xiState, 6, "UChar")
bRightTrigger: NumGet(xiState, 7, "UChar")
sThumbLX: NumGet(xiState, 8, "Short")
sThumbLY: NumGet(xiState, 10, "Short")
sThumbRX: NumGet(xiState, 12, "Short")
sThumbRY: NumGet(xiState, 14, "Short")
)}
}
/*
Function: XInput_SetState
Sends data to a connected controller. This function is used to activate the vibration
function of a controller.
Parameters:
UserIndex - [in] Index of the user's controller. Can be a value from 0 to 3.
LeftMotorSpeed - [in] Speed of the left motor, between 0 and 65535.
RightMotorSpeed - [in] Speed of the right motor, between 0 and 65535.
Returns:
If the function succeeds, the return value is 0 (ERROR_SUCCESS).
If the controller is not connected, the return value is 1167 (ERROR_DEVICE_NOT_CONNECTED).
If the function fails, the return value is an error code defined in Winerror.h.
http msdn.microsoft.com /en-us/library/ms681381.aspx Broken Link for safety
Remarks:
The left motor is the low-frequency rumble motor. The right motor is the
high-frequency rumble motor. The two motors are not the same, and they create
different vibration effects.
*/
XInput_SetState(UserIndex, LeftMotorSpeed, RightMotorSpeed)
{
global _XInput_SetState
return DllCall(_XInput_SetState ,"uint",UserIndex ,"uint*",LeftMotorSpeed|RightMotorSpeed<<16)
}
/*
Function: XInput_GetCapabilities
Retrieves the capabilities and features of a connected controller.
Parameters:
UserIndex - [in] Index of the user's controller. Can be a value in the range 0–3.
Flags - [in] Input flags that identify the controller type.
0 - All controllers.
1 - XINPUT_FLAG_GAMEPAD: Xbox 360 Controllers only.
Returns:
The controller capabilities, as an associative array.
ErrorLevel:
If the function succeeds, ErrorLevel is 0 (ERROR_SUCCESS).
If the controller is not connected, ErrorLevel is 1167 (ERROR_DEVICE_NOT_CONNECTED).
If the function fails, ErrorLevel is an error code defined in Winerror.h.
http msdn.microsoft.com /en-us/library/ms681381.aspx Broken Link for safety
Remarks:
XInput.dll returns capabilities via a binary structure:
http msdn.microsoft.com /en-us/library/microsoft.directx_sdk.reference.xinput_capabilities Broken Link for safety
*/
XInput_GetCapabilities(UserIndex, Flags)
{
global _XInput_GetCapabilities
VarSetCapacity(xiCaps,20)
if ErrorLevel := DllCall(_XInput_GetCapabilities ,"uint",UserIndex ,"uint",Flags ,"ptr",&xiCaps)
return 0
return,
(Join
{
Type: NumGet(xiCaps, 0, "UChar"),
SubType: NumGet(xiCaps, 1, "UChar"),
Flags: NumGet(xiCaps, 2, "UShort"),
Gamepad:
{
wButtons: NumGet(xiCaps, 4, "UShort"),
bLeftTrigger: NumGet(xiCaps, 6, "UChar"),
bRightTrigger: NumGet(xiCaps, 7, "UChar"),
sThumbLX: NumGet(xiCaps, 8, "Short"),
sThumbLY: NumGet(xiCaps, 10, "Short"),
sThumbRX: NumGet(xiCaps, 12, "Short"),
sThumbRY: NumGet(xiCaps, 14, "Short")
},
Vibration:
{
wLeftMotorSpeed: NumGet(xiCaps, 16, "UShort"),
wRightMotorSpeed: NumGet(xiCaps, 18, "UShort")
}
}
)
}
/*
Function: XInput_Term
Unloads the previously loaded XInput DLL.
*/
XInput_Term() {
global
if _XInput_hm
DllCall("FreeLibrary","uint",_XInput_hm), _XInput_hm :=_XInput_GetState :=_XInput_SetState :=_XInput_GetCapabilities :=0
}
; TODO: XInputEnable, 'GetBatteryInformation and 'GetKeystroke.