#Persistent #NoEnv ; ----- xtravar's XInput autohotkey script ; Version: 2011.3.27 ; Author: xtravar@yahoo.com ; License: GPLv2 (http://www.gnu.org/licenses/gpl-2.0.html) ; Requires: Autohotkey - perhaps autohotkey_l? http://www.autohotkey.net ; Notes: I'm new at autohotkey so this probably isn't perfect. ; See my Dragon Age 2 script for examples. ; Disclaimer: There is no warranty. ; ------------------------------------------------------------------------ ; ------------------------------------------------ ; EXPLANATION OF WHAT'S GOING ON ; ------------------------------------------------ ; This script allows you to listen for XInput events with callback functions. ; You may experience performance issues due to the architecture. If so, do a lower-level hook. ; All the callback functions start with XI_CB. ; The 'state' parameter is either 0 - up, 1 - hold, 2 - up ; All the button callbacks start with XI_CB_Button ; XI_CB_ButtonDPadUp(state) ; XI_CB_ButtonDPadDown(state) ; XI_CB_ButtonDPadLeft(state) ; XI_CB_ButtonDPadRight(state) ; XI_CB_ButtonStart(state) ; XI_CB_ButtonBack(state) ; XI_CB_ButtonLeftThumb(state) ; XI_CB_ButtonRightThumb(state) ; XI_CB_ButtonLeftShoulder(state) ; XI_CB_ButtonRightShoulder(state) ; XI_CB_ButtonA(state) ; XI_CB_ButtonX(state) ; XI_CB_ButtonY(state) ; XI_CB_ButtonB(state) ; And here are the axis callbacks (triggers are axis) ; XI_CB_LeftTrigger(state,value) ; XI_CB_RightTrigger(state,value) ; XI_CB_LeftThumb(state,x,y) ; XI_CB_RightThumb(state,x,y) ; ; To begin, call XI_BeginWatching(poll interval) ; To end, call XI_EndWatching() XINPUT_GAMEPAD_DPAD_UP = 0x0001 XINPUT_GAMEPAD_DPAD_DOWN = 0x0002 XINPUT_GAMEPAD_DPAD_LEFT = 0x0004 XINPUT_GAMEPAD_DPAD_RIGHT = 0x0008 XINPUT_GAMEPAD_START = 0x0010 XINPUT_GAMEPAD_BACK = 0x0020 XINPUT_GAMEPAD_LEFT_THUMB = 0x0040 XINPUT_GAMEPAD_RIGHT_THUMB = 0x0080 XINPUT_GAMEPAD_LEFT_SHOULDER = 0x0100 XINPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200 XINPUT_GAMEPAD_A = 0x1000 XINPUT_GAMEPAD_B = 0x2000 XINPUT_GAMEPAD_X = 0x4000 XINPUT_GAMEPAD_Y = 0x8000 _xi1ToName := "DPadUp" _xi2ToName := "DPadDown" _xi4ToName := "DPadLeft" _xi8ToName := "DPadRight" _xi16ToName := "Start" _xi32ToName := "Back" _xi64ToName := "LeftThumb" _xi128ToName := "RightThumb" _xi256ToName := "LeftShoulder" _xi512ToName := "RightShoulder" _xi4096ToName := "A" _xi8192ToName := "B" _xi16384ToName := "X" _xi32768ToName := "Y" XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE = 7849 XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE = 8689 XINPUT_GAMEPAD_TRIGGER_THRESHOLD = 30 _xiState := 0 _xiButtons := 0 _xiLeftTrigger := 0 _xiRightTrigger := 0 _xiThumbLX := 0 _xiThumbLY := 0 _xiThumbRX := 0 _xiThumbRY := 0 _xiLastButtons := 0 _xiLastLeftTrigger := 0 _xiLastRightTrigger := 0 _xiLastThumbLX := 0 _xiLastThumbLY := 0 _xiLastThumbRX := 0 _xiLastThumbRY := 0 XI_BeginWatching(interval) { global _xiState VarSetCapacity(_xiState, 4 + 12) SetTimer, _XIWatchState, %interval% ; Monitor the movement of the joystick. } XI_EndWatching() { SetTimer, _XIWatchState, Off } if (0) { _XIWatchState: _xiError := DllCall("xinput1_3\XInputGetState", "ptr", UserIndex, "ptr", &_xiState) if(_xiError) { return } _xiLastButtons := _xiButtons _xiLastLeftTrigger := _xiLeftTrigger _xiLastRightTrigger := _xiRightTrigger _xiLastThumbLX := _xiThumbLX _xiLastThumbLY := _xiThumbLY _xiLastThumbRX := _xiThumbRX _xiLastThumbRY := _xiThumbRY _xiButtons := NumGet(_xiState, 4, "UShort") _xiLeftTrigger := NumGet(_xiState, 4 + 2, "UChar") _xiRightTrigger := NumGet(_xiState, 4 + 3, "UChar") _xiThumbLX := NumGet(_xiState, 4 + 4, "Short") _xiThumbLY := NumGet(_xiState, 4 + 6, "Short") _xiThumbRX := NumGet(_xiState, 4 + 8, "Short") _xiThumbRY := NumGet(_xiState, 4 + 10, "Short") if(_xiLeftTrigger < XINPUT_GAMEPAD_TRIGGER_THRESHOLD) { _xiLeftTrigger := 0 } if(_xiRightTrigger < XINPUT_GAMEPAD_TRIGGER_THRESHOLD) { _xiRightTrigger := 0 } if(_xiThumbLX < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE && _xiThumbLX > -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { _xiThumbLX := 0 } if(_xiThumbLY < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE && _xiThumbLY > -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { _xiThumbLY := 0 } if(_xiThumbRX < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE && _xiThumbRX > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) { _xiThumbRX := 0 } if(_xiThumbRY < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE && _xiThumbRY > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) { _xiThumbRY := 0 } button := 1 while(button <= XINPUT_GAMEPAD_Y) { if(_xiButtons & button) { name := _xi%button%ToName func = XI_CB_Button%name% if(_xiLastButtons & button) { %func%(1) } else { %func%(0) } } else if(_xiLastButtons & button) { name := _xi%button%ToName func = XI_CB_Button%name% %func%(2) } button := button << 1 } if(_xiLeftTrigger) { if(!_xiLastLeftTrigger) { XI_CB_LeftTrigger(0,_xiLeftTrigger) } else { XI_CB_LeftTrigger(1,_xiLeftTrigger) } } else if(_xiLastLeftTrigger) { XI_CB_LeftTrigger(2,_xiLeftTrigger) } if(_xiRightTrigger) { if(!_xiLastRightTrigger) { XI_CB_RightTrigger(0,_xiRightTrigger) } else { XI_CB_RightTrigger(1,_xiRightTrigger) } } else if(_xiLastRightTrigger) { XI_CB_RightTrigger(2,_xiRightTrigger) } if(_xiThumbLX + _xiThumbLY != 0) { if(_xiLastThumbLX + _xiLastThumbLY == 0) { XI_CB_LeftThumb(0, _xiThumbLX, _xiThumbLY) } else { XI_CB_LeftThumb(1, _xiThumbLX, _xiThumbLY) } } else if(_xiLastThumbLX + _xiLastThumbLY != 0) { XI_CB_LeftThumb(2, _xiThumbLX, _xiThumbLY) } if(_xiThumbRX + _xiThumbRY != 0) { if(_xiLastThumbRX + _xiLastThumbRY == 0) { XI_CB_RightThumb(0, _xiThumbRX, _xiThumbRY) } else { XI_CB_RightThumb(1, _xiThumbRX, _xiThumbRY) } } else if(_xiLastThumbRX + _xiLastThumbRY != 0) { XI_CB_RightThumb(2, _xiThumbRX, _xiThumbRY) } return _XIDebug: WatchingGamepad: Tooltip LTrigger-%_xiLeftTrigger% RTrigger-%_xiRightTrigger% `n ThumbL- %_xiThumbLX% %_xiThumbLY% ThumbR- %_xiThumbRX% %_xiThumbRY% `n Button Info-%_xiButtons% return }