Advertisement
djvj

keymapper test with numput

Feb 9th, 2016
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.06 KB | None | 0 0
  1. MCRC=D7AF959A
  2. MVersion=1.1.5
  3.  
  4. RunAHKKeymapper(method) {
  5. Global ahkDefaultProfile,ahkFEProfile,ahkRomProfile,ahkEmuProfile,ahkSystemProfile,ahkRocketLauncherProfile,ahkLauncherPath,ahkLauncherExe,keymapperFrontEndProfile
  6. Global systemName,dbName,emuName,moduleExtensionsPath,contextOnExit
  7. Log("RunAHKKeymapper - Started")
  8.  
  9. If (method = "load")
  10. { Log("RunAHKKeymapper - Loading " . dbName . ", " . emuName . ", " . systemName . ", or _Default AHK Keymapper profile",4)
  11. profile := GetAHKProfile(ahkRomProfile . "|" . ahkEmuProfile . "|" . ahkSystemProfile . "|" . ahkDefaultProfile)
  12. unloadAHK := 1 ; this method we don't want to run any ahk profile if none were found
  13. } Else If (method = "unload" && keymapperFrontEndProfile = "ahk" && !contextOnExit) ; user must have ahk selected to load an ahk FE profile
  14. { Log("RunAHKKeymapper - Loading Front End AHK Keymapper profile",4)
  15. profile := GetAHKProfile(ahkFEProfile)
  16. unloadAHK := 1 ; this method we don't want to run any ahk profile if none were found
  17. } Else If (method = "menu") ; this method we do not want to unload AHK if a new profile was not found, existing profile should stay running
  18. { Log("RunAHKKeymapper - Loading RocketLauncher AHK Keymapper profile",4)
  19. profile := GetAHKProfile(ahkRocketLauncherProfile)
  20. } Else If (method = "unload")
  21. { Log("RunAHKKeymapper - Unloading AhkLauncher",4)
  22. unloadAHK := 1
  23. }
  24. If (unloadAHK || profile) ; if a profile was found or this method should unload the existing AHK profile
  25. { Log("RunAHKKeymapper - If " . ahkLauncherExe . " is running, need to close it first before a new profile can be loaded",4)
  26. If Process("Exist", ahkLauncherExe) {
  27. Process("Close", ahkLauncherExe) ; close ahkLauncher first
  28. Process("WaitClose", ahkLauncherExe)
  29. }
  30. }
  31.  
  32. If profile { ; if a profile was found, load it
  33. If FileExist(moduleExtensionsPath . "\autohotkey.dll")
  34. ScriptError("Please delete autohotkey.dll from the folder """ . moduleExtensionsPath . """ as it will cause errors with " . ahkLauncherExe)
  35. Log("RunAHKKeymapper - This profile was found and needs to be loaded: " . profile,4)
  36. Run(ahkLauncherExe . " -notray """ . profile . """", ahkLauncherPath) ; load desired ahk profile
  37. }
  38. Log("RunAHKKeymapper - Ended")
  39. }
  40.  
  41. ; Only use FEProfile if you want to ignore rom and system profile
  42. ; ProfilePrefixes separate prefixes with a "|"
  43. GetAHKProfile(ProfilePrefixes) {
  44. Global systemName, dbName, emuName, keymapperProfilePath ;for script error
  45. Log("GetAHKProfile - Started")
  46. Loop, Parse, ProfilePrefixes, |
  47. { profile := A_LoopField . ".ahk"
  48. Log("GetAHKProfile - Searching for: " . profile,5)
  49. If FileExist(profile)
  50. { foundProfile := 1
  51. Log("GetAHKProfile - Ended and found: " . profile)
  52. Return profile
  53. }
  54. }
  55. If !foundProfile
  56. Log("GetAHKProfile - Ended and no profile found")
  57. Return
  58. }
  59.  
  60. ;##################################################################
  61. ;LoadPreferredControllers(JoyIDsPreferredControllers)
  62. ;##################################################################
  63. ;Creates a list for Joy IDs by creating a list of currently connected controllers and re-arranging that list to match the order presented in the Preferred Controller List.
  64. ;If both an Oem Name and a related custom joy name is found in the list, the oem name position is used
  65. ;JoyIDsPreferredControllers this is the list of preferred controllers
  66. ;it should be a list of controller names separated with |
  67. ;##################################################################
  68.  
  69. LoadPreferredControllers(JoyIDsPreferredControllers) {
  70. Global CustomJoyNameArray
  71. Log("LoadPreferredControllers - Started")
  72. Log("LoadPreferredControllers - JoyIDsPreferredControllers = " . JoyIDsPreferredControllers,5)
  73. ; 16 is max number of joysticks windows and joyids allows
  74. Log("LoadPreferredControllers - Creating a list of currently connected joysticks",5)
  75. JoystickArray := GetJoystickArray()
  76. Loop, 16
  77. { ControllerName := JoystickArray[A_Index,1]
  78. MID := JoystickArray[A_Index,2]
  79. PID := JoystickArray[A_Index,3]
  80. GUID := JoystickArray[A_Index,4]
  81. If ControllerName
  82. { ;CustomJoyNameArray is an Associative Array that associates a custom joy name to a controller name. See ahk_l documentation for objects.
  83. CustomJoyName := CustomJoyNameArray[ControllerName]
  84. ;prepare for string position searching
  85. JoyIDsPreferredControllersModified := "|" . JoyIDsPreferredControllers . "|"
  86. ;store last position this will be used for controllers not in PreferredControllerList
  87. LastPosition := StrLen(JoyIDsPreferredControllersModified)
  88. ;position order 1 is for the normal controller name and position order 2 is for the custom name
  89. ;normal controller name always takes higher priority over custom names since it is more specific
  90. PositionOrder_1 := InStr(JoyIDsPreferredControllersModified, "|" . ControllerName . "|")
  91. If CustomJoyName
  92. PositionOrder_2 := InStr(JoyIDsPreferredControllersModified, "|" . CustomJoyName . "|")
  93.  
  94. If PositionOrder_1
  95. PositionOrder := PositionOrder_1
  96. Else If PositionOrder_2
  97. PositionOrder := PositionOrder_2
  98. Else
  99. PositionOrder := LastPosition
  100. ;Position Order is the order found in the JoyIDsPreferredControllersModified list
  101. ;it will be appended with a decimal value relative to order they were found in.
  102. ;create sorting string also add the order found. If controllers are not found in preferred, plug-in order is used.
  103. ;example format: 123.01|360 Controller
  104. Log("LoadPreferredControllers - Preferred Order Sorting List -> " . PositionOrder . "." . SubStr("0" . A_Index, -1) . "|" . MID . "|" . PID . "|" . GUID,5)
  105. If !String2Sort
  106. String2Sort := PositionOrder . "." . SubStr("0" . A_Index, -1) . "|" . MID . "|" . PID . "|" . GUID
  107. Else
  108. String2Sort .= "`n" . PositionOrder . "." . SubStr("0" . A_Index, -1) . "|" . MID . "|" . PID . "|" . GUID
  109. }
  110. }
  111. Log("LoadPreferredControllers - Sorting Currently Connected joysticks List to match the order of the Preferred Controller List")
  112. ;sort numerically
  113. Sort, String2Sort, N
  114. Log("LoadPreferredControllers - Assigning the New Joystick IDs according to the preferred list for the active controllers")
  115. ;parse the string
  116. Loop, Parse, String2Sort, `n
  117. { StringSplit, JoyIDsSortArray, A_LoopField, |
  118. MID := JoyIDsSortArray2
  119. PID := JoyIDsSortArray3
  120. GUID := JoyIDsSortArray4
  121. ChangeJoystickID(MID,PID,GUID,A_Index)
  122. }
  123. Log("LoadPreferredControllers - Ended")
  124. }
  125.  
  126. ;##################################################################
  127. ;RunKeyMapper(keymapperLoad_Or_Unload,keymapper)
  128. ;##################################################################
  129. ;keymapperLoad_Or_Unload can be = "load" or "unload" or "menu"
  130. ; menu is for loading the RocketLauncher menu profile
  131. ; keymapper can be = "xpadder", "joytokey" or "joy2key"
  132. ; this function returns FEProfile
  133. ;##################################################################
  134.  
  135. RunKeymapper(keymapperLoad_Or_Unload,Keymapper) {
  136. Global blankProfile,defaultProfile,FEProfile,romProfile,emuProfile,xPadderSystemProfile,systemProfile,RocketLauncherProfile
  137. Global systemName,dbName,emuName,keymapperFrontEndProfileName,keymapperFrontEndProfile,contextOnExit
  138. Global CustomJoyNameArray
  139. Global keymapperFullPath
  140. Global KeymapperRocketLauncherProfileEnabled, keymapperEnabled
  141. Static keymapperExists
  142. ;Global keymapperLoad_Or_Unload
  143. Log("RunKeymapper - Started, using method """ . keymapperLoad_Or_Unload . """")
  144.  
  145. If ((KeymapperRocketLauncherProfileEnabled = "false") OR (keymapperEnabled = "false")) AND (keymapperLoad_Or_Unload = "menu")
  146. Return
  147.  
  148. joystickArray := GetJoystickArray()
  149. If keymapperFullPath {
  150. SplitPath, keymapperFullPath, keymapperExe, keymapperPath, keymapperExt ; splitting pathname into variables
  151. If !keymapperExists {
  152. If !FileExist(keymapperPath . "\" . keymapperExe) {
  153. Log("RunKeymapper - Could not locate your keymapper application here: """ . keymapperFullPath . """",2)
  154. Return
  155. } Else {
  156. Log("RunKeymapper - Found your keymapper application here: """ . keymapperFullPath . """",5)
  157. keymapperExists := 1
  158. }
  159. }
  160. } Else
  161. ScriptError("There was an error with getting your keymapperFullPath, please report this: """ . keymapperFullPath . """")
  162.  
  163. ;define profiles to load and run keymappers
  164.  
  165. If (keymapper="xpadder")
  166. { Log("RunKeymapper - Looping through controllers to find xpadder profiles for each one",5)
  167. Loop,16
  168. { ControllerName := joystickArray[A_Index,1]
  169. If ControllerName
  170. { Log("RunKeymapper - ID: " . A_Index . " Now searching for a matching profile for this controller: """ . ControllerName . """",5)
  171. If (keymapperLoad_Or_Unload = "load")
  172. Profile2Load := GetProfile(keymapper, romProfile . "|" . emuProfile . "|" . xPadderSystemProfile . "|" . defaultProfile . "|" . blankProfile, keymapperLoad_Or_Unload, ControllerName, Player_Number)
  173. Else If (keymapperLoad_Or_Unload = "unload")
  174. Profile2Load := GetProfile(keymapper, (If keymapperFrontEndProfile = "xpadder" && !contextOnExit ? FEProfile . "|" : "") . blankProfile, keymapperLoad_Or_Unload, ControllerName, Player_Number)
  175. Else If (keymapperLoad_Or_Unload = "menu")
  176. Profile2Load := GetProfile(keymapper, RocketLauncherProfile . "|" . blankProfile, keymapperLoad_Or_Unload, ControllerName, Player_Number)
  177.  
  178. If !ProfilesInIdOrder
  179. ProfilesInIdOrder := Profile2Load
  180. Else
  181. ProfilesInIdOrder .= "|" . Profile2Load
  182. }
  183. }
  184. RunXpadder(keymapperPath,keymapperExe,ProfilesInIdOrder,joystickArray)
  185. } Else If (keymapper="joy2key") OR (keymapper = "joytokey")
  186. { Log("RunKeymapper - Looping through controllers to find joytokey profiles for each one",5)
  187. If (keymapperLoad_Or_Unload = "load")
  188. Profile2Load := GetProfile(keymapper, romProfile . "\" . dbName . "|" . emuProfile . "\" . emuName . "|" . systemProfile . "\" . systemName . "|" . defaultProfile . "\_Default", keymapperLoad_Or_Unload)
  189. Else If (keymapperLoad_Or_Unload = "unload" && keymapperFrontEndProfile = "joytokey" && !contextOnExit)
  190. Profile2Load := GetProfile(keymapper, FEProfile . "\" . keymapperFrontEndProfileName, keymapperLoad_Or_Unload)
  191. Else If (keymapperLoad_Or_Unload = "unload" && keymapperFrontEndProfile != "joytokey" && !contextOnExit)
  192. Profile2Load := ; user does not have joytokey set as their FE profile choice, keeping this blank will unload joytokey
  193. Else If (keymapperLoad_Or_Unload = "menu")
  194. Profile2Load := GetProfile(keymapper, RocketLauncherProfile . "\RocketLauncher", keymapperLoad_Or_Unload)
  195.  
  196. RunJoyToKey(keymapperPath,keymapperExe,Profile2Load)
  197. }
  198. Log("RunKeymapper - Ended")
  199. Return FEProfile
  200. }
  201.  
  202. ;#########################
  203. ; GetProfile(ControllerName,keymapper, ProfilePrefixes [,PlayerNumber], keymapperLoad_Or_Unload)
  204. ; Only use FEProfile if you want to ignore rom and system profile
  205. ; PlayerNumber is there for possible use by other functions including this one
  206. ; keymapperLoad_Or_Unload can be load, unload, or menu. for error purposes
  207. ; ControllerName must not be empty (no error checks in function)
  208. ; keymapper needs to be a valid keymapper (no error checks in function)
  209. ; ProfilePrefixes separate prefixes with a "|"
  210. ; this function is menat only for use by the Load keymapper function.
  211. ;#########################
  212.  
  213. GetProfile(keymapper, ProfilePrefixes, keymapperLoad_Or_Unload = "load", ControllerName = "", ByRef PlayerNumber = 1) {
  214. Global CustomJoyNameArray, blankProfile, systemName, dbName, emuName, keymapperFrontEndProfileName, keymapperProfilePath
  215. Static ExtensionList := {xpadder: ".xpadderprofile",joy2key: ".cfg",joytokey: ".cfg"} ; static associative array that is holds what extension is for what keymapper.
  216. ;keymapper: "keymapper profile extension". Adding name variations to this array should not slow down the script which means name variations can be accounted for.
  217. keymapperExtension := ExtensionList[keymapper]
  218. PlayerNumber := (If PlayerNumber = "" ? (1) : (PlayerNumber)) ; perform check for blank PlayerNumber
  219.  
  220. If (keymapperExtension = ".xpadderprofile") {
  221. PlayerIndicator := "\p" . PlayerNumber
  222.  
  223. CustomJoyName := CustomJoyNameArray[ControllerName]
  224. ;If CustomJoyName Exists look for it. If not, don't look for an empty [].
  225. If CustomJoyName
  226. { LoopNumber := 3
  227. PossibleJoyNames1 := "\" . ControllerName
  228. PossibleJoyNames2 := "\" . CustomJoyName
  229. PossibleJoyNames3 := ""
  230. } Else {
  231. LoopNumber := 2
  232. PossibleJoyNames1 := "\" . ControllerName
  233. PossibleJoyNames2 := ""
  234. }
  235.  
  236. } Else {
  237. PlayerIndicator := "" ;joy2key does not need a player number since the numbers are stored in the cfg
  238.  
  239. ;this is so we don't look for controller specific profiles
  240. LoopNumber := 1
  241. PossibleJoyNames1 := ""
  242. }
  243.  
  244.  
  245. ;start looking for profiles
  246. ;profile prefixes for loading should look like %romProfile%|%emuProfile%|%systemProfile%|%defaultProfile%|%blankProfile%
  247. ;profile prefixes for unloading should look like %FEProfile%|%blankProfile%
  248. Profile2Load := ""
  249. Log("GetProfile - Searching for these profiles (| delimited): " . ProfilePrefixes,5)
  250. Loop,Parse,ProfilePrefixes,|
  251. { ProfileName := A_LoopField
  252. Loop, %LoopNumber%
  253. { JoyName := PossibleJoyNames%A_Index%
  254. If (ProfileName = blankProfile) ;blankProfile is global variable. This check is here because blank profiles don't need player number.
  255. { Profile := ProfileName . keymapperExtension
  256. Log("GetProfile - Searching -> " . Profile,5)
  257. If FileExist(Profile)
  258. { Profile2Load := Profile
  259. Log("GetProfile - Loading Profile -> " . Profile2Load)
  260. PlayerNumber++
  261. Return Profile2Load
  262. }
  263. Break
  264. } Else {
  265. Profile := ProfileName . JoyName . PlayerIndicator . keymapperExtension
  266. Log("GetProfile - Searching for a Player " . PlayerNumber . " profile -> " . Profile,5)
  267. If FileExist(Profile)
  268. { Profile2Load := Profile
  269. Log("GetProfile - Loading Player " . PlayerNumber . " Profile -> " . Profile2Load)
  270. PlayerNumber++
  271. Return Profile2Load
  272. }
  273. }
  274. }
  275. }
  276. If !Profile2Load
  277. If (keymapperLoad_Or_Unload = "load")
  278. Log("GetProfile - Keymapper support is enabled for """ . keymapper . """`, but could not find a """ . dbName . """`, """ . emuName . """`, """ . systemName . """`, default`, a """ . ControllerName . """ player " . PlayerNumber . " profile or a blank profile in """ . keymapperProfilePath . """ for controller """ . ControllerName . """",2)
  279. Else If (keymapperLoad_Or_Unload = "unload")
  280. Log("GetProfile - Keymapper support is enabled for """ . keymapper . """`, but could not find a " . keymapperFrontEndProfileName . " profile or a blank profile in " . keymapperProfilePath . " for controller " . ControllerName,2)
  281. Else If (keymapperLoad_Or_Unload = "menu")
  282. Log("GetProfile - Keymapper support is enabled for """ . keymapper . """`, but could not find a RocketLauncher profile or a blank profile in " . keymapperProfilePath . " for controller " . ControllerName,2)
  283. }
  284.  
  285. ;#########################
  286. ; GetJoystickArray()
  287. ; returns a 4 column by 17 row table.
  288. ; the row number is the same as the player number or id #. this is equivalent to port number + 1
  289. ; so if your joystick is in port 0 or has an id of 1 it's name will be in JoyStickArray[1,1]
  290. ; column 1 contains the oem name, column 2 contains the mid and column 3 contains the pid, column 4 contains the guid
  291. ; Guid is a Global Universal ID that is assigned by the OS. It is 128 bits and randomly generated, It is the devices unique identifier while it is plugged in.
  292. ; row 0 column 1 contains the a pipedelimited list of the ids with connected controllers. (ex: 1|2|4) this means there is a joystick for id 1, 2 and 4.
  293. ; row 0 columns 2, 3, and 4 are empty. Future info may be added here.
  294. ;#########################
  295.  
  296. GetJoystickArray() {
  297. Log("GetJoystickArray - Started")
  298. DllCall("winmm\joyConfigChanged", UInt, 0)
  299. Loop,16
  300. {
  301. port := A_Index - 1
  302. VarSetCapacity(joyState,512)
  303. NumPut(64,joyState,0,"UInt")
  304. joyError := DllCall("winmm\joyGetPosEx", "ptr", port, "ptr", &joyState)
  305. If joyError = 0
  306. joysDetected .= 1
  307. Else
  308. joysDetected .= 0
  309. }
  310. Log("GetJoystickArray - Joysticks Detected: " . joysDetected,5)
  311. joyArray := Object()
  312. Loop, 5
  313. joyArray[0,A_Index] := ""
  314. Loop, Parse, joysDetected
  315. { CurrentController := A_Index
  316. currentJoyGUID := ""
  317. Mid := "", Pid := "", joyName := "" ; Erase values
  318. If (A_LoopField = 1)
  319. { If joyArray[0,1]
  320. joyArray[0,1] := joyArray[0,1] . "|" . CurrentController
  321. Else
  322. joyArray[0,1] := CurrentController
  323. VarSetCapacity(joybank,1024,0)
  324. i := 0
  325. port := CurrentController - 1
  326. Loop, 1024
  327. { ; Get driver information
  328. err := dllcall("winmm.dll\joyGetDevCapsA",Int,port,UInt,&joybank,UInt,i)
  329. i++
  330. ; A successful dllcall returns a 0
  331. If (err = 0)
  332. { ; Converting decimal values to hex since windows uses the hex value more often
  333. offset := 0
  334. Loop, 2
  335. { SetFormat, IntegerFast, hex
  336. ret := NumGet(&joybank,offset,"UShort")
  337. ret .= ""
  338. SetFormat, IntegerFast, d
  339. ; Remove the 0x we don't need it and padding it with 0's to have a width of four
  340. ; Advice: leave these two lines out if using this function in other scripts
  341. StringTrimLeft,ret,ret,2
  342. ID%A_Index% := SubStr("0000" . ret,-3)
  343. offset := offset+2
  344. }
  345. Mid := ID1, Pid := ID2
  346. }
  347. }
  348. If !Mid && !Pid
  349. joyName := ""
  350. Else {
  351. regFolder := "VID_" . Mid . "&PID_" . Pid
  352. joyName := RegRead("HKEY_CURRENT_USER", "System\CurrentControlSet\Control\MediaProperties\PrivateProperties\Joystick\OEM\" . regFolder, "OEMName")
  353. If ErrorLevel
  354. joyName := RegRead("HKEY_LOCAL_MACHINE", "SYSTEM\CurrentControlSet\Control\MediaProperties\PrivateProperties\Joystick\OEM\" . regFolder, "OEMName")
  355. }
  356. currentJoyGUID := GetJoystickGUID(Mid,Pid,CurrentController)
  357. Log("GetJoystickArray - ID: " . CurrentController . " | Port: " . port . " | Name: " . joyName . " | MID: " . mid . " | PID: " . pid . " | GUID: " . currentJoyGUID,5)
  358. }
  359. joyName := Trim(joyName) ; Xpadder trims leading and trailing whitespace so we will do the same
  360. ; Append empty string to avoid ahk's auto converting string type containing integers to integer type because we want the leading zeros
  361. joyArray[CurrentController,1] := joyName . ""
  362. joyArray[CurrentController,2] := Mid . ""
  363. joyArray[CurrentController,3] := Pid . ""
  364. joyArray[CurrentController,4] := currentJoyGUID . ""
  365. joyArray[CurrentController,5] := ""
  366. }
  367. Log("GetJoystickArray - Ended")
  368. Return joyArray
  369. }
  370.  
  371. ;#########################
  372. ; GetJoystickGUID(Mid,Pid,JoystickID)
  373. ; This function is used internally by the GetJoystickArray() function
  374. ; It returns the matching guid for a joystick device. Empty if error occurred.
  375. ; Mid = JoystickArray[JoystickID,2]
  376. ; PID = JoystickArray[JoystickID,3]
  377. ; JoystickID = 1 through 16
  378. ;#########################
  379.  
  380. GetJoystickGUID(Mid,Pid,JoystickID) {
  381. If !Mid OR !PID OR !JoystickID
  382. Return
  383. If JoystickID not between 1 and 16
  384. Return
  385.  
  386. Log("GetJoystickGUID - Started")
  387. SetFormat, IntegerFast, hex
  388. REG_JOY_ID := JoystickID - 1
  389. REG_JOY_ID .= "000000"
  390. StringReplace, REG_JOY_ID , REG_JOY_ID, x
  391. SetFormat, IntegerFast, d
  392.  
  393. If A_OSVersion in WIN_2003,WIN_XP,WIN_2000,WIN_NT4,WIN_95,WIN_98,WIN_ME
  394. RootKey := "HKEY_LOCAL_MACHINE"
  395. Else
  396. RootKey := "HKEY_CURRENT_USER"
  397.  
  398. Loop, %RootKey%, System\CurrentControlSet\Control\MediaProperties\PrivateProperties\DirectInput\VID_%Mid%&PID_%Pid%\Calibration,1,1
  399. {
  400. If (A_LoopRegName = "Joystick Id") {
  401. RegRead, regvar
  402. If (regvar = REG_JOY_ID) {
  403. RegSubKey := A_LoopRegSubKey
  404. Break
  405. }
  406. }
  407. }
  408. GUID := RegRead(RootKey, RegSubKey, "GUID")
  409. Log("GetJoystickGUID - Ended and found GUID: " . GUID)
  410. Return GUID
  411. }
  412.  
  413. ;#########################
  414. ; ChangeJoystickID(Mid,Pid,GUID,NewJoystickID)
  415. ; This is an awesome little function that changes the joystick id.
  416. ; It gives us more control over what devices are moved than JoyIDs.exe ever did.
  417. ; It returns 0 if successful, 1 if unsuccessful.
  418. ; Mid = JoystickArray[JoystickID,2]
  419. ; PID = JoystickArray[JoystickID,3]
  420. ; GUID = JoystickArray[JoystickID,4]
  421. ; NewJoystickID = 1 through 16, this is the new ID for the joystick with the matching MID,PID,GUID
  422. ; it has no way of checking to make sure it's not assigning the same id as an already active controller,
  423. ; so this check must be done outside the function.
  424. ;#########################
  425.  
  426. ChangeJoystickID(Mid,Pid,GUID,NewJoystickID) {
  427. Log("ChangeJoystickID - Started")
  428. If !Mid OR !Pid OR !GUID OR !NewJoystickID
  429. Return 1
  430. If NewJoystickID not between 1 and 16
  431. Return 1
  432.  
  433. SetFormat, IntegerFast, hex
  434. NewJoystickID := NewJoystickID - 1
  435. NewJoystickID .= "000000"
  436. StringReplace, NewJoystickID , NewJoystickID, x
  437. SetFormat, IntegerFast, d
  438.  
  439. If A_OSVersion in WIN_2003,WIN_XP,WIN_2000,WIN_NT4,WIN_95,WIN_98,WIN_ME
  440. RootKey := "HKEY_LOCAL_MACHINE"
  441. Else
  442. RootKey := "HKEY_CURRENT_USER"
  443.  
  444. Loop, %RootKey%, System\CurrentControlSet\Control\MediaProperties\PrivateProperties\DirectInput\VID_%Mid%&PID_%Pid%\Calibration,1,1
  445. {
  446. If (A_LoopRegName = "GUID") {
  447. RegRead, regvar
  448. If (regvar = GUID) {
  449. RegSubKey := A_LoopRegSubKey
  450. break
  451. }
  452. }
  453. }
  454. jid := RegRead(RootKey, RegSubKey, "Joystick Id")
  455. RegWrite("REG_BINARY", RootKey, RegSubKey, "Joystick Id", NewJoystickID)
  456. Log("ChangeJoystickID - Swapping Joystick ID: " . jid . " to the New Joystick ID: " . NewJoystickID . ", for the Joystick VID_" . Mid . "&PID_" . Pid . "&GUID_" . GUID,5)
  457. Log("ChangeJoystickID - Ended")
  458. Return ErrorLevel
  459. }
  460.  
  461. RunXpadder(keymapperPath,keymapperExe,ProfilesInIdOrder,joystickArray) {
  462. Global joyToKeyFullPath
  463. Log("RunXpadder - Started")
  464.  
  465. ; Closing joytokey to avoid dual keymapper conflict.
  466. SplitPath, joyToKeyFullPath, joyToKeyExe, joyToKeyPath
  467. errLvl := Process("Exist", joyToKeyExe)
  468. If errLvl
  469. Process("Close", joyToKeyExe)
  470.  
  471. ; Close xpadder to refresh controllers
  472. Log("RunXpadder - Closing xpadder to refresh controllers seen by xpadder",5)
  473. Run(keymapperExe . " /C", keymapperPath,,,,1) ; enabling bypassCmdWindow
  474.  
  475. StringSplit,Profiles,ProfilesInIdOrder,|
  476. Log("RunXpadder - Creating an array of connected controllers and profiles to arrange according to the order found in " . keymapperPath . "\xpadder.ini",5)
  477. XpadderArray := []
  478. ProfileCount := 0
  479. Loop,16
  480. { ControllerName := joystickArray[A_Index,1]
  481. MID := joystickArray[A_Index,2]
  482. PID := joystickArray[A_Index,3]
  483. ; Check to see if controller name has been previously been found
  484. String := XpadderArray[ControllerName]
  485. StringSplit,SplitArray,String,|
  486. If SplitArray0
  487. { ProfileCount++
  488. Profile2Load := Profiles%ProfileCount%
  489. ; Store ID numbers that are compatible xpadder in SplitArray1
  490. ; Append the newly found profile2load with the previously found profiles associated with this controller separated with a ? to be later replaced with " "
  491. XpadderArray[ControllerName] := SplitArray1 . "|" . SplitArray2 . "?" . Profile2Load
  492. } Else If ControllerName
  493. { ProfileCount++
  494. Profile2Load := Profiles%ProfileCount%
  495.  
  496. ; Convert hexadecimal Mid and Pid values into a format compatible with xpadder's xpadder.ini
  497. ID1:=SubStr(Mid,1,2),ID2:=SubStr(Mid,3,2),ID3:=SubStr(Pid,1,2),ID4:=SubStr(Pid,3,2)
  498. Loop,4
  499. { ID%A_Index% := "0x" . ID%A_Index%
  500. ID%A_Index% += 0
  501. }
  502. ControllerID := ID1 . "`," . ID2 . "`," . ID3 . "`," . ID4
  503. Value := ControllerID . "|" . Profile2Load
  504. XpadderArray.Insert(ControllerName,Value)
  505. }
  506. }
  507. errLvl := Process("WaitClose", keymapperExe, 2) ;wait for xpadder to finish writing its values to xpadder.ini before reading and editing it
  508. If errLvl
  509. Process("Close", keymapperExe)
  510. Log("RunXpadder - Reading the order in " . keymapperPath . "\xpadder.ini and arranging profiles found to match that order",5)
  511. Loop {
  512. ; Get profiles in order as appears in xpadder.ini
  513. LoopIndex := A_Index ;record number in case we need to add a new key to xpadder.
  514. IniControllerName := IniRead(keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "Name")
  515. If (IniControllerName = "ERROR") { ;this means there are no more controllers to be found in the ini
  516. Log("RunXpadder - No more controllers to be found",5)
  517. Break
  518. }
  519. ; Look to see if the controller found in the ini is already in our array
  520. XpadderArrayValue := XpadderArray[IniControllerName]
  521. If XpadderArrayValue
  522. { StringSplit,SplitArray,XpadderArrayValue,|
  523. ; Make sure controller is not hidden. if it is one xpadder does not recognize controller and the profile loading is messed up.
  524. IniWrite(0, keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "Hidden")
  525. ; This is for later use
  526. If !IniControllersFound
  527. IniControllersFound := IniControllerName
  528. Else
  529. IniControllersFound .= "," . IniControllerName
  530. ; Start creating the string of profiles to send to xpadder
  531. If !ProfilesInXpadderOrder
  532. ProfilesInXpadderOrder := SplitArray2
  533. Else
  534. ProfilesInXpadderOrder .= """ """ . SplitArray2
  535. ; Because we looped and looked up profiles in the array in the order of the ini, they will be in order when sent to xpadder
  536. }
  537. }
  538. For key, XpadderArrayValue in XpadderArray
  539. {
  540. If !RegExMatch(key,"i)" . IniControllersFound)
  541. { Log("RunXpadder - Could not find " . key . " in xpadder.ini. Writing the new controller to xpadder.ini",5)
  542. StringSplit,SplitArray,XpadderArrayValue,|
  543. ; Write new key values for the controllers not found in xpadder.ini to xpadder so it sees them when it restarts.
  544. IniWrite(key, keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "Name")
  545. IniWrite(SplitArray1, keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "ID")
  546. IniWrite(0, keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "Hidden")
  547.  
  548. ; Look for matching xpaddercontroller file in xpadder.exe root directory
  549. CustomJoyName := CustomJoyNameArray[key]
  550. ; Profiles can be named after CustomJoyName or controller name. Oem Name takes priority.
  551. If (FileExist(keymapperPath . key . ".xpaddercontroller")) {
  552. Log("RunXpadder - Loading " . keymapperPath . "\" . key ".xpaddercontroller layout for the new controller",5)
  553. IniWrite(key . ".xpaddercontroller", keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "File")
  554. } Else If (CustomJoyName AND FileExist(keymapperPath . CustomJoyName . ".xpaddercontroller")) {
  555. Log("RunXpadder - Loading " . keymapperPath . "\" . CustomJoyName ".xpaddercontroller layout for the new controller",5)
  556. IniWrite(CustomJoyName . ".xpaddercontroller", keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "File")
  557. } Else {
  558. ; This means a xpaddercontroller profile has not been found
  559. ScriptError("Please create a xpaddercontroller profile named either " . key . " or " . CustomJoyName . ". It also needs to be in the same folder as xpadder.exe")
  560. }
  561. Loop, 4
  562. IniWrite(A_Space, keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "Recent" . A_Index)
  563. LoopIndex++
  564. If !ProfilesInXpadderOrder
  565. ProfilesInXpadderOrder := SplitArray2
  566. Else
  567. ProfilesInXpadderOrder .= """ """ . SplitArray2
  568. }
  569. }
  570. StringReplace, ProfilesInXpadderOrder, ProfilesInXpadderOrder, ?, " ", All
  571. If ProfilesInXpadderOrder
  572. Run(keymapperExe . " """ . ProfilesInXpadderOrder . """ /M", keymapperPath, "Hide",,,1) ; enabling bypassCmdWindow)
  573. Else
  574. Log("RunXpadder - No profiles found and nothing to tell Xpadder to load",2)
  575. Log("RunXpadder - Ended")
  576. }
  577.  
  578. RunJoyToKey(keymapperPath,keymapperExe,Profile="") {
  579. Global xpadderFullPath
  580. Log("RunJoyToKey - Started")
  581. ; Closing xpadder to avoid dual keymapper conflict.
  582. If FileExist(xpadderFullPath) {
  583. SplitPath, xpadderFullPath, xpadderexe, xpadderdir
  584. errLvl := Process("Exist", xpadderexe)
  585. If errLvl
  586. { Log("RunJoyToKey - Closing xpadder to avoid dual keymapper conflict",2)
  587. Run(xpadderexe . " /C", xpadderdir,,,,1) ; enabling bypassCmdWindow)
  588. errLvl := Process("Exist", xpadderexe)
  589. If errLvl
  590. Process("Close", xpadderexe)
  591. }
  592. }
  593.  
  594. exitMeansMinimize := IniRead(keymapperPath . "\JoyToKey.ini", "LastStatus", "ExitMeansMinimize")
  595. If (exitMeansMinimize = "ERROR")
  596. ScriptError("You are using KeyMapper support but are not up-to-date with JoyToKey or cannot find JoyToKey.ini in " . keymapperPath . "`nPlease make sure you are running JoyToKey v5.1.0 or later",10)
  597. Else If ( exitMeansMinimize = 1 ) {
  598. Process("Close", keymapperExe)
  599. Process("WaitClose", keymapperExe)
  600. IniWrite(0, keymapperPath . "\JoyToKey.ini", "LastStatus", "ExitMeansMinimize")
  601. }
  602. DetectHiddenWindows, On
  603. WinClose("JoyToKey ahk_class TMainForm")
  604.  
  605. errLvl := Process("WaitClose", keymapperExe, 2)
  606. If errLvl
  607. Process("Close", keymapperExe)
  608. ; RocketLauncherUI may turn off joytokey from starting minimized, let's set it just in case
  609. startMinimized := IniRead(keymapperPath . "\JoyToKey.ini", "LastStatus", "StartIconified")
  610. If startMinimized != 1
  611. IniWrite(1, keymapperPath . "\JoyToKey.ini", "LastStatus", "StartIconified")
  612. ; Finally we start the keymapper with the cfg profile we found
  613. If Profile
  614. Run(keymapperExe . " """ . Profile . """", keymapperPath,,,,1) ; enabling bypassCmdWindow)
  615. Log("RunJoyToKey - Ended")
  616. }
  617.  
  618. Keymapper_PauseProfileList(ControllerName,PlayerNumber,keymapper) {
  619. ; [file name (no extension), type (options are default,system,emulator,game),0 or 1 (1 if controller specific), full path to file]
  620. Global blankProfile,defaultProfile,romProfile,emuProfile,xPadderSystemProfile,systemProfile
  621. Global systemName,dbName,emuName ;for use with joytokey
  622. Global CustomJoyNameArray ;for use with xpadder
  623. Log("Keymapper_PauseProfileList - Started")
  624.  
  625. If (keymapper = "xpadder")
  626. { keymapperExtension = .xpadderprofile
  627. sProfile := xPadderSystemProfile
  628. PlayerIndicator := "\p" . PlayerNumber
  629. CustomJoyName := CustomJoyNameArray[ControllerName]
  630. If CustomJoyName
  631. { LoopNumber := 3
  632. PossibleJoyNames1 := "\" . ControllerName
  633. PossibleJoyNames2 := "\" . CustomJoyName
  634. PossibleJoyNames3 := ""
  635. } Else {
  636. LoopNumber := 2
  637. PossibleJoyNames1 := "\" . ControllerName
  638. PossibleJoyNames2 := ""
  639. }
  640. } Else { ; keymapper = joy2key
  641. keymapperExtension := ".cfg"
  642. sProfile := systemProfile
  643. LoopNumber := 1
  644. PossibleJoyNames1 := "" ;joy2key does not use a profile per controller
  645. PlayerIndicator := "" ;joy2key and ahk do not need a player number
  646. }
  647.  
  648. ; used for finding the normally loaded profile
  649. normalProfileFound := 0
  650.  
  651. ; loop counters
  652. i := 1
  653. j := 0
  654.  
  655. ProfileList := []
  656. ProfileFolderArray := ["Game","Emulator","System","Default"]
  657. If (keymapper = "xpadder")
  658. String2Parse := romProfile . "|" . emuProfile . "|" . sProfile . "|" . defaultProfile
  659. Else { ;joytokey
  660. String2Parse := romProfile . "|" . emuProfile . "|" . sProfile . "|" . defaultProfile
  661. normProfileName := [dbName,emuName,systemName,"_Default"]
  662. }
  663. Log(String2Parse)
  664. Loop,Parse,String2Parse,|
  665. { j++
  666. FolderPath := A_LoopField
  667. ;If CustomJoyName Exists look for it. If not, don't look for a \\ directory
  668. Loop % LoopNumber
  669. {
  670. joyName := PossibleJoyNames%A_Index%
  671. If joyName
  672. Controller_Specific_Boolean := 1
  673. Else
  674. Controller_Specific_Boolean := 0
  675.  
  676. If (keymapper = "xpadder") {
  677. normProfile := FolderPath . joyName . PlayerIndicator . keymapperExtension
  678. FilePattern := FolderPath . joyName . "\*" . keymapperExtension
  679. } Else { ; keymapper = joy2key
  680. normProfile := FolderPath . "\" . normProfileName[j] . keymapperExtension
  681. FilePattern := FolderPath . "\*" . keymapperExtension
  682. }
  683. Loop % FilePattern
  684. {
  685. SplitPath,A_LoopFileFullPath,,,,FileNameNoExt
  686.  
  687. If (keymapper = "joytokey") OR (keymapper = "joy2key") {
  688. ; I find this information to be more useful because it determines if a profile will actually work if you use joytokey.
  689. ; the boolean value means profile will work, but due to joy2key limitations we don't know if the profile was made for this controller
  690. SectionName := "Joystick " . PlayerNumber
  691. CheckForSection := IniRead(A_LoopFileFullPath, "SectionName", "Axis1p") ; this key will always exist if the section exists and was properly created by joytokey
  692. If CheckForSection
  693. Controller_Specific_Boolean := 1
  694. Else
  695. Controller_Specific_Boolean := 0
  696. }
  697.  
  698. If (normProfile = A_LoopFileFullPath) && !normalProfileFound
  699. { normalProfileFound := 1
  700. Log("Keymapper_PauseProfileList - Creating Profile List (normal load profile) -> 1`," . FileNameNoExt . "`," . ProfileFolderArray[j] . "`," . Controller_Specific_Boolean . "`," . A_LoopFileFullPath,5)
  701. ProfileList[1,1] := FileNameNoExt
  702. ProfileList[1,2] := ProfileFolderArray[j]
  703. ProfileList[1,3] := Controller_Specific_Boolean
  704. ProfileList[1,4] := A_LoopFileFullPath
  705. } Else If A_LoopFileFullPath
  706. { i++
  707. Log("Keymapper_PauseProfileList - Creating Profile List -> " . i . "`," . FileNameNoExt . "`," . ProfileFolderArray[j] . "`," . Controller_Specific_Boolean . "`," . A_LoopFileFullPath,5)
  708. ProfileList[0,1] := i
  709. ProfileList[i,1] := FileNameNoExt
  710. ProfileList[i,2] := ProfileFolderArray[j]
  711. ProfileList[i,3] := Controller_Specific_Boolean
  712. ProfileList[i,4] := A_LoopFileFullPath
  713. }
  714. }
  715. }
  716. }
  717. Log("Keymapper_PauseProfileList - Ended")
  718. Return ProfileList
  719. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement