MCRC=D7AF959A
MVersion=1.1.5
RunAHKKeymapper(method) {
Global ahkDefaultProfile,ahkFEProfile,ahkRomProfile,ahkEmuProfile,ahkSystemProfile,ahkRocketLauncherProfile,ahkLauncherPath,ahkLauncherExe,keymapperFrontEndProfile
Global systemName,dbName,emuName,moduleExtensionsPath,contextOnExit
Log("RunAHKKeymapper - Started")
If (method = "load")
{ Log("RunAHKKeymapper - Loading " . dbName . ", " . emuName . ", " . systemName . ", or _Default AHK Keymapper profile",4)
profile := GetAHKProfile(ahkRomProfile . "|" . ahkEmuProfile . "|" . ahkSystemProfile . "|" . ahkDefaultProfile)
unloadAHK := 1 ; this method we don't want to run any ahk profile if none were found
} Else If (method = "unload" && keymapperFrontEndProfile = "ahk" && !contextOnExit) ; user must have ahk selected to load an ahk FE profile
{ Log("RunAHKKeymapper - Loading Front End AHK Keymapper profile",4)
profile := GetAHKProfile(ahkFEProfile)
unloadAHK := 1 ; this method we don't want to run any ahk profile if none were found
} 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
{ Log("RunAHKKeymapper - Loading RocketLauncher AHK Keymapper profile",4)
profile := GetAHKProfile(ahkRocketLauncherProfile)
} Else If (method = "unload")
{ Log("RunAHKKeymapper - Unloading AhkLauncher",4)
unloadAHK := 1
}
If (unloadAHK || profile) ; if a profile was found or this method should unload the existing AHK profile
{ Log("RunAHKKeymapper - If " . ahkLauncherExe . " is running, need to close it first before a new profile can be loaded",4)
If Process("Exist", ahkLauncherExe) {
Process("Close", ahkLauncherExe) ; close ahkLauncher first
Process("WaitClose", ahkLauncherExe)
}
}
If profile { ; if a profile was found, load it
If FileExist(moduleExtensionsPath . "\autohotkey.dll")
ScriptError("Please delete autohotkey.dll from the folder """ . moduleExtensionsPath . """ as it will cause errors with " . ahkLauncherExe)
Log("RunAHKKeymapper - This profile was found and needs to be loaded: " . profile,4)
Run(ahkLauncherExe . " -notray """ . profile . """", ahkLauncherPath) ; load desired ahk profile
}
Log("RunAHKKeymapper - Ended")
}
; Only use FEProfile if you want to ignore rom and system profile
; ProfilePrefixes separate prefixes with a "|"
GetAHKProfile(ProfilePrefixes) {
Global systemName, dbName, emuName, keymapperProfilePath ;for script error
Log("GetAHKProfile - Started")
Loop, Parse, ProfilePrefixes, |
{ profile := A_LoopField . ".ahk"
Log("GetAHKProfile - Searching for: " . profile,5)
If FileExist(profile)
{ foundProfile := 1
Log("GetAHKProfile - Ended and found: " . profile)
Return profile
}
}
If !foundProfile
Log("GetAHKProfile - Ended and no profile found")
Return
}
;##################################################################
;LoadPreferredControllers(JoyIDsPreferredControllers)
;##################################################################
;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.
;If both an Oem Name and a related custom joy name is found in the list, the oem name position is used
;JoyIDsPreferredControllers this is the list of preferred controllers
;it should be a list of controller names separated with |
;##################################################################
LoadPreferredControllers(JoyIDsPreferredControllers) {
Global CustomJoyNameArray
Log("LoadPreferredControllers - Started")
Log("LoadPreferredControllers - JoyIDsPreferredControllers = " . JoyIDsPreferredControllers,5)
; 16 is max number of joysticks windows and joyids allows
Log("LoadPreferredControllers - Creating a list of currently connected joysticks",5)
JoystickArray := GetJoystickArray()
Loop, 16
{ ControllerName := JoystickArray[A_Index,1]
MID := JoystickArray[A_Index,2]
PID := JoystickArray[A_Index,3]
GUID := JoystickArray[A_Index,4]
If ControllerName
{ ;CustomJoyNameArray is an Associative Array that associates a custom joy name to a controller name. See ahk_l documentation for objects.
CustomJoyName := CustomJoyNameArray[ControllerName]
;prepare for string position searching
JoyIDsPreferredControllersModified := "|" . JoyIDsPreferredControllers . "|"
;store last position this will be used for controllers not in PreferredControllerList
LastPosition := StrLen(JoyIDsPreferredControllersModified)
;position order 1 is for the normal controller name and position order 2 is for the custom name
;normal controller name always takes higher priority over custom names since it is more specific
PositionOrder_1 := InStr(JoyIDsPreferredControllersModified, "|" . ControllerName . "|")
If CustomJoyName
PositionOrder_2 := InStr(JoyIDsPreferredControllersModified, "|" . CustomJoyName . "|")
If PositionOrder_1
PositionOrder := PositionOrder_1
Else If PositionOrder_2
PositionOrder := PositionOrder_2
Else
PositionOrder := LastPosition
;Position Order is the order found in the JoyIDsPreferredControllersModified list
;it will be appended with a decimal value relative to order they were found in.
;create sorting string also add the order found. If controllers are not found in preferred, plug-in order is used.
;example format: 123.01|360 Controller
Log("LoadPreferredControllers - Preferred Order Sorting List -> " . PositionOrder . "." . SubStr("0" . A_Index, -1) . "|" . MID . "|" . PID . "|" . GUID,5)
If !String2Sort
String2Sort := PositionOrder . "." . SubStr("0" . A_Index, -1) . "|" . MID . "|" . PID . "|" . GUID
Else
String2Sort .= "`n" . PositionOrder . "." . SubStr("0" . A_Index, -1) . "|" . MID . "|" . PID . "|" . GUID
}
}
Log("LoadPreferredControllers - Sorting Currently Connected joysticks List to match the order of the Preferred Controller List")
;sort numerically
Sort, String2Sort, N
Log("LoadPreferredControllers - Assigning the New Joystick IDs according to the preferred list for the active controllers")
;parse the string
Loop, Parse, String2Sort, `n
{ StringSplit, JoyIDsSortArray, A_LoopField, |
MID := JoyIDsSortArray2
PID := JoyIDsSortArray3
GUID := JoyIDsSortArray4
ChangeJoystickID(MID,PID,GUID,A_Index)
}
Log("LoadPreferredControllers - Ended")
}
;##################################################################
;RunKeyMapper(keymapperLoad_Or_Unload,keymapper)
;##################################################################
;keymapperLoad_Or_Unload can be = "load" or "unload" or "menu"
; menu is for loading the RocketLauncher menu profile
; keymapper can be = "xpadder", "joytokey" or "joy2key"
; this function returns FEProfile
;##################################################################
RunKeymapper(keymapperLoad_Or_Unload,Keymapper) {
Global blankProfile,defaultProfile,FEProfile,romProfile,emuProfile,xPadderSystemProfile,systemProfile,RocketLauncherProfile
Global systemName,dbName,emuName,keymapperFrontEndProfileName,keymapperFrontEndProfile,contextOnExit
Global CustomJoyNameArray
Global keymapperFullPath
Global KeymapperRocketLauncherProfileEnabled, keymapperEnabled
Static keymapperExists
;Global keymapperLoad_Or_Unload
Log("RunKeymapper - Started, using method """ . keymapperLoad_Or_Unload . """")
If ((KeymapperRocketLauncherProfileEnabled = "false") OR (keymapperEnabled = "false")) AND (keymapperLoad_Or_Unload = "menu")
Return
joystickArray := GetJoystickArray()
If keymapperFullPath {
SplitPath, keymapperFullPath, keymapperExe, keymapperPath, keymapperExt ; splitting pathname into variables
If !keymapperExists {
If !FileExist(keymapperPath . "\" . keymapperExe) {
Log("RunKeymapper - Could not locate your keymapper application here: """ . keymapperFullPath . """",2)
Return
} Else {
Log("RunKeymapper - Found your keymapper application here: """ . keymapperFullPath . """",5)
keymapperExists := 1
}
}
} Else
ScriptError("There was an error with getting your keymapperFullPath, please report this: """ . keymapperFullPath . """")
;define profiles to load and run keymappers
If (keymapper="xpadder")
{ Log("RunKeymapper - Looping through controllers to find xpadder profiles for each one",5)
Loop,16
{ ControllerName := joystickArray[A_Index,1]
If ControllerName
{ Log("RunKeymapper - ID: " . A_Index . " Now searching for a matching profile for this controller: """ . ControllerName . """",5)
If (keymapperLoad_Or_Unload = "load")
Profile2Load := GetProfile(keymapper, romProfile . "|" . emuProfile . "|" . xPadderSystemProfile . "|" . defaultProfile . "|" . blankProfile, keymapperLoad_Or_Unload, ControllerName, Player_Number)
Else If (keymapperLoad_Or_Unload = "unload")
Profile2Load := GetProfile(keymapper, (If keymapperFrontEndProfile = "xpadder" && !contextOnExit ? FEProfile . "|" : "") . blankProfile, keymapperLoad_Or_Unload, ControllerName, Player_Number)
Else If (keymapperLoad_Or_Unload = "menu")
Profile2Load := GetProfile(keymapper, RocketLauncherProfile . "|" . blankProfile, keymapperLoad_Or_Unload, ControllerName, Player_Number)
If !ProfilesInIdOrder
ProfilesInIdOrder := Profile2Load
Else
ProfilesInIdOrder .= "|" . Profile2Load
}
}
RunXpadder(keymapperPath,keymapperExe,ProfilesInIdOrder,joystickArray)
} Else If (keymapper="joy2key") OR (keymapper = "joytokey")
{ Log("RunKeymapper - Looping through controllers to find joytokey profiles for each one",5)
If (keymapperLoad_Or_Unload = "load")
Profile2Load := GetProfile(keymapper, romProfile . "\" . dbName . "|" . emuProfile . "\" . emuName . "|" . systemProfile . "\" . systemName . "|" . defaultProfile . "\_Default", keymapperLoad_Or_Unload)
Else If (keymapperLoad_Or_Unload = "unload" && keymapperFrontEndProfile = "joytokey" && !contextOnExit)
Profile2Load := GetProfile(keymapper, FEProfile . "\" . keymapperFrontEndProfileName, keymapperLoad_Or_Unload)
Else If (keymapperLoad_Or_Unload = "unload" && keymapperFrontEndProfile != "joytokey" && !contextOnExit)
Profile2Load := ; user does not have joytokey set as their FE profile choice, keeping this blank will unload joytokey
Else If (keymapperLoad_Or_Unload = "menu")
Profile2Load := GetProfile(keymapper, RocketLauncherProfile . "\RocketLauncher", keymapperLoad_Or_Unload)
RunJoyToKey(keymapperPath,keymapperExe,Profile2Load)
}
Log("RunKeymapper - Ended")
Return FEProfile
}
;#########################
; GetProfile(ControllerName,keymapper, ProfilePrefixes [,PlayerNumber], keymapperLoad_Or_Unload)
; Only use FEProfile if you want to ignore rom and system profile
; PlayerNumber is there for possible use by other functions including this one
; keymapperLoad_Or_Unload can be load, unload, or menu. for error purposes
; ControllerName must not be empty (no error checks in function)
; keymapper needs to be a valid keymapper (no error checks in function)
; ProfilePrefixes separate prefixes with a "|"
; this function is menat only for use by the Load keymapper function.
;#########################
GetProfile(keymapper, ProfilePrefixes, keymapperLoad_Or_Unload = "load", ControllerName = "", ByRef PlayerNumber = 1) {
Global CustomJoyNameArray, blankProfile, systemName, dbName, emuName, keymapperFrontEndProfileName, keymapperProfilePath
Static ExtensionList := {xpadder: ".xpadderprofile",joy2key: ".cfg",joytokey: ".cfg"} ; static associative array that is holds what extension is for what keymapper.
;keymapper: "keymapper profile extension". Adding name variations to this array should not slow down the script which means name variations can be accounted for.
keymapperExtension := ExtensionList[keymapper]
PlayerNumber := (If PlayerNumber = "" ? (1) : (PlayerNumber)) ; perform check for blank PlayerNumber
If (keymapperExtension = ".xpadderprofile") {
PlayerIndicator := "\p" . PlayerNumber
CustomJoyName := CustomJoyNameArray[ControllerName]
;If CustomJoyName Exists look for it. If not, don't look for an empty [].
If CustomJoyName
{ LoopNumber := 3
PossibleJoyNames1 := "\" . ControllerName
PossibleJoyNames2 := "\" . CustomJoyName
PossibleJoyNames3 := ""
} Else {
LoopNumber := 2
PossibleJoyNames1 := "\" . ControllerName
PossibleJoyNames2 := ""
}
} Else {
PlayerIndicator := "" ;joy2key does not need a player number since the numbers are stored in the cfg
;this is so we don't look for controller specific profiles
LoopNumber := 1
PossibleJoyNames1 := ""
}
;start looking for profiles
;profile prefixes for loading should look like %romProfile%|%emuProfile%|%systemProfile%|%defaultProfile%|%blankProfile%
;profile prefixes for unloading should look like %FEProfile%|%blankProfile%
Profile2Load := ""
Log("GetProfile - Searching for these profiles (| delimited): " . ProfilePrefixes,5)
Loop,Parse,ProfilePrefixes,|
{ ProfileName := A_LoopField
Loop, %LoopNumber%
{ JoyName := PossibleJoyNames%A_Index%
If (ProfileName = blankProfile) ;blankProfile is global variable. This check is here because blank profiles don't need player number.
{ Profile := ProfileName . keymapperExtension
Log("GetProfile - Searching -> " . Profile,5)
If FileExist(Profile)
{ Profile2Load := Profile
Log("GetProfile - Loading Profile -> " . Profile2Load)
PlayerNumber++
Return Profile2Load
}
Break
} Else {
Profile := ProfileName . JoyName . PlayerIndicator . keymapperExtension
Log("GetProfile - Searching for a Player " . PlayerNumber . " profile -> " . Profile,5)
If FileExist(Profile)
{ Profile2Load := Profile
Log("GetProfile - Loading Player " . PlayerNumber . " Profile -> " . Profile2Load)
PlayerNumber++
Return Profile2Load
}
}
}
}
If !Profile2Load
If (keymapperLoad_Or_Unload = "load")
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)
Else If (keymapperLoad_Or_Unload = "unload")
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)
Else If (keymapperLoad_Or_Unload = "menu")
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)
}
;#########################
; GetJoystickArray()
; returns a 4 column by 17 row table.
; the row number is the same as the player number or id #. this is equivalent to port number + 1
; so if your joystick is in port 0 or has an id of 1 it's name will be in JoyStickArray[1,1]
; column 1 contains the oem name, column 2 contains the mid and column 3 contains the pid, column 4 contains the guid
; 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.
; 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.
; row 0 columns 2, 3, and 4 are empty. Future info may be added here.
;#########################
GetJoystickArray() {
Log("GetJoystickArray - Started")
DllCall("winmm\joyConfigChanged", UInt, 0)
Loop,16
{
port := A_Index - 1
VarSetCapacity(joyState,512)
NumPut(64,joyState,0,"UInt")
joyError := DllCall("winmm\joyGetPosEx", "ptr", port, "ptr", &joyState)
If joyError = 0
joysDetected .= 1
Else
joysDetected .= 0
}
Log("GetJoystickArray - Joysticks Detected: " . joysDetected,5)
joyArray := Object()
Loop, 5
joyArray[0,A_Index] := ""
Loop, Parse, joysDetected
{ CurrentController := A_Index
currentJoyGUID := ""
Mid := "", Pid := "", joyName := "" ; Erase values
If (A_LoopField = 1)
{ If joyArray[0,1]
joyArray[0,1] := joyArray[0,1] . "|" . CurrentController
Else
joyArray[0,1] := CurrentController
VarSetCapacity(joybank,1024,0)
i := 0
port := CurrentController - 1
Loop, 1024
{ ; Get driver information
err := dllcall("winmm.dll\joyGetDevCapsA",Int,port,UInt,&joybank,UInt,i)
i++
; A successful dllcall returns a 0
If (err = 0)
{ ; Converting decimal values to hex since windows uses the hex value more often
offset := 0
Loop, 2
{ SetFormat, IntegerFast, hex
ret := NumGet(&joybank,offset,"UShort")
ret .= ""
SetFormat, IntegerFast, d
; Remove the 0x we don't need it and padding it with 0's to have a width of four
; Advice: leave these two lines out if using this function in other scripts
StringTrimLeft,ret,ret,2
ID%A_Index% := SubStr("0000" . ret,-3)
offset := offset+2
}
Mid := ID1, Pid := ID2
}
}
If !Mid && !Pid
joyName := ""
Else {
regFolder := "VID_" . Mid . "&PID_" . Pid
joyName := RegRead("HKEY_CURRENT_USER", "System\CurrentControlSet\Control\MediaProperties\PrivateProperties\Joystick\OEM\" . regFolder, "OEMName")
If ErrorLevel
joyName := RegRead("HKEY_LOCAL_MACHINE", "SYSTEM\CurrentControlSet\Control\MediaProperties\PrivateProperties\Joystick\OEM\" . regFolder, "OEMName")
}
currentJoyGUID := GetJoystickGUID(Mid,Pid,CurrentController)
Log("GetJoystickArray - ID: " . CurrentController . " | Port: " . port . " | Name: " . joyName . " | MID: " . mid . " | PID: " . pid . " | GUID: " . currentJoyGUID,5)
}
joyName := Trim(joyName) ; Xpadder trims leading and trailing whitespace so we will do the same
; Append empty string to avoid ahk's auto converting string type containing integers to integer type because we want the leading zeros
joyArray[CurrentController,1] := joyName . ""
joyArray[CurrentController,2] := Mid . ""
joyArray[CurrentController,3] := Pid . ""
joyArray[CurrentController,4] := currentJoyGUID . ""
joyArray[CurrentController,5] := ""
}
Log("GetJoystickArray - Ended")
Return joyArray
}
;#########################
; GetJoystickGUID(Mid,Pid,JoystickID)
; This function is used internally by the GetJoystickArray() function
; It returns the matching guid for a joystick device. Empty if error occurred.
; Mid = JoystickArray[JoystickID,2]
; PID = JoystickArray[JoystickID,3]
; JoystickID = 1 through 16
;#########################
GetJoystickGUID(Mid,Pid,JoystickID) {
If !Mid OR !PID OR !JoystickID
Return
If JoystickID not between 1 and 16
Return
Log("GetJoystickGUID - Started")
SetFormat, IntegerFast, hex
REG_JOY_ID := JoystickID - 1
REG_JOY_ID .= "000000"
StringReplace, REG_JOY_ID , REG_JOY_ID, x
SetFormat, IntegerFast, d
If A_OSVersion in WIN_2003,WIN_XP,WIN_2000,WIN_NT4,WIN_95,WIN_98,WIN_ME
RootKey := "HKEY_LOCAL_MACHINE"
Else
RootKey := "HKEY_CURRENT_USER"
Loop, %RootKey%, System\CurrentControlSet\Control\MediaProperties\PrivateProperties\DirectInput\VID_%Mid%&PID_%Pid%\Calibration,1,1
{
If (A_LoopRegName = "Joystick Id") {
RegRead, regvar
If (regvar = REG_JOY_ID) {
RegSubKey := A_LoopRegSubKey
Break
}
}
}
GUID := RegRead(RootKey, RegSubKey, "GUID")
Log("GetJoystickGUID - Ended and found GUID: " . GUID)
Return GUID
}
;#########################
; ChangeJoystickID(Mid,Pid,GUID,NewJoystickID)
; This is an awesome little function that changes the joystick id.
; It gives us more control over what devices are moved than JoyIDs.exe ever did.
; It returns 0 if successful, 1 if unsuccessful.
; Mid = JoystickArray[JoystickID,2]
; PID = JoystickArray[JoystickID,3]
; GUID = JoystickArray[JoystickID,4]
; NewJoystickID = 1 through 16, this is the new ID for the joystick with the matching MID,PID,GUID
; it has no way of checking to make sure it's not assigning the same id as an already active controller,
; so this check must be done outside the function.
;#########################
ChangeJoystickID(Mid,Pid,GUID,NewJoystickID) {
Log("ChangeJoystickID - Started")
If !Mid OR !Pid OR !GUID OR !NewJoystickID
Return 1
If NewJoystickID not between 1 and 16
Return 1
SetFormat, IntegerFast, hex
NewJoystickID := NewJoystickID - 1
NewJoystickID .= "000000"
StringReplace, NewJoystickID , NewJoystickID, x
SetFormat, IntegerFast, d
If A_OSVersion in WIN_2003,WIN_XP,WIN_2000,WIN_NT4,WIN_95,WIN_98,WIN_ME
RootKey := "HKEY_LOCAL_MACHINE"
Else
RootKey := "HKEY_CURRENT_USER"
Loop, %RootKey%, System\CurrentControlSet\Control\MediaProperties\PrivateProperties\DirectInput\VID_%Mid%&PID_%Pid%\Calibration,1,1
{
If (A_LoopRegName = "GUID") {
RegRead, regvar
If (regvar = GUID) {
RegSubKey := A_LoopRegSubKey
break
}
}
}
jid := RegRead(RootKey, RegSubKey, "Joystick Id")
RegWrite("REG_BINARY", RootKey, RegSubKey, "Joystick Id", NewJoystickID)
Log("ChangeJoystickID - Swapping Joystick ID: " . jid . " to the New Joystick ID: " . NewJoystickID . ", for the Joystick VID_" . Mid . "&PID_" . Pid . "&GUID_" . GUID,5)
Log("ChangeJoystickID - Ended")
Return ErrorLevel
}
RunXpadder(keymapperPath,keymapperExe,ProfilesInIdOrder,joystickArray) {
Global joyToKeyFullPath
Log("RunXpadder - Started")
; Closing joytokey to avoid dual keymapper conflict.
SplitPath, joyToKeyFullPath, joyToKeyExe, joyToKeyPath
errLvl := Process("Exist", joyToKeyExe)
If errLvl
Process("Close", joyToKeyExe)
; Close xpadder to refresh controllers
Log("RunXpadder - Closing xpadder to refresh controllers seen by xpadder",5)
Run(keymapperExe . " /C", keymapperPath,,,,1) ; enabling bypassCmdWindow
StringSplit,Profiles,ProfilesInIdOrder,|
Log("RunXpadder - Creating an array of connected controllers and profiles to arrange according to the order found in " . keymapperPath . "\xpadder.ini",5)
XpadderArray := []
ProfileCount := 0
Loop,16
{ ControllerName := joystickArray[A_Index,1]
MID := joystickArray[A_Index,2]
PID := joystickArray[A_Index,3]
; Check to see if controller name has been previously been found
String := XpadderArray[ControllerName]
StringSplit,SplitArray,String,|
If SplitArray0
{ ProfileCount++
Profile2Load := Profiles%ProfileCount%
; Store ID numbers that are compatible xpadder in SplitArray1
; Append the newly found profile2load with the previously found profiles associated with this controller separated with a ? to be later replaced with " "
XpadderArray[ControllerName] := SplitArray1 . "|" . SplitArray2 . "?" . Profile2Load
} Else If ControllerName
{ ProfileCount++
Profile2Load := Profiles%ProfileCount%
; Convert hexadecimal Mid and Pid values into a format compatible with xpadder's xpadder.ini
ID1:=SubStr(Mid,1,2),ID2:=SubStr(Mid,3,2),ID3:=SubStr(Pid,1,2),ID4:=SubStr(Pid,3,2)
Loop,4
{ ID%A_Index% := "0x" . ID%A_Index%
ID%A_Index% += 0
}
ControllerID := ID1 . "`," . ID2 . "`," . ID3 . "`," . ID4
Value := ControllerID . "|" . Profile2Load
XpadderArray.Insert(ControllerName,Value)
}
}
errLvl := Process("WaitClose", keymapperExe, 2) ;wait for xpadder to finish writing its values to xpadder.ini before reading and editing it
If errLvl
Process("Close", keymapperExe)
Log("RunXpadder - Reading the order in " . keymapperPath . "\xpadder.ini and arranging profiles found to match that order",5)
Loop {
; Get profiles in order as appears in xpadder.ini
LoopIndex := A_Index ;record number in case we need to add a new key to xpadder.
IniControllerName := IniRead(keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "Name")
If (IniControllerName = "ERROR") { ;this means there are no more controllers to be found in the ini
Log("RunXpadder - No more controllers to be found",5)
Break
}
; Look to see if the controller found in the ini is already in our array
XpadderArrayValue := XpadderArray[IniControllerName]
If XpadderArrayValue
{ StringSplit,SplitArray,XpadderArrayValue,|
; Make sure controller is not hidden. if it is one xpadder does not recognize controller and the profile loading is messed up.
IniWrite(0, keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "Hidden")
; This is for later use
If !IniControllersFound
IniControllersFound := IniControllerName
Else
IniControllersFound .= "," . IniControllerName
; Start creating the string of profiles to send to xpadder
If !ProfilesInXpadderOrder
ProfilesInXpadderOrder := SplitArray2
Else
ProfilesInXpadderOrder .= """ """ . SplitArray2
; 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
}
}
For key, XpadderArrayValue in XpadderArray
{
If !RegExMatch(key,"i)" . IniControllersFound)
{ Log("RunXpadder - Could not find " . key . " in xpadder.ini. Writing the new controller to xpadder.ini",5)
StringSplit,SplitArray,XpadderArrayValue,|
; Write new key values for the controllers not found in xpadder.ini to xpadder so it sees them when it restarts.
IniWrite(key, keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "Name")
IniWrite(SplitArray1, keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "ID")
IniWrite(0, keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "Hidden")
; Look for matching xpaddercontroller file in xpadder.exe root directory
CustomJoyName := CustomJoyNameArray[key]
; Profiles can be named after CustomJoyName or controller name. Oem Name takes priority.
If (FileExist(keymapperPath . key . ".xpaddercontroller")) {
Log("RunXpadder - Loading " . keymapperPath . "\" . key ".xpaddercontroller layout for the new controller",5)
IniWrite(key . ".xpaddercontroller", keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "File")
} Else If (CustomJoyName AND FileExist(keymapperPath . CustomJoyName . ".xpaddercontroller")) {
Log("RunXpadder - Loading " . keymapperPath . "\" . CustomJoyName ".xpaddercontroller layout for the new controller",5)
IniWrite(CustomJoyName . ".xpaddercontroller", keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "File")
} Else {
; This means a xpaddercontroller profile has not been found
ScriptError("Please create a xpaddercontroller profile named either " . key . " or " . CustomJoyName . ". It also needs to be in the same folder as xpadder.exe")
}
Loop, 4
IniWrite(A_Space, keymapperPath . "\Xpadder.ini", "Controllers", "Controller" . LoopIndex . "Recent" . A_Index)
LoopIndex++
If !ProfilesInXpadderOrder
ProfilesInXpadderOrder := SplitArray2
Else
ProfilesInXpadderOrder .= """ """ . SplitArray2
}
}
StringReplace, ProfilesInXpadderOrder, ProfilesInXpadderOrder, ?, " ", All
If ProfilesInXpadderOrder
Run(keymapperExe . " """ . ProfilesInXpadderOrder . """ /M", keymapperPath, "Hide",,,1) ; enabling bypassCmdWindow)
Else
Log("RunXpadder - No profiles found and nothing to tell Xpadder to load",2)
Log("RunXpadder - Ended")
}
RunJoyToKey(keymapperPath,keymapperExe,Profile="") {
Global xpadderFullPath
Log("RunJoyToKey - Started")
; Closing xpadder to avoid dual keymapper conflict.
If FileExist(xpadderFullPath) {
SplitPath, xpadderFullPath, xpadderexe, xpadderdir
errLvl := Process("Exist", xpadderexe)
If errLvl
{ Log("RunJoyToKey - Closing xpadder to avoid dual keymapper conflict",2)
Run(xpadderexe . " /C", xpadderdir,,,,1) ; enabling bypassCmdWindow)
errLvl := Process("Exist", xpadderexe)
If errLvl
Process("Close", xpadderexe)
}
}
exitMeansMinimize := IniRead(keymapperPath . "\JoyToKey.ini", "LastStatus", "ExitMeansMinimize")
If (exitMeansMinimize = "ERROR")
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)
Else If ( exitMeansMinimize = 1 ) {
Process("Close", keymapperExe)
Process("WaitClose", keymapperExe)
IniWrite(0, keymapperPath . "\JoyToKey.ini", "LastStatus", "ExitMeansMinimize")
}
DetectHiddenWindows, On
WinClose("JoyToKey ahk_class TMainForm")
errLvl := Process("WaitClose", keymapperExe, 2)
If errLvl
Process("Close", keymapperExe)
; RocketLauncherUI may turn off joytokey from starting minimized, let's set it just in case
startMinimized := IniRead(keymapperPath . "\JoyToKey.ini", "LastStatus", "StartIconified")
If startMinimized != 1
IniWrite(1, keymapperPath . "\JoyToKey.ini", "LastStatus", "StartIconified")
; Finally we start the keymapper with the cfg profile we found
If Profile
Run(keymapperExe . " """ . Profile . """", keymapperPath,,,,1) ; enabling bypassCmdWindow)
Log("RunJoyToKey - Ended")
}
Keymapper_PauseProfileList(ControllerName,PlayerNumber,keymapper) {
; [file name (no extension), type (options are default,system,emulator,game),0 or 1 (1 if controller specific), full path to file]
Global blankProfile,defaultProfile,romProfile,emuProfile,xPadderSystemProfile,systemProfile
Global systemName,dbName,emuName ;for use with joytokey
Global CustomJoyNameArray ;for use with xpadder
Log("Keymapper_PauseProfileList - Started")
If (keymapper = "xpadder")
{ keymapperExtension = .xpadderprofile
sProfile := xPadderSystemProfile
PlayerIndicator := "\p" . PlayerNumber
CustomJoyName := CustomJoyNameArray[ControllerName]
If CustomJoyName
{ LoopNumber := 3
PossibleJoyNames1 := "\" . ControllerName
PossibleJoyNames2 := "\" . CustomJoyName
PossibleJoyNames3 := ""
} Else {
LoopNumber := 2
PossibleJoyNames1 := "\" . ControllerName
PossibleJoyNames2 := ""
}
} Else { ; keymapper = joy2key
keymapperExtension := ".cfg"
sProfile := systemProfile
LoopNumber := 1
PossibleJoyNames1 := "" ;joy2key does not use a profile per controller
PlayerIndicator := "" ;joy2key and ahk do not need a player number
}
; used for finding the normally loaded profile
normalProfileFound := 0
; loop counters
i := 1
j := 0
ProfileList := []
ProfileFolderArray := ["Game","Emulator","System","Default"]
If (keymapper = "xpadder")
String2Parse := romProfile . "|" . emuProfile . "|" . sProfile . "|" . defaultProfile
Else { ;joytokey
String2Parse := romProfile . "|" . emuProfile . "|" . sProfile . "|" . defaultProfile
normProfileName := [dbName,emuName,systemName,"_Default"]
}
Log(String2Parse)
Loop,Parse,String2Parse,|
{ j++
FolderPath := A_LoopField
;If CustomJoyName Exists look for it. If not, don't look for a \\ directory
Loop % LoopNumber
{
joyName := PossibleJoyNames%A_Index%
If joyName
Controller_Specific_Boolean := 1
Else
Controller_Specific_Boolean := 0
If (keymapper = "xpadder") {
normProfile := FolderPath . joyName . PlayerIndicator . keymapperExtension
FilePattern := FolderPath . joyName . "\*" . keymapperExtension
} Else { ; keymapper = joy2key
normProfile := FolderPath . "\" . normProfileName[j] . keymapperExtension
FilePattern := FolderPath . "\*" . keymapperExtension
}
Loop % FilePattern
{
SplitPath,A_LoopFileFullPath,,,,FileNameNoExt
If (keymapper = "joytokey") OR (keymapper = "joy2key") {
; I find this information to be more useful because it determines if a profile will actually work if you use joytokey.
; the boolean value means profile will work, but due to joy2key limitations we don't know if the profile was made for this controller
SectionName := "Joystick " . PlayerNumber
CheckForSection := IniRead(A_LoopFileFullPath, "SectionName", "Axis1p") ; this key will always exist if the section exists and was properly created by joytokey
If CheckForSection
Controller_Specific_Boolean := 1
Else
Controller_Specific_Boolean := 0
}
If (normProfile = A_LoopFileFullPath) && !normalProfileFound
{ normalProfileFound := 1
Log("Keymapper_PauseProfileList - Creating Profile List (normal load profile) -> 1`," . FileNameNoExt . "`," . ProfileFolderArray[j] . "`," . Controller_Specific_Boolean . "`," . A_LoopFileFullPath,5)
ProfileList[1,1] := FileNameNoExt
ProfileList[1,2] := ProfileFolderArray[j]
ProfileList[1,3] := Controller_Specific_Boolean
ProfileList[1,4] := A_LoopFileFullPath
} Else If A_LoopFileFullPath
{ i++
Log("Keymapper_PauseProfileList - Creating Profile List -> " . i . "`," . FileNameNoExt . "`," . ProfileFolderArray[j] . "`," . Controller_Specific_Boolean . "`," . A_LoopFileFullPath,5)
ProfileList[0,1] := i
ProfileList[i,1] := FileNameNoExt
ProfileList[i,2] := ProfileFolderArray[j]
ProfileList[i,3] := Controller_Specific_Boolean
ProfileList[i,4] := A_LoopFileFullPath
}
}
}
}
Log("Keymapper_PauseProfileList - Ended")
Return ProfileList
}
Comments