icydeath-ffxi

ffxi_xinput.ahk

Jan 15th, 2021
1,192
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*  XInput by Lexikos
  2.  *  This version of the script uses objects, so requires AutoHotkey_L.
  3.  */
  4.  
  5. /*
  6.     Function: XInput_Init
  7.    
  8.     Initializes XInput.ahk with the given XInput DLL.
  9.    
  10.     Parameters:
  11.         dll     -   The path or name of the XInput DLL to load.
  12. */
  13. XInput_Init(dll="C:\Windows\System32\xinput1_3")
  14. {
  15.     global
  16.     if _XInput_hm
  17.         return
  18.    
  19.     ;======== CONSTANTS DEFINED IN XINPUT.H ========
  20.    
  21.     ; NOTE: These are based on my outdated copy of the DirectX SDK.
  22.     ;       Newer versions of XInput may require additional constants.
  23.    
  24.     ; Device types available in XINPUT_CAPABILITIES
  25.     XINPUT_DEVTYPE_GAMEPAD          := 0x01
  26.  
  27.     ; Device subtypes available in XINPUT_CAPABILITIES
  28.     XINPUT_DEVSUBTYPE_GAMEPAD       := 0x01
  29.  
  30.     ; Flags for XINPUT_CAPABILITIES
  31.     XINPUT_CAPS_VOICE_SUPPORTED     := 0x0004
  32.  
  33.     ; Constants for gamepad buttons
  34.     XINPUT_GAMEPAD_DPAD_UP          := 0x0001
  35.     XINPUT_GAMEPAD_DPAD_DOWN        := 0x0002
  36.     XINPUT_GAMEPAD_DPAD_LEFT        := 0x0004
  37.     XINPUT_GAMEPAD_DPAD_RIGHT       := 0x0008
  38.     XINPUT_GAMEPAD_START            := 0x0010
  39.     XINPUT_GAMEPAD_BACK             := 0x0020
  40.     XINPUT_GAMEPAD_LEFT_THUMB       := 0x0040
  41.     XINPUT_GAMEPAD_RIGHT_THUMB      := 0x0080
  42.     XINPUT_GAMEPAD_LEFT_SHOULDER    := 0x0100
  43.     XINPUT_GAMEPAD_RIGHT_SHOULDER   := 0x0200
  44.     XINPUT_GAMEPAD_A                := 0x1000
  45.     XINPUT_GAMEPAD_B                := 0x2000
  46.     XINPUT_GAMEPAD_X                := 0x4000
  47.     XINPUT_GAMEPAD_Y                := 0x8000
  48.  
  49.     ; Gamepad thresholds
  50.     XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE  := 7849
  51.     XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE := 8689
  52.     XINPUT_GAMEPAD_TRIGGER_THRESHOLD    := 30
  53.  
  54.     ; Flags to pass to XInputGetCapabilities
  55.     XINPUT_FLAG_GAMEPAD             := 0x00000001
  56.    
  57.     ;=============== END CONSTANTS =================
  58.    
  59.     _XInput_hm := DllCall("LoadLibrary" ,"str",dll)
  60.    
  61.     if !_XInput_hm
  62.     {
  63.         MsgBox, Failed to initialize XInput: %dll%.dll not found.
  64.         return
  65.     }
  66.    
  67.     _XInput_GetState        := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputGetState")
  68.     _XInput_SetState        := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputSetState")
  69.     _XInput_GetCapabilities := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputGetCapabilities")
  70.    
  71.     if !(_XInput_GetState && _XInput_SetState && _XInput_GetCapabilities)
  72.     {
  73.         XInput_Term()
  74.         MsgBox, Failed to initialize XInput: function not found.
  75.         return
  76.     }
  77. }
  78.  
  79. /*
  80.     Function: XInput_GetState
  81.    
  82.     Retrieves the current state of the specified controller.
  83.  
  84.     Parameters:
  85.         UserIndex   -   [in] Index of the user's controller. Can be a value from 0 to 3.
  86.         State       -   [out] Receives the current state of the controller.
  87.    
  88.     Returns:
  89.         If the function succeeds, the return value is ERROR_SUCCESS (zero).
  90.         If the controller is not connected, the return value is ERROR_DEVICE_NOT_CONNECTED (1167).
  91.         If the function fails, the return value is an error code defined in Winerror.h.
  92.             http://msdn.microsoft.com/en-us/library/ms681381.aspx
  93.  
  94.     Remarks:
  95.         XInput.dll returns controller state as a binary structure:
  96.             http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.xinput_state
  97.             http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.xinput_gamepad
  98.         XInput.ahk converts this structure to an AutoHotkey_L object.
  99. */
  100. XInput_GetState(UserIndex)
  101. {
  102.     global _XInput_GetState
  103.    
  104.     VarSetCapacity(xiState,16)
  105.  
  106.     if ErrorLevel := DllCall(_XInput_GetState ,"uint",UserIndex ,"uint",&xiState)
  107.         return 0
  108.    
  109.     return {
  110.     (Join,
  111.         dwPacketNumber: NumGet(xiState,  0, "UInt")
  112.         wButtons:      NumGet(xiState,  4, "UShort")
  113.         bLeftTrigger:  NumGet(xiState,  6, "UChar")
  114.         bRightTrigger: NumGet(xiState,  7, "UChar")
  115.         sThumbLX:      NumGet(xiState,  8, "Short")
  116.         sThumbLY:      NumGet(xiState, 10, "Short")
  117.         sThumbRX:      NumGet(xiState, 12, "Short")
  118.         sThumbRY:      NumGet(xiState, 14, "Short")
  119.     )}
  120. }
  121.  
  122. /*
  123.     Function: XInput_SetState
  124.    
  125.     Sends data to a connected controller. This function is used to activate the vibration
  126.     function of a controller.
  127.    
  128.     Parameters:
  129.         UserIndex       -   [in] Index of the user's controller. Can be a value from 0 to 3.
  130.         LeftMotorSpeed  -   [in] Speed of the left motor, between 0 and 65535.
  131.         RightMotorSpeed -   [in] Speed of the right motor, between 0 and 65535.
  132.    
  133.     Returns:
  134.         If the function succeeds, the return value is 0 (ERROR_SUCCESS).
  135.         If the controller is not connected, the return value is 1167 (ERROR_DEVICE_NOT_CONNECTED).
  136.         If the function fails, the return value is an error code defined in Winerror.h.
  137.             http://msdn.microsoft.com/en-us/library/ms681381.aspx
  138.    
  139.     Remarks:
  140.         The left motor is the low-frequency rumble motor. The right motor is the
  141.         high-frequency rumble motor. The two motors are not the same, and they create
  142.         different vibration effects.
  143. */
  144. XInput_SetState(UserIndex, LeftMotorSpeed, RightMotorSpeed)
  145. {
  146.     global _XInput_SetState
  147.     return DllCall(_XInput_SetState ,"uint",UserIndex ,"uint*",LeftMotorSpeed|RightMotorSpeed<<16)
  148. }
  149.  
  150. /*
  151.     Function: XInput_GetCapabilities
  152.    
  153.     Retrieves the capabilities and features of a connected controller.
  154.    
  155.     Parameters:
  156.         UserIndex   -   [in] Index of the user's controller. Can be a value in the range 0–3.
  157.         Flags       -   [in] Input flags that identify the controller type.
  158.                                 0   - All controllers.
  159.                                 1   - XINPUT_FLAG_GAMEPAD: Xbox 360 Controllers only.
  160.         Caps        -   [out] Receives the controller capabilities.
  161.    
  162.     Returns:
  163.         If the function succeeds, the return value is 0 (ERROR_SUCCESS).
  164.         If the controller is not connected, the return value is 1167 (ERROR_DEVICE_NOT_CONNECTED).
  165.         If the function fails, the return value is an error code defined in Winerror.h.
  166.             http://msdn.microsoft.com/en-us/library/ms681381.aspx
  167.    
  168.     Remarks:
  169.         XInput.dll returns capabilities via a binary structure:
  170.             http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.xinput_capabilities
  171.         XInput.ahk converts this structure to an AutoHotkey_L object.
  172. */
  173. XInput_GetCapabilities(UserIndex, Flags)
  174. {
  175.     global _XInput_GetCapabilities
  176.    
  177.     VarSetCapacity(xiCaps,20)
  178.    
  179.     if ErrorLevel := DllCall(_XInput_GetCapabilities ,"uint",UserIndex ,"uint",Flags ,"ptr",&xiCaps)
  180.         return 0
  181.    
  182.     return,
  183.     (Join
  184.         {
  185.             Type:                  NumGet(xiCaps,  0, "UChar"),
  186.             SubType:               NumGet(xiCaps,  1, "UChar"),
  187.             Flags:                 NumGet(xiCaps,  2, "UShort"),
  188.             Gamepad:
  189.            {
  190.                 wButtons:          NumGet(xiCaps,  4, "UShort"),
  191.                 bLeftTrigger:      NumGet(xiCaps,  6, "UChar"),
  192.                 bRightTrigger:     NumGet(xiCaps,  7, "UChar"),
  193.                 sThumbLX:          NumGet(xiCaps,  8, "Short"),
  194.                 sThumbLY:          NumGet(xiCaps, 10, "Short"),
  195.                 sThumbRX:          NumGet(xiCaps, 12, "Short"),
  196.                 sThumbRY:          NumGet(xiCaps, 14, "Short")
  197.             },
  198.             Vibration:
  199.            {
  200.                 wLeftMotorSpeed:   NumGet(xiCaps, 16, "UShort"),
  201.                 wRightMotorSpeed:  NumGet(xiCaps, 18, "UShort")
  202.             }
  203.         }
  204.     )
  205. }
  206.  
  207. /*
  208.     Function: XInput_Term
  209.     Unloads the previously loaded XInput DLL.
  210. */
  211. XInput_Term() {
  212.     global
  213.     if _XInput_hm
  214.         DllCall("FreeLibrary","uint",_XInput_hm), _XInput_hm :=_XInput_GetState :=_XInput_SetState :=_XInput_GetCapabilities :=0
  215. }
  216.  
  217. #SingleInstance force
  218.  
  219. lastKeyPressed := ""
  220. isLeftTriggerDown := false
  221. isRightTriggerDown := false
  222. isCtrlDown := false
  223.  
  224. isDpadUpDown := false
  225. isDpadRightDown := false
  226. isDpadDownDown := false
  227. isDpadLeftDown := false
  228. isButtonADown := false
  229. isButtonBDown := false
  230. isButtonXDown := false
  231. isButtonYDown := false
  232. isButtonStartDown := false
  233. isButtonBackDown := false
  234.  
  235. IniRead, ButtonLayout, config.ini, ButtonMap, ButtonLayout
  236. IniRead, ConfirmButton, config.ini, ButtonMap, ConfirmButton
  237. IniRead, CancelButton, config.ini, ButtonMap, CancelButton
  238. IniRead, MainMenuButton, config.ini, ButtonMap, MainMenuButton
  239. IniRead, ActiveWindowButton, config.ini, ButtonMap, ActiveWindowButton
  240. StringUpper, ButtonLayout, ButtonLayout
  241. StringUpper, ConfirmButton, ConfirmButton
  242. StringUpper, CancelButton, CancelButton
  243. StringUpper, MainMenuButton, MainMenuButton
  244. StringUpper, ActiveWindowButton, ActiveWindowButton
  245.  
  246. ; Example: Control the vibration motors using the analog triggers of each controller.
  247. XInput_Init()
  248. Loop {
  249.     Loop, 4 {
  250.         If State := XInput_GetState(A_Index-1) {
  251.             If WinActive("ahk_class FFXiClass") {
  252.                 if (State.bLeftTrigger and !isLeftTriggerDown) {
  253.                     isLeftTriggerDown := true
  254.                     If (!isCtrlDown) {
  255.                         isCtrlDown := true
  256.                         SendInput {Ctrl down}
  257.                     }
  258.                     SendInput {f11 down}
  259.                 } else If (!State.bLeftTrigger and isLeftTriggerDown) {
  260.                     isLeftTriggerDown := false
  261.                     SendInput {f11 up}
  262.                     If (!State.bRightTrigger and !isRightTriggerDown and isCtrlDown) {
  263.                         isCtrlDown := false
  264.                         SendInput {Ctrl up}
  265.                     }
  266.                 }
  267.                
  268.                 if (State.bRightTrigger and !isRightTriggerDown) {
  269.                     isRightTriggerDown := true
  270.                     If (!isCtrlDown) {
  271.                         isCtrlDown := true
  272.                         SendInput {Ctrl down}
  273.                     }
  274.                     SendInput {f12 down}
  275.                 } else If (!State.bRightTrigger and isRightTriggerDown) {
  276.                     isRightTriggerDown := false
  277.                     SendInput {f12 up}
  278.                     If (!State.bLeftTrigger and !isLeftTriggerDown and isCtrlDown) {
  279.                         isCtrlDown := false
  280.                         SendInput {Ctrl up}
  281.                     }
  282.                 }
  283.                
  284.                 if (isRightTriggerDown or isLeftTriggerDown or isButtonStartDown) {
  285.                     If (!isDpadUpDown and State.wButtons & XINPUT_GAMEPAD_DPAD_UP) {
  286.                         SendInput {f1}
  287.  
  288.                         isDpadUpDown := true
  289.                     } else If (isDpadUpDown and !(State.wButtons & XINPUT_GAMEPAD_DPAD_UP)) {
  290.                         isDpadUpDown := false
  291.                     }
  292.                     If (!isDpadRightDown and State.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) {
  293.                         SendInput {f2}
  294.  
  295.                         isDpadRightDown := true
  296.                     } else If (isDpadRightDown and !(State.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)) {
  297.                         isDpadRightDown := false
  298.                     }
  299.                     If (!isDpadDownDown and State.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {
  300.                         SendInput {f3}
  301.  
  302.                         isDpadDownDown := true
  303.                     } else If (isDpadDownDown and !(State.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)) {
  304.                         isDpadDownDown := false
  305.                     }
  306.                     If (!isDpadLeftDown and State.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) {
  307.                         SendInput {f4}
  308.  
  309.                         isDpadLeftDown := true
  310.                     } else If (isDpadLeftDown and !(State.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)) {
  311.                         isDpadLeftDown := false
  312.                     }
  313.                 }
  314.                
  315.                 If (!isButtonADown and State.wButtons & XINPUT_GAMEPAD_A) {
  316.                     If (isLeftTriggerDown or isRightTriggerDown) {
  317.                         SendInput {f5}
  318.                     } else {
  319.                         If (ButtonLayout == "GAMECUBE" or ButtonLayout == "XBOX") {
  320.                             If (ConfirmButton == "A") {
  321.                                 Gosub, SendConfirmKey
  322.                             } else If (CancelButton == "A") {
  323.                                 Gosub, SendCancelKey
  324.                             } else If (MainMenuButton == "A") {
  325.                                 Gosub, SendMainMenuKey
  326.                             } else If (ActiveWindowButton == "A") {
  327.                                 Gosub, SendActiveWindowKey
  328.                             }
  329.                         } else If (ButtonLayout == "PLAYSTATION") {
  330.                             If (ConfirmButton == "CROSS") {
  331.                                 Gosub, SendConfirmKey
  332.                             } else If (CancelButton == "CROSS") {
  333.                                 Gosub, SendCancelKey
  334.                             } else If (MainMenuButton == "CROSS") {
  335.                                 Gosub, SendMainMenuKey
  336.                             } else If (ActiveWindowButton == "CROSS") {
  337.                                 Gosub, SendActiveWindowKey
  338.                             }
  339.                         } else If (ButtonLayout == "NINTENDO") {
  340.                             If (ConfirmButton == "B") {
  341.                                 Gosub, SendConfirmKey
  342.                             } else If (CancelButton == "B") {
  343.                                 Gosub, SendCancelKey
  344.                             } else If (MainMenuButton == "B") {
  345.                                 Gosub, SendMainMenuKey
  346.                             } else If (ActiveWindowButton == "B") {
  347.                                 Gosub, SendActiveWindowKey
  348.                             }
  349.                         }
  350.                     }
  351.  
  352.                     isButtonADown := true
  353.                 } else If (isButtonADown and !(State.wButtons & XINPUT_GAMEPAD_A)) {
  354.                     isButtonADown := false
  355.                 }
  356.                 If (!isButtonBDown and State.wButtons & XINPUT_GAMEPAD_B) {
  357.                     If (isLeftTriggerDown or isRightTriggerDown) {
  358.                         SendInput {f7}
  359.                     } else {
  360.                         If (ButtonLayout == "GAMECUBE") {
  361.                             If (ConfirmButton == "X") {
  362.                                 Gosub, SendConfirmKey
  363.                             } else If (CancelButton == "X") {
  364.                                 Gosub, SendCancelKey
  365.                             } else If (MainMenuButton == "X") {
  366.                                 Gosub, SendMainMenuKey
  367.                             } else If (ActiveWindowButton == "X") {
  368.                                 Gosub, SendActiveWindowKey
  369.                             }
  370.                         } else If (ButtonLayout == "XBOX") {
  371.                             If (ConfirmButton == "B") {
  372.                                 Gosub, SendConfirmKey
  373.                             } else If (CancelButton == "B") {
  374.                                 Gosub, SendCancelKey
  375.                             } else If (MainMenuButton == "B") {
  376.                                 Gosub, SendMainMenuKey
  377.                             } else If (ActiveWindowButton == "B") {
  378.                                 Gosub, SendActiveWindowKey
  379.                             }
  380.                         } else If (ButtonLayout == "PLAYSTATION") {
  381.                             If (ConfirmButton == "CIRCLE") {
  382.                                 Gosub, SendConfirmKey
  383.                             } else If (CancelButton == "CIRCLE") {
  384.                                 Gosub, SendCancelKey
  385.                             } else If (MainMenuButton == "CIRCLE") {
  386.                                 Gosub, SendMainMenuKey
  387.                             } else If (ActiveWindowButton == "CIRCLE") {
  388.                                 Gosub, SendActiveWindowKey
  389.                             }
  390.                         } else If (ButtonLayout == "NINTENDO") {
  391.                             If (ConfirmButton == "A") {
  392.                                 Gosub, SendConfirmKey
  393.                             } else If (CancelButton == "A") {
  394.                                 Gosub, SendCancelKey
  395.                             } else If (MainMenuButton == "A") {
  396.                                 Gosub, SendMainMenuKey
  397.                             } else If (ActiveWindowButton == "A") {
  398.                                 Gosub, SendActiveWindowKey
  399.                             }
  400.                         }
  401.                     }
  402.  
  403.                     isButtonBDown := true
  404.                 } else If (isButtonBDown and !(State.wButtons & XINPUT_GAMEPAD_B)) {
  405.                     isButtonBDown := false
  406.                 }
  407.                 If (!isButtonXDown and State.wButtons & XINPUT_GAMEPAD_X) {
  408.                     If (isLeftTriggerDown or isRightTriggerDown) {
  409.                         SendInput {f6}
  410.                     } else {
  411.                         If (ButtonLayout == "GAMECUBE") {
  412.                             If (ConfirmButton == "B") {
  413.                                 Gosub, SendConfirmKey
  414.                             } else If (CancelButton == "B") {
  415.                                 Gosub, SendCancelKey
  416.                             } else If (MainMenuButton == "B") {
  417.                                 Gosub, SendMainMenuKey
  418.                             } else If (ActiveWindowButton == "B") {
  419.                                 Gosub, SendActiveWindowKey
  420.                             }
  421.                         } else If (ButtonLayout == "XBOX") {
  422.                             If (ConfirmButton == "X") {
  423.                                 Gosub, SendConfirmKey
  424.                             } else If (CancelButton == "X") {
  425.                                 Gosub, SendCancelKey
  426.                             } else If (MainMenuButton == "X") {
  427.                                 Gosub, SendMainMenuKey
  428.                             } else If (ActiveWindowButton == "X") {
  429.                                 Gosub, SendActiveWindowKey
  430.                             }
  431.                         } else If (ButtonLayout == "PLAYSTATION") {
  432.                             If (ConfirmButton == "SQUARE") {
  433.                                 Gosub, SendConfirmKey
  434.                             } else If (CancelButton == "SQUARE") {
  435.                                 Gosub, SendCancelKey
  436.                             } else If (MainMenuButton == "SQUARE") {
  437.                                 Gosub, SendMainMenuKey
  438.                             } else If (ActiveWindowButton == "SQUARE") {
  439.                                 Gosub, SendActiveWindowKey
  440.                             }
  441.                         } else If (ButtonLayout == "NINTENDO") {
  442.                             If (ConfirmButton == "Y") {
  443.                                 Gosub, SendConfirmKey
  444.                             } else If (CancelButton == "Y") {
  445.                                 Gosub, SendCancelKey
  446.                             } else If (MainMenuButton == "Y") {
  447.                                 Gosub, SendMainMenuKey
  448.                             } else If (ActiveWindowButton == "Y") {
  449.                                 Gosub, SendActiveWindowKey
  450.                             }
  451.                         }
  452.                     }
  453.  
  454.                     isButtonXDown := true
  455.                 } else If (isButtonXDown and !(State.wButtons & XINPUT_GAMEPAD_X)) {
  456.                     isButtonXDown := false
  457.                 }
  458.                 If (!isButtonYDown and State.wButtons & XINPUT_GAMEPAD_Y) {
  459.                     If (isLeftTriggerDown or isRightTriggerDown) {
  460.                         SendInput {f8}
  461.                     } else {
  462.                         If (ButtonLayout == "GAMECUBE" or ButtonLayout == "XBOX") {
  463.                             If (ConfirmButton == "Y") {
  464.                                 Gosub, SendConfirmKey
  465.                             } else If (CancelButton == "Y") {
  466.                                 Gosub, SendCancelKey
  467.                             } else If (MainMenuButton == "Y") {
  468.                                 Gosub, SendMainMenuKey
  469.                             } else If (ActiveWindowButton == "Y") {
  470.                                 Gosub, SendActiveWindowKey
  471.                             }
  472.                         } else If (ButtonLayout == "PLAYSTATION") {
  473.                             If (ConfirmButton == "TRIANGLE") {
  474.                                 Gosub, SendConfirmKey
  475.                             } else If (CancelButton == "TRIANGLE") {
  476.                                 Gosub, SendCancelKey
  477.                             } else If (MainMenuButton == "TRIANGLE") {
  478.                                 Gosub, SendMainMenuKey
  479.                             } else If (ActiveWindowButton == "TRIANGLE") {
  480.                                 Gosub, SendActiveWindowKey
  481.                             }
  482.                         } else If (ButtonLayout == "NINTENDO") {
  483.                             If (ConfirmButton == "X") {
  484.                                 Gosub, SendConfirmKey
  485.                             } else If (CancelButton == "X") {
  486.                                 Gosub, SendCancelKey
  487.                             } else If (MainMenuButton == "X") {
  488.                                 Gosub, SendMainMenuKey
  489.                             } else If (ActiveWindowButton == "X") {
  490.                                 Gosub, SendActiveWindowKey
  491.                             }
  492.                         }
  493.                     }
  494.  
  495.                     isButtonYDown := true
  496.                 } else If (isButtonYDown and !(State.wButtons & XINPUT_GAMEPAD_Y)) {
  497.                     isButtonYDown := false
  498.                 }
  499.  
  500.                 If (!isButtonBackDown and State.wButtons & XINPUT_GAMEPAD_BACK) {
  501.                     SendInput {Ctrl down}
  502.                     SendInput {f9 down}
  503.  
  504.                     isButtonBackDown := true
  505.                 } else If (isButtonBackDown and !(State.wButtons & XINPUT_GAMEPAD_BACK)) {
  506.                     SendInput {f9 up}
  507.                     SendInput {Ctrl up}
  508.  
  509.                     isButtonBackDown := false
  510.                 }
  511.                 If (!isButtonStartDown and State.wButtons & XINPUT_GAMEPAD_START) {
  512.                     SendInput {Ctrl down}
  513.                     SendInput {f10 down}
  514.  
  515.                     isButtonStartDown := true
  516.                 } else If (isButtonStartDown and !(State.wButtons & XINPUT_GAMEPAD_START)) {
  517.                     SendInput {f10 up}
  518.                     SendInput {Ctrl up}
  519.  
  520.                     isButtonStartDown := false
  521.                 }
  522.             }
  523.         }
  524.     }
  525.     Sleep, 10
  526. }
  527.  
  528. ; Helper subroutines. *DON'T* modify these to remap, instead just change which buttons call them
  529. SendConfirmKey:
  530. SendInput {Enter}
  531. return
  532. SendCancelKey:
  533. SendInput {Esc}
  534. return
  535. SendMainMenuKey:
  536. SendInput {NumpadSub}
  537. return
  538. SendActiveWindowKey:
  539. SendInput {NumpadAdd}
  540. return
RAW Paste Data