Advertisement
Guest User

Experimental AHK

a guest
Jul 6th, 2022
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.50 KB | None | 0 0
  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. TRIGGER_DEAD_ZONE := 4
  220.  
  221. lastKeyPressed := ""
  222. isLeftTriggerDown := false
  223. isRightTriggerDown := false
  224. isCtrlDown := false
  225.  
  226. isDpadUpDown := false
  227. isDpadRightDown := false
  228. isDpadDownDown := false
  229. isDpadLeftDown := false
  230. isButtonADown := false
  231. isButtonBDown := false
  232. isButtonXDown := false
  233. isButtonYDown := false
  234. isButtonStartDown := false
  235. isButtonBackDown := false
  236. isBumperRightDown := false
  237.  
  238. IniRead, ButtonLayout, config.ini, ButtonMap, ButtonLayout
  239. IniRead, ConfirmButton, config.ini, ButtonMap, ConfirmButton
  240. IniRead, CancelButton, config.ini, ButtonMap, CancelButton
  241. IniRead, MainMenuButton, config.ini, ButtonMap, MainMenuButton
  242. IniRead, ActiveWindowButton, config.ini, ButtonMap, ActiveWindowButton
  243. StringUpper, ButtonLayout, ButtonLayout
  244. StringUpper, ConfirmButton, ConfirmButton
  245. StringUpper, CancelButton, CancelButton
  246. StringUpper, MainMenuButton, MainMenuButton
  247. StringUpper, ActiveWindowButton, ActiveWindowButton
  248.  
  249. ; Example: Control the vibration motors using the analog triggers of each controller.
  250. XInput_Init()
  251. Loop {
  252. Loop, 4 {
  253. If State := XInput_GetState(A_Index-1) {
  254. If (!isBumperRightDown and State.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) {
  255. isBumperRightDown := true
  256.  
  257. If WinExist("ahk_class FFXiClass") and !WinActive("ahk_class FFXiClass") {
  258. WinActivate
  259. }
  260. } else If (isBumperRightDown and !(State.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER)) {
  261. isBumperRightDown := false
  262. }
  263.  
  264. If WinActive("ahk_class FFXiClass") {
  265. if (State.bLeftTrigger > TRIGGER_DEAD_ZONE and !isLeftTriggerDown) {
  266. isLeftTriggerDown := true
  267. If (!isCtrlDown) {
  268. isCtrlDown := true
  269. SendInput {Ctrl down}
  270. }
  271. SendInput {f11 down}
  272. } else If ((State.bLeftTrigger <= TRIGGER_DEAD_ZONE and isLeftTriggerDown) {
  273. isLeftTriggerDown := false
  274. SendInput {f11 up}
  275. If (!State.bRightTrigger and !isRightTriggerDown and isCtrlDown) {
  276. isCtrlDown := false
  277. SendInput {Ctrl up}
  278. }
  279. }
  280.  
  281. if (State.bRightTrigger > TRIGGER_DEAD_ZONE and !isRightTriggerDown) {
  282. isRightTriggerDown := true
  283. If (!isCtrlDown) {
  284. isCtrlDown := true
  285. SendInput {Ctrl down}
  286. }
  287. SendInput {f12 down}
  288. } else If (State.bRightTrigger <= TRIGGER_DEAD_ZONE and isRightTriggerDown) {
  289. isRightTriggerDown := false
  290. SendInput {f12 up}
  291. If (!State.bLeftTrigger and !isLeftTriggerDown and isCtrlDown) {
  292. isCtrlDown := false
  293. SendInput {Ctrl up}
  294. }
  295. }
  296.  
  297. If (isLeftTriggerDown or isRightTriggerDown or isButtonStartDown) {
  298. If (!isDpadUpDown and State.wButtons & XINPUT_GAMEPAD_DPAD_UP) {
  299. SendInput {f1}
  300.  
  301. isDpadUpDown := true
  302. } else If (isDpadUpDown and !(State.wButtons & XINPUT_GAMEPAD_DPAD_UP)) {
  303. isDpadUpDown := false
  304. }
  305. If (!isDpadRightDown and State.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) {
  306. SendInput {f2}
  307.  
  308. isDpadRightDown := true
  309. } else If (isDpadRightDown and !(State.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)) {
  310. isDpadRightDown := false
  311. }
  312. If (!isDpadDownDown and State.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {
  313. SendInput {f3}
  314.  
  315. isDpadDownDown := true
  316. } else If (isDpadDownDown and !(State.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)) {
  317. isDpadDownDown := false
  318. }
  319. If (!isDpadLeftDown and State.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) {
  320. SendInput {f4}
  321.  
  322. isDpadLeftDown := true
  323. } else If (isDpadLeftDown and !(State.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)) {
  324. isDpadLeftDown := false
  325. }
  326. }
  327.  
  328. If (!isButtonADown and State.wButtons & XINPUT_GAMEPAD_A) {
  329. If (isLeftTriggerDown or isRightTriggerDown) {
  330. SendInput {f5}
  331. } else {
  332. If (ButtonLayout == "GAMECUBE" or ButtonLayout == "XBOX") {
  333. If (ConfirmButton == "A") {
  334. Gosub, SendConfirmKey
  335. } else If (CancelButton == "A") {
  336. Gosub, SendCancelKey
  337. } else If (MainMenuButton == "A") {
  338. Gosub, SendMainMenuKey
  339. } else If (ActiveWindowButton == "A") {
  340. Gosub, SendActiveWindowKey
  341. }
  342. } else If (ButtonLayout == "PLAYSTATION") {
  343. If (ConfirmButton == "CROSS") {
  344. Gosub, SendConfirmKey
  345. } else If (CancelButton == "CROSS") {
  346. Gosub, SendCancelKey
  347. } else If (MainMenuButton == "CROSS") {
  348. Gosub, SendMainMenuKey
  349. } else If (ActiveWindowButton == "CROSS") {
  350. Gosub, SendActiveWindowKey
  351. }
  352. } else If (ButtonLayout == "NINTENDO") {
  353. If (ConfirmButton == "B") {
  354. Gosub, SendConfirmKey
  355. } else If (CancelButton == "B") {
  356. Gosub, SendCancelKey
  357. } else If (MainMenuButton == "B") {
  358. Gosub, SendMainMenuKey
  359. } else If (ActiveWindowButton == "B") {
  360. Gosub, SendActiveWindowKey
  361. }
  362. }
  363. }
  364.  
  365. isButtonADown := true
  366. } else If (isButtonADown and !(State.wButtons & XINPUT_GAMEPAD_A)) {
  367. isButtonADown := false
  368. }
  369. If (!isButtonBDown and State.wButtons & XINPUT_GAMEPAD_B) {
  370. If (isLeftTriggerDown or isRightTriggerDown) {
  371. SendInput {f7}
  372. } else {
  373. If (ButtonLayout == "GAMECUBE") {
  374. If (ConfirmButton == "X") {
  375. Gosub, SendConfirmKey
  376. } else If (CancelButton == "X") {
  377. Gosub, SendCancelKey
  378. } else If (MainMenuButton == "X") {
  379. Gosub, SendMainMenuKey
  380. } else If (ActiveWindowButton == "X") {
  381. Gosub, SendActiveWindowKey
  382. }
  383. } else If (ButtonLayout == "XBOX") {
  384. If (ConfirmButton == "B") {
  385. Gosub, SendConfirmKey
  386. } else If (CancelButton == "B") {
  387. Gosub, SendCancelKey
  388. } else If (MainMenuButton == "B") {
  389. Gosub, SendMainMenuKey
  390. } else If (ActiveWindowButton == "B") {
  391. Gosub, SendActiveWindowKey
  392. }
  393. } else If (ButtonLayout == "PLAYSTATION") {
  394. If (ConfirmButton == "CIRCLE") {
  395. Gosub, SendConfirmKey
  396. } else If (CancelButton == "CIRCLE") {
  397. Gosub, SendCancelKey
  398. } else If (MainMenuButton == "CIRCLE") {
  399. Gosub, SendMainMenuKey
  400. } else If (ActiveWindowButton == "CIRCLE") {
  401. Gosub, SendActiveWindowKey
  402. }
  403. } else If (ButtonLayout == "NINTENDO") {
  404. If (ConfirmButton == "A") {
  405. Gosub, SendConfirmKey
  406. } else If (CancelButton == "A") {
  407. Gosub, SendCancelKey
  408. } else If (MainMenuButton == "A") {
  409. Gosub, SendMainMenuKey
  410. } else If (ActiveWindowButton == "A") {
  411. Gosub, SendActiveWindowKey
  412. }
  413. }
  414. }
  415.  
  416. isButtonBDown := true
  417. } else If (isButtonBDown and !(State.wButtons & XINPUT_GAMEPAD_B)) {
  418. isButtonBDown := false
  419. }
  420. If (!isButtonXDown and State.wButtons & XINPUT_GAMEPAD_X) {
  421. If (isLeftTriggerDown or isRightTriggerDown) {
  422. SendInput {f6}
  423. } else {
  424. If (ButtonLayout == "GAMECUBE") {
  425. If (ConfirmButton == "B") {
  426. Gosub, SendConfirmKey
  427. } else If (CancelButton == "B") {
  428. Gosub, SendCancelKey
  429. } else If (MainMenuButton == "B") {
  430. Gosub, SendMainMenuKey
  431. } else If (ActiveWindowButton == "B") {
  432. Gosub, SendActiveWindowKey
  433. }
  434. } else If (ButtonLayout == "XBOX") {
  435. If (ConfirmButton == "X") {
  436. Gosub, SendConfirmKey
  437. } else If (CancelButton == "X") {
  438. Gosub, SendCancelKey
  439. } else If (MainMenuButton == "X") {
  440. Gosub, SendMainMenuKey
  441. } else If (ActiveWindowButton == "X") {
  442. Gosub, SendActiveWindowKey
  443. }
  444. } else If (ButtonLayout == "PLAYSTATION") {
  445. If (ConfirmButton == "SQUARE") {
  446. Gosub, SendConfirmKey
  447. } else If (CancelButton == "SQUARE") {
  448. Gosub, SendCancelKey
  449. } else If (MainMenuButton == "SQUARE") {
  450. Gosub, SendMainMenuKey
  451. } else If (ActiveWindowButton == "SQUARE") {
  452. Gosub, SendActiveWindowKey
  453. }
  454. } else If (ButtonLayout == "NINTENDO") {
  455. If (ConfirmButton == "Y") {
  456. Gosub, SendConfirmKey
  457. } else If (CancelButton == "Y") {
  458. Gosub, SendCancelKey
  459. } else If (MainMenuButton == "Y") {
  460. Gosub, SendMainMenuKey
  461. } else If (ActiveWindowButton == "Y") {
  462. Gosub, SendActiveWindowKey
  463. }
  464. }
  465. }
  466.  
  467. isButtonXDown := true
  468. } else If (isButtonXDown and !(State.wButtons & XINPUT_GAMEPAD_X)) {
  469. isButtonXDown := false
  470. }
  471. If (!isButtonYDown and State.wButtons & XINPUT_GAMEPAD_Y) {
  472. If (isLeftTriggerDown or isRightTriggerDown) {
  473. SendInput {f8}
  474. } else {
  475. If (ButtonLayout == "GAMECUBE" or ButtonLayout == "XBOX") {
  476. If (ConfirmButton == "Y") {
  477. Gosub, SendConfirmKey
  478. } else If (CancelButton == "Y") {
  479. Gosub, SendCancelKey
  480. } else If (MainMenuButton == "Y") {
  481. Gosub, SendMainMenuKey
  482. } else If (ActiveWindowButton == "Y") {
  483. Gosub, SendActiveWindowKey
  484. }
  485. } else If (ButtonLayout == "PLAYSTATION") {
  486. If (ConfirmButton == "TRIANGLE") {
  487. Gosub, SendConfirmKey
  488. } else If (CancelButton == "TRIANGLE") {
  489. Gosub, SendCancelKey
  490. } else If (MainMenuButton == "TRIANGLE") {
  491. Gosub, SendMainMenuKey
  492. } else If (ActiveWindowButton == "TRIANGLE") {
  493. Gosub, SendActiveWindowKey
  494. }
  495. } else If (ButtonLayout == "NINTENDO") {
  496. If (ConfirmButton == "X") {
  497. Gosub, SendConfirmKey
  498. } else If (CancelButton == "X") {
  499. Gosub, SendCancelKey
  500. } else If (MainMenuButton == "X") {
  501. Gosub, SendMainMenuKey
  502. } else If (ActiveWindowButton == "X") {
  503. Gosub, SendActiveWindowKey
  504. }
  505. }
  506. }
  507.  
  508. isButtonYDown := true
  509. } else If (isButtonYDown and !(State.wButtons & XINPUT_GAMEPAD_Y)) {
  510. isButtonYDown := false
  511. }
  512.  
  513. If (!isButtonBackDown and State.wButtons & XINPUT_GAMEPAD_BACK) {
  514. SendInput {Ctrl down}
  515. SendInput {f9 down}
  516.  
  517. isButtonBackDown := true
  518. } else If (isButtonBackDown and !(State.wButtons & XINPUT_GAMEPAD_BACK)) {
  519. SendInput {f9 up}
  520. SendInput {Ctrl up}
  521.  
  522. isButtonBackDown := false
  523. }
  524. If (!isButtonStartDown and State.wButtons & XINPUT_GAMEPAD_START) {
  525. SendInput {Ctrl down}
  526. SendInput {f10 down}
  527.  
  528. isButtonStartDown := true
  529. } else If (isButtonStartDown and !(State.wButtons & XINPUT_GAMEPAD_START)) {
  530. SendInput {f10 up}
  531. SendInput {Ctrl up}
  532.  
  533. isButtonStartDown := false
  534. }
  535. }
  536. }
  537. }
  538. Sleep, 10
  539. }
  540.  
  541. ; Helper subroutines. *DON'T* modify these to remap, instead just change which buttons call them
  542. SendConfirmKey:
  543. SendInput {Enter}
  544. return
  545. SendCancelKey:
  546. SendInput {Esc}
  547. return
  548. SendMainMenuKey:
  549. SendInput {NumpadSub}
  550. return
  551. SendActiveWindowKey:
  552. SendInput {NumpadAdd}
  553. return
  554.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement