XBOX One Controller
XBOX One Controller
Microsoft have made some updates for the XBOX One Controller for Windows 10 and now i't wont work with autohotkey anymore or atleast as a global key it did work before.
If i use this code for example
Joy1::
Msgbox hello
return
the script wont work if it's minimized but if i Open the script it works, if I change controller to a XBOX 360 Controller it works fine as global key.
Does it have to do something with https://msdn.microsoft.com/en-us/librar ... s.85).aspx ?
If i use this code for example
Joy1::
Msgbox hello
return
the script wont work if it's minimized but if i Open the script it works, if I change controller to a XBOX 360 Controller it works fine as global key.
Does it have to do something with https://msdn.microsoft.com/en-us/librar ... s.85).aspx ?
Re: XBOX One Controller
"the script wont work if it's minimized but if i Open the script it works"
That script has no GUI, so it cannot be minimized.
What do you mean by "Open the script"?
That script has no GUI, so it cannot be minimized.
What do you mean by "Open the script"?
Re: XBOX One Controller
It's linked to this:
https://autohotkey.com/boards/viewtopic ... 14&t=21230
https://autohotkey.com/boards/viewtopic ... 14&t=21230
Recommends AHK Studio
-
- Posts: 2
- Joined: 22 Apr 2019, 16:40
Re: XBOX One Controller
Hello! I wanted to add support for the Xbox One controller (wireless) and spent some time writing AutoHotkey scripts for it.
First is an updated version of XInput.ahk. I only changed the constant values (for buttons) and their names to make it clearer what each button corresponds to.
Second is a script to manage the sticks. In particular a new way to move the mouse with the right stick (the script provided in the AutoHotkey documentation doesn't emulate mouse movement well). The right stick sensibility can be changed and you can reduce the timer period for even faster response times.
Cheers!
First is an updated version of XInput.ahk. I only changed the constant values (for buttons) and their names to make it clearer what each button corresponds to.
Code: Select all
/* 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.
Code: Select all
#Persistent
#SingleInstance force
#Include XInput.ahk
XInput_Init()
ReleasePressedDirectionalKey(key)
{
GetKeyState, state, %key%
if state = D
Send {%key% up}
}
stickSensibility := 3 / 1000
Thread, interrupt, 0 ; Make all threads always-interruptible.
SetTimer, Sticks, 5
return
Sticks:
Loop, 4 {
if state := XInput_GetState(A_Index-1) {
LSx := state.sThumbLX
LSy := state.sThumbLY
RSx := state.sThumbRX
RSy := state.sThumbRY
if (abs(LSx) < XINPUT_GAMEPAD_LEFT_STICK_DEADZONE)
{
ReleasePressedDirectionalKey("Right")
ReleasePressedDirectionalKey("Left")
LSx := 0
xDirection := ""
xDirectionLast := ""
}
if (abs(LSy) < XINPUT_GAMEPAD_LEFT_STICK_DEADZONE)
{
ReleasePressedDirectionalKey("Up")
ReleasePressedDirectionalKey("Down")
LSy := 0
yDirection := ""
yDirectionLast := ""
}
if LSx
xDirection := LSx > 0 ? "Right" : "Left"
if LSy
yDirection := LSy > 0 ? "Up" : "Down"
;MsgBox % LSx . " / " . xDirection . " / " . xDirectionLast . " / " . LSy . " / " . yDirection . " / " . yDirectionLast
if (xDirection != "" && xDirection != xDirectionLast)
{
ReleasePressedDirectionalKey(xDirectionLast)
Send {%xDirection% down}
xDirectionLast := xDirection
}
if (yDirection != "" && yDirection != yDirectionLast)
{
ReleasePressedDirectionalKey(yDirectionLast)
Send {%yDirection% down}
yDirectionLast := yDirection
}
;8 689 = RS dead zone
;24 078 = RS live zone
;32 767 = radius
RSHypotenuse := sqrt(RSx * RSx + RSy * RSy)
if (RSHypotenuse > XINPUT_GAMEPAD_RIGHT_STICK_DEADZONE) {
RSValue := RSHypotenuse - XINPUT_GAMEPAD_RIGHT_STICK_DEADZONE
RSValueInProportion := RSValue / (32767 - XINPUT_GAMEPAD_RIGHT_STICK_DEADZONE)
;MsgBox % RSx . " - " . RSy . " - " . RSHypotenuse . " - " . RSValue . " - " . RSValueInProportion
SetMouseDelay, -1 ; Makes movement smoother.
if RSValueInProportion > 1
RSValueInProportion := 1
S := (1 - RSValueInProportion) * 100
RSx *= RSValueInProportion * stickSensibility
RSy *= RSValueInProportion * stickSensibility
MouseMove, RSx, -RSy, S, R
}
}
}
return
Re: XBOX One Controller
Hi villain, not to derail this topic, but with your updated xinput.ahk, this will work with latest windows 10 updates? I have implemented xinput.ahk into my script, and included an older version of the xinput 1_3.dll in my scripts directory to make it work. If I didn't have to include an old version of xinput.dll it would be awesome. Would I have to rewrite my entire xinput controller handlers with your script? That would be a lot of work.
-
- Posts: 2
- Joined: 22 Apr 2019, 16:40
Re: XBOX One Controller
Hello Seeds! I think it should, at least it works for me! I just changed the values of a few constants for the buttons because they weren't accurate for my controller. I don't think you need to include the dll if you're using XInput.ahk. I'm not sure what your scripts do. I guess you could try and see if they still work with the last version of W10.
Re: XBOX One Controller
Hey guys, I'm net to all this and I can safely say that I'm also really bad at creating scripts.
I was trying to create a simple Xbox Controller "A button mashing" loop.
The thing is, I don't really know what I'm doing
Is this anything close to being right?
If anyone can help me make this, I'd really appreciate it.
I was trying to create a simple Xbox Controller "A button mashing" loop.
The thing is, I don't really know what I'm doing

Is this anything close to being right?
Code: Select all
XINPUT_GAMEPAD_A::
Loop
{
Send, {XINPUT_GAMEPAD_A}
Sleep, 100
}until GetKeyState("XINPUT_GAMEPAD_B")
Esc:: Stop:=1
Return
Re: XBOX One Controller
What on earth makes you think XINPUT_GAMEPAD_A:: is a valid hotkey, or a valid syntax for the Send command?
AHK simply cannot send XInput, period, let alone using that syntax for input
You are literally saying "Why does this feature that I just made up not work?"
Because you made it up and it is not part of the software...
AHK simply cannot send XInput, period, let alone using that syntax for input
You are literally saying "Why does this feature that I just made up not work?"
Because you made it up and it is not part of the software...
Re: XBOX One Controller
@evilC: XINPUT_GAMEPAD_A and the like are variable names from lexikos' XInput, so apparently vpl91 is misapplying some things he found there.
Re: XBOX One Controller
Apologies for necro-posting. I don't like creating new threads unnecessarily.
I am trying to make heads or tails of how to add the new XBOX ONE xinput library (post #4) to AHK. I know the old post (https://autohotkey.com/board/topic/35848-xinput-xbox-360-controller-api/) said something about adding a library to the lib folder within the AHK install directory but there is no "Lib" folder. (Is there another place?) I am running AHK on W10 1909 64-bit and have AHK 1.1.33.02 32-bit Unicode installed as default. It is however, installed to the "Program Files" directory, not "Program Files (x86)" I doubt that really matters though.
What I read in the old forums for the xinput library is that AutoHotKey_L is required. Then I read that the current ahk IS the "L" version.
My head is spinning at this point and I am *FAR* from proficient in AHK. If somebody can give me the "down-n-dirty" on how to get the Xbox ONE Xinput lib (from post number 4 in this thread) installed using the current version of AHK (or which ever version of AHK that I need to install) to give me the functionality with my XBOX ONE controller that I need, I would be indebted to you. Thank you all in advance for the countless hours you have so selflessly dedicated to helping others. Such as myself.
I am trying to make heads or tails of how to add the new XBOX ONE xinput library (post #4) to AHK. I know the old post (https://autohotkey.com/board/topic/35848-xinput-xbox-360-controller-api/) said something about adding a library to the lib folder within the AHK install directory but there is no "Lib" folder. (Is there another place?) I am running AHK on W10 1909 64-bit and have AHK 1.1.33.02 32-bit Unicode installed as default. It is however, installed to the "Program Files" directory, not "Program Files (x86)" I doubt that really matters though.
What I read in the old forums for the xinput library is that AutoHotKey_L is required. Then I read that the current ahk IS the "L" version.
My head is spinning at this point and I am *FAR* from proficient in AHK. If somebody can give me the "down-n-dirty" on how to get the Xbox ONE Xinput lib (from post number 4 in this thread) installed using the current version of AHK (or which ever version of AHK that I need to install) to give me the functionality with my XBOX ONE controller that I need, I would be indebted to you. Thank you all in advance for the countless hours you have so selflessly dedicated to helping others. Such as myself.