Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- MCRC=93430C5C
- MVersion=1.4.0
- StartModule(){
- Global gameSectionStartTime,gameSectionStartHour,skipChecks,dbName,romPath,romPathOrig,romName,romExtension,systemName,MEmu,MEmuV,MURL,MAuthor,MVersion,MCRC,iCRC,MSystem,romMapTable,romMappingLaunchMenuEnabled,romMenuRomName,sevenZEnabled,hideCursor,toggleCursorKey,servoStikEnabled,ledblinkyEnabled,winVer,setResolution,zz
- Global mgEnabled,mgOnLaunch,mgCandidate,mgLaunchMenuActive,MultiGame_Running,keyboardEncoder,keyboardEncoderEnabled,ultraMapFullPath,winIPACFullPath
- Global rIniIndex,globalPluginsFile,sysPluginsFile
- Log("StartModule - Started")
- Log("StartModule - MEmu: " . MEmu . "`r`n`t`t`t`t`tMEmuV: " . MEmuV . "`r`n`t`t`t`t`tMURL: " . MURL . "`r`n`t`t`t`t`tMAuthor: " . MAuthor . "`r`n`t`t`t`t`tMVersion: " . MVersion . "`r`n`t`t`t`t`tMCRC: " . MCRC . "`r`n`t`t`t`t`tiCRC: " . iCRC . "`r`n`t`t`t`t`tMID: " . MID . "`r`n`t`t`t`t`tMSystem: " . MSystem)
- If InStr(MSystem,systemName)
- Log("StartModule - You have a supported System Name for this module: """ . systemName . """")
- Else
- Log("StartModule - You have an unsupported System Name for this module: """ . systemName . """. Only the following System Names are suppported: """ . MSystem . """",2)
- winVer := If A_Is64bitOS ? "64" : "32" ; get windows version
- ;-----------------------------------------------------------------------------------------------------------------------------------------
- ; Plugin Specific Settings from Settings \ Global Plugins.ini and Settings \ %systemName% \ Plugins.ini
- ;-----------------------------------------------------------------------------------------------------------------------------------------
- rIniIndex := {} ; initialize the RIni array
- globalPluginsFile := A_ScriptDir . "\Settings\Global Plugins.ini"
- If !FileExist(globalPluginsFile)
- FileAppend,, %globalPluginsFile% ; create blank ini
- RIni_Read(8,globalPluginsFile)
- rIniIndex[8] := globalPluginsFile ; assign to array
- sysPluginsFile := A_ScriptDir . "\Settings\" . systemName . "\Plugins.ini"
- If !FileExist(sysPluginsFile)
- FileAppend,, %sysPluginsFile% ; create blank ini
- RIni_Read(9,sysPluginsFile)
- rIniIndex[9] := sysPluginsFile ; assign to array
- Gosub, PluginInit ; initialize plugin vars
- ; Gosub, ReadFEGameInfo ; read plugin data
- ;-----------------------------------------------------------------------------------------------------------------------------------------
- If (mgEnabled = "true" && mgOnLaunch = "true" && mgCandidate) { ; only if user has mgOnLaunch enabled
- mgLaunchMenuActive := true
- Log("StartModule - MultiGame_On_Launch execution started.",4)
- Gosub, StartMulti
- Sleep, 200
- Loop {
- If !MultiGame_Running
- Break
- }
- mgLaunchMenuActive := false
- Log("StartModule - MultiGame_On_Launch execution ended.",4)
- }
- If (romMappingLaunchMenuEnabled = "true" && romMapTable.MaxIndex()) ; && romMapMultiRomsFound)
- CreateRomMappingLaunchMenu%zz%(romMapTable)
- ; msgbox dbName: %dbName%`nromName: %romName%`nromMenuRomName: %romMenuRomName%`nsevenZEnabled: %sevenZEnabled%`nskipChecks: %skipChecks%
- If (skipChecks != "false" && romMenuRomName && sevenZEnabled = "false") ; this is to support the scenario where Rom Map Launch Menu can send a rom that does not exist on disk or in the archive (mame clones)
- { Log("StartModule - Setting romName to the game picked from the Launch Menu: " . romMenuRomName,4)
- romName := romMenuRomName
- } Else If romName && romMapTable.MaxIndex()
- { Log("StartModule - Leaving romName as is because Rom Mapping filled it with an Alternate_Rom_Name: " . romName,4)
- romName := romName ; When Rom Mapping is used but no Alternate_Archive_Name key exists yet Alternate_Rom_Name key(s) were used.
- } Else If romMapTable.MaxIndex()
- { Log("StartModule - Not setting romName because Launch Menu was used and 7z will take care of it.",4)
- romName := "" ; If a romMapTable exists with roms, do not fill romName yet as 7z will take care of that.
- } Else
- { Log("StartModule - Setting romName to the dbName sent to RocketLauncher: " . dbName,4)
- romName := dbName ; Use dbName if previous checks are false
- }
- romPathOrig := romPath ; storing original rom path for any modules or features that need this before 7z updates it.
- If (setResolution != "")
- SetDisplaySettings(setResolution)
- If RegExMatch(hideCursor,"i)true|do_not_restore")
- SystemCursor("Off")
- Else If RegExMatch(hideCursor,"i)custom|custom_do_not_restore") {
- cursor := GetRLMediaFiles("Cursors","cur|ani") ;load cursor file for the system if they exist
- If cursor
- SetSystemCursor(Cursor) ; replace system cursors
- }
- If toggleCursorKey
- XHotKeywrapper(toggleCursorKey,"ToggleCursor")
- If (ledblinkyEnabled = "All")
- LEDBlinky("START")
- KeymapperProfileSelect("START", keyboardEncoder, %keyboardEncoder%FullPath, "ipc", "keyboard")
- KeymapperProfileSelect("START", "UltraMap", ultraMapFullPath, "ugc")
- If (servoStikEnabled = 4 || servoStikEnabled = 8)
- ServoStik(servoStikEnabled) ; handle servostiks on start
- ; romName := If romName ? romName : If romMapTable.MaxIndex() ? "" : dbName ; OLD METHOD, keeping this here until the split apart conditionals have been tested enough. ; if romName was filled at some point, use it, Else If a romMapTable exists with roms, do not fill romName yet as 7z will take care of that. Use dbName if previous checks are false
- Gui, show,Hide,RocketLauncherMessageReceiver ; creating hidden GUI to receive RocketLauncher messages
- OnMessage(0x4a, "ReceiveMessage")
- BroadcastMessage("RocketLauncher Message: Welcome! :)")
- gameSectionStartTime := A_TickCount
- gameSectionStartHour := A_Now
- ; msgbox % "romPath: " . romPath . "`nromName: " . romName . "`nromExtension: " . romExtension . "`nromMenuRomName: " . romMenuRomName . "`nromMapTable.MaxIndex(): " . romMapTable.MaxIndex()
- Log("StartModule - Ended")
- }
- ; ExitModule function in case we need to call anything on the module's exit routine, like UpdateStatistics for Pause or UnloadKeymapper
- ExitModule(){
- Global statisticsEnabled,keymapperEnabled,keymapper,keymapperAHKMethod,keymapperLoaded,logShowCommandWindow,pToken,cmdWindowObj,mouseCursorHidden,cursor,hideCursor,rocketLauncherIsExiting,servoStikExitMode,ledblinkyEnabled,zz
- Global JoyIDsEnabled,JoyIDsPreferredControllersOnExit,keyboardEncoder,keyboardEncoderEnabled,ultraMapFullPath,winIPACFullPath
- Log("ExitModule - Started")
- rocketLauncherIsExiting := 1 ; notifies rest of the thread that the exit routine was triggered
- If (statisticsEnabled = "true")
- Gosub, UpdateStatistics
- If (keymapperEnabled = "true" && keymapperLoaded)
- RunKeyMapper%zz%("unload",keymapper)
- If keymapperAHKMethod = External
- RunAHKKeymapper%zz%("unload")
- If (JoyIDsEnabled = "true" && JoyIDsPreferredControllersOnExit)
- LoadPreferredControllers%zz%(JoyIDsPreferredControllersOnExit)
- If (hideCursor = "custom" and cursor)
- RestoreCursors() ; retore default system cursors
- If mouseCursorHidden ; just in case
- SystemCursor("On")
- If (ledblinkyEnabled = "All")
- LEDBlinky("END")
- KeymapperProfileSelect("END", keyboardEncoder, %keyboardEncoder%FullPath, "ipc", "keyboard")
- KeymapperProfileSelect("END", "UltraMap", ultraMapFullPath, "ugc")
- If (servoStikExitMode = 4 || servoStikExitMode = 8)
- ServoStik(servoStikExitMode) ; handle servostiks on exit
- If logShowCommandWindow = true
- Loop {
- If !cmdWindowObj[A_Index,"Name"]
- Break
- Else {
- Log("ExitModule - Closing command window: " . cmdWindowObj[A_Index,"Name"] . " PID: " . cmdWindowObj[A_Index,"PID"],4)
- Process("Close", cmdWindowObj[A_Index,"Name"]) ; close each opened cmd.exe
- }
- }
- BroadcastMessage("RocketLauncher Message: Goodbye! :(")
- Gdip_Shutdown(pToken) ; gdi+ may now be shutdown on exiting the thread
- Log("ExitModule - Ended")
- Log("End of Module Logs",,,1)
- ExitApp
- }
- WinWait(winTitle,winText="",secondsToWait=30,excludeTitle="",excludeText=""){
- Global detectFadeErrorEnabled, logLevel
- If logLevel > 3
- GetActiveWindowStatus()
- Log("WinWait - Waiting for """ . winTitle . """")
- WinWait, %winTitle% ,%winText% , %secondsToWait% , %excludeTitle% ,%excludeText%
- curErr := ErrorLevel ; have to store this because GetActiveWindowStatus will reset it
- If logLevel > 3
- GetActiveWindowStatus()
- If (curErr and detectFadeErrorEnabled = "true")
- ScriptError("There was an error waiting for the window """ . winTitle . """. Please check you have the correct version emulator installed for this module, followed any notes in the module, and have this emulator working outside your Frontend first. Also turn off Fade to see if you are hiding your problem.",10)
- Else If (curErr and detectFadeErrorEnabled != "true")
- Log("There was an error waiting for the window """ . winTitle . """. Please check you have the correct version emulator installed for this module, followed any notes in the module, and have this emulator working outside your Frontend first. Also turn off Fade to see if you are hiding your problem.",3)
- Return curErr
- }
- WinWaitActive(winTitle,winText="",secondsToWait=30,excludeTitle="",excludeText=""){
- Global detectFadeErrorEnabled, logLevel, emulatorProcessID, emulatorVolumeObject, emulatorInitialMuteState, fadeMuteEmulator, fadeIn
- If (logLevel > 3)
- GetActiveWindowStatus()
- Log("WinWaitActive - Waiting for """ . winTitle . """")
- WinWaitActive, %winTitle% ,%winText% , %secondsToWait% , %excludeTitle% ,%excludeText%
- curErr := ErrorLevel ; have to store this because GetActiveWindowStatus will reset it
- If (logLevel > 3)
- GetActiveWindowStatus()
- If (curErr and detectFadeErrorEnabled = "true")
- ScriptError("There was an error waiting for the window """ . winTitle . """ to become active. Please check you have the correct version emulator installed for this module, followed any notes in the module, and have this emulator working outside your Frontend first. Also turn off Fade to see if you are hiding your problem.",10)
- Else If (curErr and detectFadeErrorEnabled != "true")
- Log("There was an error waiting for the window """ . winTitle . """ to become active. Please check you have the correct version emulator installed for this module, followed any notes in the module, and have this emulator working outside your Frontend first. Also turn off Fade to see if you are hiding your problem.",3)
- If !curErr
- {
- WinGet emulatorProcessID, PID, %winTitle%
- emulatorVolumeObject := GetVolumeObject(emulatorProcessID)
- If ((fadeMuteEmulator = "true") and (fadeIn = "true")){
- getMute(emulatorInitialMuteState, emulatorVolumeObject)
- setMute(1, emulatorVolumeObject)
- }
- }
- Return curErr
- }
- WinWaitClose(winTitle,winText="",secondsToWait="",excludeTitle="",excludeText=""){
- Log("WinWaitClose - Waiting for """ . winTitle . """ to close")
- WinWaitClose, %winTitle% ,%winText% , %secondsToWait% , %excludeTitle% ,%excludeText%
- Return ErrorLevel
- }
- WinClose(winTitle,winText="",secondsToWait="",excludeTitle="",excludeText=""){
- Log("WinClose - Closing: " . winTitle)
- WinClose, %winTitle%, %winText% , %secondsToWait%, %excludeTitle%, %excludeText%
- If (secondsToWait = "" || !secondsToWait)
- secondsToWait := 2 ; need to always have some timeout for this command otherwise it will wait forever
- WinWaitClose, %winTitle%, %winText% , %secondsToWait%, %excludeTitle%, %excludeText% ; only WinWaitClose reports an ErrorLevel
- Return ErrorLevel
- }
- WinActivate(WinTitle,WinText="",ExcludeTitle="",ExcludeText="")
- {
- Log("WinActivate - Selecting " . Menu . " -> " . SubMenu1 . (SubMenu2 ? " -> " . SubMenu2 : "") . (SubMenu3 ? " -> " . SubMenu3 : "") . (SubMenu4 ? " -> " . SubMenu4 : "") . (SubMenu5 ? " -> " . SubMenu5 : "") . (SubMenu6 ? " -> " . SubMenu6 : ""),4)
- WinActivate,%WinTitle%,%WinText%,%Menu%,%SubMenu1%,%SubMenu2%,%SubMenu3%,%SubMenu4%,%SubMenu5%,%SubMenu6%,%ExcludeTitle%,%ExcludeText%
- Return ErrorLevel
- }
- WinGet(cmd,WinTitle,WinText="",ExcludeTitle="",ExcludeText="",log=1)
- {
- WinGet,OutputVar,%cmd%,%WinTitle%,%WinText%,%ExcludeTitle%,%ExcludeText%
- If log
- Log("WinGet - Retrieved """ . OutputVar . """ from " . WinTitle . A_Space . WinText,4)
- Return OutputVar
- }
- WinGetTitle(WinTitle,WinText="",ExcludeTitle="",ExcludeText="",log=1)
- {
- WinGetTitle,OutputVar,%WinTitle%,%WinText%,%ExcludeTitle%,%ExcludeText%
- If log
- Log("WinGetTitle - Retrieved """ . OutputVar . """ from " . WinTitle . A_Space . WinText,4)
- Return OutputVar
- }
- WinGetPos(ByRef x,ByRef y,ByRef w,ByRef h,WinTitle,WinText="",ExcludeTitle="",ExcludeText="",log=1)
- {
- WinGetPos,x,y,w,h,%WinTitle%,%WinText%,%ExcludeTitle%,%ExcludeText%
- If log
- Log("WinGetPos - Retrieved x:" . x . " y:" . y . " w: " . w . " h: " . h . " from " . WinTitle . A_Space . WinText,4)
- Return
- }
- WinHide(WinTitle,WinText="",ExcludeTitle="",ExcludeText="")
- {
- Log("WinHide - Hiding window " . WinTitle . A_Space . WinText,4)
- WinHide,%WinTitle%,%WinText%,%ExcludeTitle%,%ExcludeText%
- Return ErrorLevel
- }
- WinMenuSelectItem(WinTitle,WinText="",Menu="",SubMenu1="",SubMenu2="",SubMenu3="",SubMenu4="",SubMenu5="",SubMenu6="",ExcludeTitle="",ExcludeText="")
- {
- If (!Menu || !SubMenu1)
- ScriptError("Menu and SubMenu are required for RL.WinMenuSelectItem")
- Log("WinMenuSelectItem - Selecting " . Menu . " -> " . SubMenu1 . (SubMenu2 ? " -> " . SubMenu2 : "") . (SubMenu3 ? " -> " . SubMenu3 : "") . (SubMenu4 ? " -> " . SubMenu4 : "") . (SubMenu5 ? " -> " . SubMenu5 : "") . (SubMenu6 ? " -> " . SubMenu6 : ""),4)
- WinMenuSelectItem,%WinTitle%,%WinText%,%Menu%,%SubMenu1%,%SubMenu2%,%SubMenu3%,%SubMenu4%,%SubMenu5%,%SubMenu6%,%ExcludeTitle%,%ExcludeText%
- Return ErrorLevel
- }
- WinMove(x,y,w="",h="",WinTitle="",WinText="",ExcludeTitle="",ExcludeText="",log=1)
- {
- If WinTitle
- WinMove,%WinTitle%,%WinText%,%x%,%y%,%w%,%h%,%ExcludeTitle%,%ExcludeText%
- Else
- WinMove,%x%,%y%
- If log
- Log("WinMove - Moved " . WinTitle . A_Space . WinText . " to x:" . x . " y:" . y . " w: " . w . " h: " . h,4)
- Return
- }
- WinRestore(WinTitle,WinText="",ExcludeTitle="",ExcludeText="")
- {
- Log("WinRestore - Restoring window " . WinTitle . A_Space . WinText,4)
- WinRestore,%WinTitle%,%WinText%,%ExcludeTitle%,%ExcludeText%
- Return ErrorLevel
- }
- WinSet(Attribute,Value,WinTitle,WinText="",ExcludeTitle="",ExcludeText="")
- {
- Log("WinSet - Setting " . Attribute . " to " . Value . " on window " . WinTitle . A_Space . WinText,4)
- WinSet,%Attribute%,%Value%,%WinTitle%,%WinText%,%ExcludeTitle%,%ExcludeText%
- Return ErrorLevel
- }
- WinShow(WinTitle,WinText="",ExcludeTitle="",ExcludeText="")
- {
- Log("WinShow - Unhiding window " . WinTitle . A_Space . WinText,4)
- WinShow,%WinTitle%,%WinText%,%ExcludeTitle%,%ExcludeText%
- Return ErrorLevel
- }
- RunWait(target,workingDir="",options=0,ByRef outputVarPID=""){
- Global errorLevelReporting
- options := If options = 1 ? "useErrorLevel" : options ; enable or disable error level
- Log("RunWait - Started - running: " . workingDir . "\" . target)
- RunWait, %target%, %workingDir%, %options%, outputVarPID
- curErr := ErrorLevel ; store error level immediately
- Log("RunWait - """ . target . """ Process ID: " . outputVarPID . " and ErrorLevel reported as: " . curErr, 4)
- Return curErr
- }
- ; To disable inputBlocker on a specific Run call, set inputBlocker to 0, or to force it a specified amount of seconds (upto 30), set it to that amount.
- ; By default, options will enable all calls of Run() to return errorlevel within the function. However, it will only be returned if errorLevelReporting is true
- ; bypassCmdWindow - some apps will never work with the command window, like xpadder. enable this argument on these Run calls so it doesn't get caught here
- Run(target,workingDir="",options=0,ByRef outputVarPID="",inputBlocker=1,bypassCmdWindow=0,disableLogging=0){
- Static cmdWindowCount
- Global logShowCommandWindow,logCommandWindow,cmdWindowObj,blockInputTime,blockInputFile,errorLevelReporting
- options := If options = 1 ? "useErrorLevel" : options ; enable or disable error level
- If disableLogging
- Log("Run - Running hidden executable in " . workingDir)
- Else
- Log("Run - Running: " . workingDir . "\" . target)
- If (blockInputTime && inputBlocker = 1) ; if user set a block time, use the user set length
- blockTime := blockInputTime
- Else If (inputBlocker > 1) ; if module called for a block, use that amount
- blockTime := inputBlocker
- Else ; do not block input
- blockTime := ""
- If blockTime
- { Log("Run - Blocking Input for: " . blockTime . " seconds")
- Run, %blockInputFile% %blockTime%
- }
- If !cmdWindowObj
- cmdWindowObj := Object() ; initialize object, this is used so all the command windows can be properly closed on exit
- If (logShowCommandWindow = "true" && !bypassCmdWindow) {
- Run, %ComSpec% /k, %workingDir%, %options%, outputVarPID ; open a command window (cmd.exe), starting in the directory of the target executable
- curErr := ErrorLevel ; store error level immediately
- If errorLevelReporting = true
- { Log("Run - Error Level for " . ComSpec . " reported as: " . curErr, 4)
- errLvl := curErr ; allows the module to handle the error level
- }
- Log("Run - Showing Command Window to troubleshoot launching. ProcessID: " . outputVarPID)
- WinWait, ahk_pid %outputVarPID%
- WinActivate, ahk_pid %outputVarPID%
- WinWaitActive, ahk_pid %outputVarPID%,,2
- If ErrorLevel {
- WinSet, AlwaysOnTop, On, ahk_pid %outputVarPID%
- WinActivate, ahk_pid %outputVarPID%
- WinWaitActive, ahk_pid %outputVarPID%,,2
- If ErrorLevel
- ScriptError("Could not put focus onto the command window. Please try turning off Fade In if you have it enabled in order to see it")
- }
- WinGet, procName, ProcessName, ahk_pid %outputVarPID% ; get the name of the process (which should usually be cmd.exe)
- mapObjects[currentObj,"type"] := "database"
- cmdWindowCount++
- cmdWindowObj[cmdWindowCount,"Name"] := procName ; store the ProcessName being ran
- cmdWindowObj[cmdWindowCount,"PID"] := outputVarPID ; store the PID of the application being ran
- foundPos := RegExMatch(target,".*\.(exe|bat)",targetExeOnly) ; grab only the exe or bat file from the supplied target
- exeLen := StrLen(targetExeOnly) ; get length of exe name
- params := SubStr(target, exeLen+1) ; grab optional params out of supplied target
- If InStr(targetExeOnly, A_Space)
- target := """" . targetExeOnly . """" . params
- If (logCommandWindow = "true")
- SendInput, {Raw}%target% 1>"%A_ScriptDir%\command_%cmdWindowCount%_output.log" 2>"%A_ScriptDir%\command_%cmdWindowCount%_error.log" ; send the text to the command window and log the output to file
- Else
- SendInput, {Raw}%target% ; send the text to the command window and run it
- Send, {Enter}
- } Else {
- Run, %target%, %workingDir%, %options%, outputVarPID
- curErr := ErrorLevel ; store error level immediately
- If errorLevelReporting = true
- { Log("Run - Error Level for " . target . " reported as: " . curErr, 4)
- errLvl := curErr ; allows the module to handle the error level
- }
- }
- If disableLogging
- Log("Run - ""Hidden executable"" Process ID: " . outputVarPID, 4)
- Else
- Log("Run - """ . target . """ Process ID: " . outputVarPID, 4)
- Return errLvl
- }
- ; Replaces standard ahk IniRead calls
- ; Will not let ERROR be returned, returns no value instead
- ; If errormsg is set, will trigger ScriptError instead of returning no or default value
- IniRead(file,section,key,defaultvalue="",errorMsg="") {
- IniRead, v, %file%, %section%, %key%, %defaultvalue%
- ; msgbox % v
- Log("IniRead - SECTION: [" . section . "] - KEY: " . key . " - VALUE: " . v . " - FILE: " . file,4)
- If (v = "ERROR" || v = A_Space) { ; if key does not exist or is a space, delete ERROR as the value
- If errorMsg
- ScriptError(errorMsg)
- Else {
- If (defaultValue := A_Space) ; this prevents the var from existing when it's actually blank
- defaultValue := ""
- Return defaultValue
- }
- }
- Return v
- }
- ; Replaces standard ahk IniWrite calls
- ; compare = if used, only writes new value if existing value differs
- IniWrite(value,file,section,key,compare="") {
- If compare {
- IniRead, v, %file%, %section%, %key%
- If (v != value) {
- IniWrite, %value%, %file%, %section%, %key%
- err := ErrorLevel
- Log("IniWrite - ini updated due to differed value. SECTION: [" . section . "] - KEY: " . key . " - Old: " . v . " | New: " . value)
- } Else
- Log("IniWrite - ini value already correct. SECTION: [" . section . "] - KEY: " . key . " - Value: " . value,4)
- } Else {
- IniWrite, %value%, %file%, %section%, %key%
- err := ErrorLevel
- Log("IniWrite - SECTION: [" . section . "] - KEY: " . key . " - VALUE: " . value . " - FILE: " . file)
- }
- If err
- Log("IniWrite - There was an error writing to the ini",3)
- Return err ; returns 1 if there was an error
- }
- Process(cmd,name,param=""){
- Log("Process - " . cmd . A_Space . name . A_Space . param)
- Process, %cmd%, %name%, %param%
- Return ErrorLevel
- }
- SetKeyDelay(delay="",pressDur="",play="") {
- Global pressDuration
- If (delay = "") ; -1 is the default delay for play mode and 10 for event mode when none is supplied
- delay := (If play = "" ? 10 : -1)
- If (pressDur = "") ; -1 is the default pressDur when none is supplied
- pressDur := -1
- Log("SetKeyDelay - Current delay is " . A_KeyDelay . ". Current press duration is " . pressDuration . ". Delay will now be set to """ . delay . """ms for a press duration of """ . pressDur . """", 4)
- SetKeyDelay, %delay%, %pressDur%, %play%
- pressDuration := pressDur ; this is so the current pressDuration can be monitored outside the function
- }
- ; Mainly used in modules to read module.ini settings so multiple sections of an ini can be read of the same key name
- ; section: Allows | separated values so multiple sections can be checked.
- IniReadCheck(file,section,key,defaultvalue="",errorMsg="",logType="") {
- Loop, Parse, section, |
- { section%A_Index% := A_LoopField ; keep each parsed section in its own var
- If iniVar != "" ; if last loop's iniVar has a value, update this loop's default value with it
- defaultValue := If A_Index = 1 ? defaultValue : iniVar ; on first loop, default value will be the one sent to the function, on following loops it gets the value from the previous loop
- IniRead, iniVar, %file%, % section%A_Index%, %key%, %defaultvalue%
- If (IniVar = "ERROR" || iniVar = A_Space) ; if key does not exist or is a space, delete ERROR as the value
- iniVar := ""
- If (A_Index = 1 && iniVar = "" and !logType) {
- If errorMsg
- ScriptError(errorMsg)
- Else
- IniWrite, %defaultValue%, %file%, % section%A_Index%, %key%
- Return defaultValue
- }
- If logType ; only log if logType set
- { logAr := ["Module","Bezel"]
- Log(logAr[logType] . " Setting - [" . section%A_Index% . "] - " . key . ": " . iniVar)
- }
- If (iniVar != "") ; if IniVar contains a value, update the lastIniVar
- lastIniVar := iniVar
- }
- If defaultValue = %A_Space% ; this prevents the var from existing when it's actually blank
- defaultValue := ""
- Return If A_Index = 1 ? iniVar : If lastIniVar != "" ? lastIniVar : defaultValue ; if this is the first loop, always return the iniVar. If any other loop, return the lastinivar if it was filled, otherwise send the last updated defaultvalue
- }
- MaximizeWindow(WinTitle, keepAspectRatio="true", removeTitle="true", removeBorder="true", removeToggleMenu="true") {
- Log("MaximizeWindow - Started to process window """ . winTitle . """", 4)
- If (removeTitle = "true")
- RL.WinSet("Style", "-0xC00000", WinTitle) ;Removes the titlebar of the game window
- If (removeBorder = "true")
- RL.WinSet("Style", "-0x40000", WinTitle) ;Removes the border of the game window
- If (removeToggleMenu = "true") {
- WinID := RL.WinGet( "ID", WinTitle)
- ToggleMenu(WinID)
- }
- If (keepAspectRatio = "true") {
- RL.WinGetPos(appX, appY, appWidth, appHeight, WinTitle)
- widthMaxPercenty := ( A_ScreenWidth / appWidth )
- heightMaxPercenty := ( A_ScreenHeight / appHeight )
- If ( widthMaxPercenty < heightMaxPercenty )
- percentToEnlarge := widthMaxPercenty
- Else
- percentToEnlarge := heightMaxPercenty
- appWidthNew := appWidth * percentToEnlarge
- appHeightNew := appHeight * percentToEnlarge
- appY := RL.Transform("Round", appY)
- appWidthNew := RL.Transform("Round", appWidthNew, 2)
- appHeightNew := RL.Transform("Round", appHeightNew, 2)
- appXPos := ( A_ScreenWidth / 2 ) - ( appWidthNew / 2 )
- appYPos := ( A_ScreenHeight / 2 ) - ( appHeightNew / 2 )
- }
- Else {
- appXPos := 0
- appYPos := 0
- appWidthNew := A_ScreenWidth
- appHeightNew := A_ScreenHeight
- }
- MoveWindow(WinTitle,appXPos,appYPos,appWidthNew,appHeightNew)
- Log("MaximizeWindow - Ended", 4)
- }
- MoveWindow(winTitle,X,Y,W,H,timeLimit=2000,ignoreWin=""){ ; assures that a window is moved to the desired position within a timeout
- Log("MoveWindow - Moving window " . winTitle . " to X=" . X . ", Y=" . Y . ", W=" . W . " H=" . H, 4)
- RL.WinMove(winTitle,"", X, Y, W, H, ignoreWin)
- ;check If window moved
- timeout := A_TickCount
- Loop
- { RL.WinGetPos(Xgot, Ygot, Wgot, Hgot, winTitle,"", ignoreWin)
- If ((Xgot=X) and (Ygot=Y) and (Wgot=W) and (Hgot=H)){
- Log("MoveWindow - Successful: Window " . winTitle . " moved to X=" . X . ", Y=" . Y . ", W=" . W . " H=" . H, 4)
- error := 0
- Break
- }
- If (timeout<A_TickCount-timeLimit){
- Log("MoveWindow - Failed: Window " . winTitle . " at X=" . Xgot . ", Y=" . Ygot . ", W=" . Wgot . " H=" . Hgot, 4)
- error := 1
- Break
- }
- Sleep, 200
- RL.WinMove(winTitle,"", X, Y, W, H, ignoreWin)
- }
- Return error
- }
- ; Purpose: Handle an emulators Open Rom window when CLI is not an option
- ; Returns 1 when successful
- OpenROM(windowName,selectedRomName) {
- Log("OpenROM - Started")
- Global MEmu,moduleName
- RL.WinWait(windowName)
- RL.WinWaitActive(windowName)
- state := 0
- Loop, 150 ; 15 seconds
- { RL.ControlSetText("Edit1", selectedRomName, windowName)
- edit1Text := RL.ControlGetText(Edit1, windowName)
- If (edit1Text = selectedRomName) {
- state := 1
- Log("OpenROM - Successfully set romName into """ . windowName . """ in " . A_Index . " " . (If A_Index = 1 ? "try." : "tries."),4)
- Break
- }
- Sleep, 100
- }
- If (state != 1)
- ScriptError("Tried for 15 seconds to send the romName to " . MEmu . " but was unsuccessful. Please try again with Fade and Bezel disabled and put the " . moduleName . " in windowed mode to see if the problem persists.", 10)
- RL.PostMessage("0x111", 1,"","", windowName) ; Select Open
- Log("OpenROM - Ended")
- Return %state%
- }
- GetActiveWindowStatus(){
- dWin := A_DetectHiddenWindows ; store current value to return later
- DetectHiddenWindows, On
- activeWinHWND := WinExist("A")
- WinGet, procPath, ProcessPath, ahk_id %activeWinHWND%
- WinGet, procID, PID, ahk_id %activeWinHWND%
- WinGet, winState, MinMax, ahk_id %activeWinHWND%
- WinGetClass, winClass, ahk_id %activeWinHWND%
- WinGetTitle, winTitle, ahk_id %activeWinHWND%
- WinGetPos, X, Y, W, H, ahk_id %activeWinHWND%
- Log("GetActiveWindowStatus - Title: " . winTitle . " | Class: " . winClass . " | State: " . winState . " | X: " . X . " | Y: " . Y . " | Width: " . W . " | Height: " . H . " | Window HWND: " . activeWinHWND . " | Process ID: " . procID . " | Process Path: " . procPath, 4)
- DetectHiddenWindows, %dWin% ; restore prior state
- }
- ; CheckFile Usage:
- ; file = file to be checked if it exists
- ; msg = the error msg you want displayed on screen if you don't want the default "file not found"
- ; timeout = gets passed to ScriptError(), the amount of time you want the error to show on screen
- ; crc = If this is a an AHK library only, provide a crc so it can be validated
- ; crctype = default empty and crc is not checked. Use 0 for AHK libraries and RocketLauncher extension files. Use 1 for module crc checks..
- ; logerror = default empty will give a log error instead of stopping with a scripterror
- ; allowFolder = allows folders or files w/o an extension to be checked. By default a file must have an extension.
- CheckFile(file,msg="",timeout=6,crc="",crctype="",logerror="",allowFolder=0){
- Global RLObject,logIncludeFileProperties
- exeFileInfo := "
- ( LTrim
- FileDescription
- FileVersion
- InternalName
- LegalCopyright
- OriginalFilename
- ProductName
- ProductVersion
- CompanyName
- PrivateBuild
- SpecialBuild
- LegalTrademarks
- )"
- Log("CheckFile - Checking if " . file . " exists")
- SplitPath, file, fileName, filePath, fileExt, fileNameNoExt
- If !FileExist(filePath . "\" . fileName)
- If FileExist(filePath . "\" . fileNameNoExt . " (Example)." . fileExt) {
- FileCopy, %filePath%\%fileNameNoExt% (Example).%fileExt%, %filePath%\%fileName%
- If ErrorLevel
- Log("CheckFile - Found an example for this file, but did not have permissions to retore it: " . filePath . "\" . fileNameNoExt . " (Example)." . fileExt,3)
- Else
- Log("CheckFile - Restored this file from its example: " . filePath . "\" . fileNameNoExt . " (Example)." . fileExt,2)
- } Else {
- If msg
- ScriptError(msg, timeout)
- Else
- ScriptError("Cannot find " . file, timeout)
- }
- If (!fileExt && !allowFolder)
- ScriptError("This is a folder and must point to a file instead: " . file, timeout)
- If (crctype = 0 Or crctype = 1) {
- CRCResult := RL_checkModuleCRC("" . file . "",crc,crctype)
- If (CRCResult = -1)
- Log("CRC Check - " . (If crctype=1 ? "Module" : If (crctype=0 && crc) ? "Library" : "Extension") . " file not found.",3)
- Else If (CRCResult = 0)
- If (crctype = 1)
- Log("CRC Check - CRC does not match official module and will not be supported. Continue using at your own risk.",2)
- Else If logerror
- Log("CRC Check - CRC does not match for this " . (If (crctype=0 && crc) ? "Library" : "Extension") . ". Please re-download this file to continue using RocketLauncher: " . file,3)
- Else
- ScriptError("CRC Check - CRC does not match for this " . (If (crctype=0 && crc) ? "Library" : "Extension") . ". Please re-download this file to continue using RocketLauncher: " . file)
- Else If (CRCResult = 1)
- Log("CRC Check - CRC matches, this is an official unedited " . (If crctype=1 ? "Module" : If (crctype=0 && crc) ? "Library" : "Extension") . ".",4)
- Else If (CRCResult = 2)
- Log("CRC Check - No CRC defined on the header for: " . file,3)
- }
- If (logIncludeFileProperties = "true")
- { If exeAtrib := FileGetVersionInfo_AW(file, exeFileInfo, "`n")
- Loop, Parse, exeAtrib, `n
- logTxt .= (If A_Index=1 ? "":"`n") . "`t`t`t`t`t" . A_LoopField
- FileGetSize, fileSize, %file%
- FileGetTime, fileTimeC, %file%, C
- FormatTime, fileTimeC, %fileTimeC%, M/d/yyyy - h:mm:ss tt
- FileGetTime, fileTimeM, %file%, M
- FormatTime, fileTimeM, %fileTimeM%, M/d/yyyy - h:mm:ss tt
- logTxt .= (If logTxt ? "`r`n":"") . "`t`t`t`t`tFile Size:`t`t`t" . fileSize . " bytes"
- logTxt .= "`r`n`t`t`t`t`tCreated:`t`t`t" . fileTimeC
- logTxt .= "`r`n`t`t`t`t`tModified:`t`t`t" . fileTimeM
- Log("CheckFile - Attributes:`r`n" . logTxt,4)
- }
- Return %file%
- }
- CheckFolder(folder,msg="",timeout=6,crc="",crctype="",logerror="") {
- Return CheckFile(folder,msg,timeout,crc,crctype,logerror,1)
- }
- ; ScriptError usage:
- ; error = error text
- ; timeout = duration in seconds error will show
- ; w = width of error box
- ; h = height of error box
- ; txt = font size
- ScriptError(error,timeout=6,w=800,h=225,txt=20,noexit=""){
- Global RLMediaPath,exitEmulatorKey,RLFile,RLErrSoundPath,logShowCommandWindow,cmdWindowObj,scriptErrorTriggered
- Global screenRotationAngle,baseScreenWidth,baseScreenHeight,xTranslation,yTranslation,XBaseRes,YBaseRes
- XHotKeywrapper(exitEmulatorKey,"CloseProcess","OFF")
- XHotKeywrapper(exitEmulatorKey,"CloseError","ON")
- Hotkey, Esc, CloseError
- Hotkey, Enter, CloseError
- If !pToken := Gdip_Startup(){ ; Start gdi+
- MsgBox % "Gdiplus failed to start. Please ensure you have gdiplus on your system"
- ExitApp
- }
- timeout *= 1000 ; converting to seconds
- ;Acquiring screen info for dealing with rotated menu drawings
- Gdip_Alt_GetRotatedDimensions(A_ScreenWidth, A_ScreenHeight, screenRotationAngle, baseScreenWidth, baseScreenHeight)
- Gdip_GetRotatedTranslation(baseScreenWidth, baseScreenHeight, screenRotationAngle, xTranslation, yTranslation)
- xTranslation:=round(xTranslation), yTranslation:=round(yTranslation)
- XBaseRes := 1920, YBaseRes := 1080
- If (((A_screenWidth < A_screenHeight) and ((screenRotationAngle=0) or (screenRotationAngle=180))) or ((A_screenWidth > A_screenHeight) and ((screenRotationAngle=90) or (screenRotationAngle=270))))
- XBaseRes := 1080, YBaseRes := 1920
- If !errorXScale
- errorXScale := baseScreenWidth/XBaseRes
- If !errorYScale
- errorYScale := baseScreenHeight/YBaseRes
- Error_Warning_Width := w
- Error_Warning_Height := h
- Error_Warning_Pen_Width := 7
- Error_Warning_Rounded_Corner := 30
- Error_Warning_Margin := 30
- Error_Warning_Bitmap_Size := 125
- Error_Warning_Text_Size := txt
- OptionScale(Error_Warning_Width, errorXScale)
- OptionScale(Error_Warning_Height, errorYScale)
- OptionScale(Error_Warning_Pen_Width, errorXScale)
- OptionScale(Error_Warning_Rounded_Corner, errorXScale)
- OptionScale(Error_Warning_Margin, errorXScale)
- OptionScale(Error_Warning_Bitmap_Size, errorXScale)
- OptionScale(Error_Warning_Text_Size, errorYScale)
- ;Create error GUI
- Gui, Error_GUI: +Disabled -Caption +E0x80000 +OwnDialogs +LastFound +ToolWindow +AlwaysOnTop
- Gui, Error_GUI: Margin,0,0
- Gui, Error_GUI: Show,, ErrorLayer
- Error_hwnd := WinExist()
- Error_hbm := CreateDIBSection(A_ScreenWidth, A_ScreenHeight)
- Error_hdc := CreateCompatibleDC()
- Error_obm := SelectObject(Error_hdc, Error_hbm)
- Error_G := Gdip_GraphicsFromhdc(Error_hdc)
- Gdip_SetSmoothingMode(Error_G, 4)
- Gdip_TranslateWorldTransform(Error_G, xTranslation, yTranslation)
- Gdip_RotateWorldTransform(Error_G, screenRotationAngle)
- pGraphUpd(Error_G,baseScreenWidth, baseScreenHeight)
- ;Create GUI elements
- pBrush := Gdip_BrushCreateSolid("0xFF000000") ; Painting the background color
- Gdip_Alt_FillRectangle(Error_G, pBrush, -1, -1, baseScreenWidth+1, baseScreenHeight+1) ; draw the background first on layer 1 first, layer order matters!!
- brushWarningBackground := Gdip_CreateLineBrushFromRect(0, 0, Error_Warning_Width, Error_Warning_Height, 0xff555555, 0xff050505)
- penWarningBackground := Gdip_CreatePen(0xffffffff, Error_Warning_Pen_Width)
- Gdip_Alt_FillRoundedRectangle(Error_G, brushWarningBackground, (baseScreenWidth - Error_Warning_Width)//2, (baseScreenHeight - Error_Warning_Height)//2, Error_Warning_Width, Error_Warning_Height, Error_Warning_Rounded_Corner)
- Gdip_Alt_DrawRoundedRectangle(Error_G, penWarningBackground, (baseScreenWidth - Error_Warning_Width)//2, (baseScreenHeight - Error_Warning_Height)//2, Error_Warning_Width, Error_Warning_Height, Error_Warning_Rounded_Corner)
- WarningBitmap := Gdip_CreateBitmapFromFile(RLMediaPath . "\Menu Images\RocketLauncher\Warning.png")
- Gdip_Alt_DrawImage(Error_G,WarningBitmap, round((baseScreenWidth - Error_Warning_Width)//2 + Error_Warning_Margin),round(baseScreenHeight/2 - Error_Warning_Bitmap_Size/2),Error_Warning_Bitmap_Size,Error_Warning_Bitmap_Size)
- Gdip_Alt_TextToGraphics(Error_G, error, "x" round((baseScreenWidth-Error_Warning_Width)//2+Error_Warning_Bitmap_Size+Error_Warning_Margin) " y" round((baseScreenHeight-Error_Warning_Height)//2+Error_Warning_Margin) " Left vCenter cffffffff r4 s" Error_Warning_Text_Size " Bold",, round((Error_Warning_Width - 2*Error_Warning_Margin - Error_Warning_Bitmap_Size)) , round((Error_Warning_Height - 2*Error_Warning_Margin)))
- startTime := A_TickCount
- Loop{ ; fade in
- t := ((TimeElapsed := A_TickCount-startTime) < 300) ? (255*(timeElapsed/300)) : 255
- Alt_UpdateLayeredWindow(Error_hwnd,Error_hdc, 0, 0, baseScreenWidth, baseScreenHeight,t)
- If (t >= 255)
- Break
- }
- ; Generate a random sound to play on a script error
- erSoundsAr:=[] ; initialize the array to store error sounds
- Loop, %RLErrSoundPath%\error*.mp3
- erSoundsAr.Insert(A_LoopFileName) ; insert each found error sound into an array
- Random, erRndmSound, 1, % erSoundsAr.MaxIndex() ; randomize what sound to play
- Log("ScriptError - Playing error sound: " . erSoundsAr[erRndmSound],4)
- setMute(0,emulatorVolumeObject)
- SoundPlay % If erSoundsAr.MaxIndex() ? (RLErrSoundPath . "\" . erSoundsAr[erRndmSound]):("*-64"), wait ; play the random sound if any exist, or default to the Asterisk windows sound
- If noexit { ; do not close thread, continue with script and let it handle the exiting
- scriptErrorTriggered := 1
- Return
- }
- 7zCleanUp() ; clean up 7z if necessary
- Sleep, %timeout%
- CloseError:
- endTime := A_TickCount
- Loop { ; fade out
- t := ((TimeElapsed := A_TickCount-endTime) < 300) ? (255*(1-timeElapsed/300)) : 0
- Alt_UpdateLayeredWindow(Error_hwnd,Error_hdc, 0, 0, baseScreenWidth, baseScreenHeight,t)
- If (t <= 0)
- Break
- }
- XHotKeywrapper(exitEmulatorKey,"CloseError","OFF")
- XHotKeywrapper(exitEmulatorKey,"CloseProcess","ON")
- Gdip_DeleteBrush(pBrush)
- Gdip_DisposeImage(WarningBitmap), SelectObject(Error_hdc, Error_obm), DeleteObject(Error_hbm), DeleteDC(Error_hdc), Gdip_DeleteGraphics(Error_G)
- Gui, ErrorGUI_10: Destroy
- Log("ScriptError - " . error,3)
- ExitModule() ; attempting to use this method which has the small chance to cause an infinite ScriptError loop, but no need to duplicate code to clean up on errors
- ; Below cleanup exists because we can't call other functions that may cause additional scripterrors and put the thread in an infinite loop
- ; If logShowCommandWindow = true
- ; { for index, element in cmdWindowObj
- ; Process, Close, % cmdWindowObj[A_Index,1] ; close each opened cmd.exe
- ; }
- ; ExitApp
- }
- ; Log usage:
- ; text = text I want to log
- ; lvl = the lvl to log the text at
- ; notime = only used for 1st and last lines of the log so a time is not inserted when I inset the BBCode [code] tags. Do not use this param
- ; dump = tells the function to write the log file at the end. Do not use this param
- ; firstLog = tells the function to not insert a time when the first log is made, instead puts an N/A. Do not use this param
- ; Log() in the module thread requires `r`n at the end of each line, where it's not needed in the RocketLauncher thread
- Log(text,lvl=1,notime="",dump="",firstLog=""){
- Static log
- Static lastLog
- Global logFile,logLevel,logLabel,logShowDebugConsole
- ; Global executable
- If (logLevel > 0)
- {
- If (lvl<=logLevel || lvl=3){ ; ensures errors are always logged
- logDiff := A_TickCount - lastLog
- lastLog := A_TickCount
- log := log . (If notime?"" : A_Hour . ":" . A_Min ":" . A_Sec ":" . A_MSec . " | MD | " . logLabel[lvl] . A_Space . " | +" . AlignColumn(If firstLog ? "N/A" : logDiff) . "" . " | ") . text . "`r`n"
- }
- If (logShowDebugConsole = "true")
- DebugMessage(log)
- If (logLevel>=10 || dump){
- FileAppend,%log%,%logFile%
- log := ""
- }
- ; Process, Exist, %executable%
- ; If ErrorLevel
- ; Log .= "mame exists`r`n"
- Return log
- }
- }
- ; Inserts extra characters/spaces into sections of the Log file to keep it aligned.
- ; Usage: inserts char x number of times on the end of txt until pad is reached.
- AlignColumn(txt,pad=9,char=" "){
- x := If char=" "?2:1 ; if char is a space, let's only insert half as many so it looks slightly more even in notepad++
- Loop {
- n := StrLen(txt)
- If (n*x >= pad)
- Break
- txt := txt . char
- }
- Return txt
- }
- ; Rini returns -2 if section does not exist
- ; Rini returns -3 if key does not exist
- ; Rini returns -10 if an invalid reference var for the ini file was used
- ; Rini returns empty value if key exists with no value
- ; rIniIndex := Object(1,globalRLFile,2,sysRLFile,3,globalEmuFile,4,sysEmuFile,5,RLFile,6,gamesFile)
- ; preferDefault - On rare occasions we may want to set a default value w/o wanting rini to return an error value of -2 or -3. Used for JoyIDs_Preferred_Controllers
- RIniLoadVar(gRIniVar,sRIniVar,section,key,gdefaultvalue="",sdefaultvalue="use_global",preferDefault="") {
- Global rIniIndex
- If (gRIniVar != 6) ; do not create missing sections or keys for games.ini
- { gValue := RIni_GetKeyValue(gRIniVar,section,key,If preferDefault ? gdefaultvalue : "")
- gValue := gValue ; trims whitespace
- If RegExMatch(gValue,"-2|-3") ; if global ini key does not exist, create the key
- { RIni_SetKeyValue(gRIniVar,section,key,gdefaultvalue)
- RIni_Write(gRIniVar,rIniIndex[gRIniVar],"`r`n",1,1,1)
- gValue := gdefaultvalue ; set to default value because it did not exist
- Log("RIniLoadVar - Created missing Global ini key: """ . key . """ in section: """ . section . """ in """ . rIniIndex[gRIniVar] . """",2)
- }
- If sRIniVar ; != "" ; only create system sections or keys for inis that use them
- { sValue := RIni_GetKeyValue(sRIniVar,section,key,If preferDefault ? sdefaultvalue : "")
- sValue := sValue ; trims whitespace
- If RegExMatch(sValue,"-2|-3") ; if system ini key does not exist, create the key
- { RIni_SetKeyValue(sRIniVar,section,key,sdefaultvalue)
- RIni_Write(sRIniVar,rIniIndex[sRIniVar],"`r`n",1,1,1)
- sValue := sdefaultvalue ; set to default value because it did not exist
- Log("RIniLoadVar - Created missing System ini key: """ . key . """ in section: """ . section . """ in """ . rIniIndex[sRIniVar] . """",2)
- }
- Return If sValue = "use_global" ? gValue : sValue ; now compare global & system keys to get final value
- }
- Return gValue ; return gValue when not using globa/system inis, like RLFile (rIniIndex 5)
- }
- iniVar := RIni_GetKeyValue(gRIniVar,section,key,gdefaultvalue) ; lookup key from ini and return it
- iniVar := iniVar ; trims whitespace
- Return iniVar
- }
- RIniReadCheck(rIniVar,section,key,defaultvalue="",errorMsg="") {
- Global rIniIndex
- iniVar := RIni_GetKeyValue(rIniVar,section,key) ; lookup key from ini and return it
- iniVar := iniVar ; trims whitespace
- If (iniVar = -2 or iniVar = -3 or iniVar = "") {
- If (iniVar != "") { ; with rini, no need write to ini file if value is returned empty, we already know the section\key exists with no value
- Log("RIniReadCheck - Created missing RocketLauncher ini key: """ . key . """ in section: """ . section . """ in """ . rIniIndex[rIniVar] . """",2)
- RIni_SetKeyValue(rIniVar,section,key,defaultvalue)
- RIni_Write(rIniVar,rIniIndex[rIniVar],"`r`n",1,1,1) ; write blank section, blank key, and space between sections
- }
- If errorMsg
- ScriptError(errorMsg)
- Return defaultValue
- }
- Return iniVar
- }
- CheckFont(font) {
- If !(Gdip_FontFamilyCreate(font))
- ScriptError("The Font """ . font . """ is not installed on your system. Please install the font or change it in RocketLauncherUI.")
- }
- ; Toggles hiding/showing a MenuBar
- ; Usage: Provide the window's PID of the window you want to toggle the MenuBar
- ; used in nulldc module and bezel
- ToggleMenu(hWin){
- Static hMenu, visible
- If (hMenu = "")
- hMenu := DllCall("GetMenu", "uint", hWin) ; store the menubar ID so it can be restored later
- hMenuCur := DllCall("GetMenu", "uint", hWin)
- timeout := A_TickCount
- If !hMenuCur
- Loop {
- ;ToolTip, menubar is hidden`, bringing it back`nhMenuCur: %hMenuCur%`n%A_Index%
- hMenuCur := DllCall("GetMenu", "uint", hWin)
- If hMenuCur {
- Log("ToggleMenu - MenuBar is now visible for " . hWin,4)
- Break ; menubar is now visible, break out
- }
- DllCall("SetMenu", "uint", hWin, "uint", hMenu)
- If (timeout < A_TickCount - 500) ; prevents an infinite loop and breaks after 2 seconds
- Break
- }
- Else Loop { ; menubar is visible
- ;ToolTip, menubar is visible`, hiding it`nhMenuCur: %hMenuCur%`n%A_Index%
- hMenuCur := DllCall("GetMenu", "uint", hWin)
- If !hMenuCur {
- Log("ToggleMenu - MenuBar is now hidden for " . hWin,4)
- Break ; menubar is now hidden, break out
- }
- DllCall("SetMenu", "uint", hWin, "uint", 0)
- If (timeout < A_TickCount - 500) ; prevents an infinite loop and breaks after 2 seconds
- Break
- }
- }
- ; Original function but somestimes does not work, which is why the new function loops above
- ToggleMenuOld(hWin){
- Static hMenu, visible
- If (hMenu = "")
- hMenu := DllCall("GetMenu", "uint", hWin)
- If !visible
- DllCall("SetMenu", "uint", hWin, "uint", hMenu)
- Else
- DllCall("SetMenu", "uint", hWin, "uint", 0)
- visible := !visible
- }
- ; Function to pause and wait for a user to press any key to continue.
- ; IdleCheck usage:
- ; t = timeout in ms to break out of function
- ; m = the method - can be "P" (physical) or "L" (logical)
- ; s = sleep or how fast the function checks for idle state
- ; Exits when state is no longer idle or times out
- IdleCheck(t="",m="L",s=200){
- timeIdlePrev := 0
- startTime := A_TickCount
- While timeIdlePrev < (If m = "L" ? A_TimeIdle : A_TimeIdlePhysical){
- timeIdlePrev := If m = "L" ? A_TimeIdle : A_TimeIdlePhysical
- If (t && A_TickCount-startTime >= t)
- Return "Timed Out"
- Sleep s
- }
- Return A_PriorKey
- }
- ; This function looks through all defined romPaths and romExtensions for the provided rom file
- ; Returns a path to the rom where it was found
- ; Returns nothing if not found
- RomNameExistCheck(file,archivesOnly="") {
- Global romPathFromIni,romExtensions,sevenZFormats
- Loop, Parse, romPathFromIni, | ; for each rom path defined
- { tempRomPath := A_LoopField ; assigning this to a var so it can be accessed in the next loop
- Loop, Parse, romExtensions, | ; for each extension defined
- { If (archivesOnly != "")
- If !InStr(sevenZFormats,A_LoopField) ; if rom extension is not an archive type, skip this rom
- Continue
- ; msgbox % tempRomPath . "\" . file . "." . tempRomExtension
- Log("RomNameExistCheck - Looking for rom: " . tempRomPath . "\" . file . "." . A_LoopField,4)
- If FileExist( tempRomPath . "\" . file . "." . A_LoopField ) {
- Log("RomNameExistCheck - Found rom: " . tempRomPath . "\" . file . "." . A_LoopField)
- Return tempRomPath . "\" . file . "." . A_LoopField ; return path if file exists
- }
- Log("RomNameExistCheck - Looking for rom: " . tempRomPath . "\" . file . "\" . file . "." . A_LoopField,4)
- If FileExist( tempRomPath . "\" . file . "\" . file . "." . A_LoopField ) { ; check one folder deep of the rom's name in case user keeps each rom in a folder
- Log("RomNameExistCheck - Found rom: " . tempRomPath . "\" . file . "\" . file . "." . A_LoopField)
- Return tempRomPath . "\" . file . "\" . file . "." . A_LoopField ; return path if file exists
- }
- }
- }
- Log("RomNameExistCheck - Could not find """ . file . """ in any of your Rom Paths with any defined Rom Extensions",2)
- Return
- }
- ; Shared romTable function and label for Pause and MG which calculates what roms have multiple discs. Now available on every launch to support some custom uses for loading multiple disks on some older computer systems
- CreateMGRomTable:
- Log("CreateMGRomTable - Started")
- If !mgCandidate {
- Log("CreateMGRomTable - Ended - This rom does not qualify for MultiGame")
- Return
- }
- If !IsObject(romTable)
- { Log("CreateMGRomTable - romTable does not exist, creating one for """ . dbName . """",4)
- romTable := CreateRomTable(dbName)
- } Else
- Log("CreateMGRomTable - romTable already exists, skipping table creation.",4)
- Log("CreateMGRomTable - Ended")
- Return
- CreateRomTable(table) {
- Global romPathFromIni,dbName,romExtensionOrig,sevenZEnabled,romTableStarted,romTableComplete,romTableCanceled,rocketLauncherIsExiting,mgCandidate
- romTableStarted := 1
- romTableCanceled := ""
- romTableComplete := ""
- If rocketLauncherIsExiting {
- romTableCanceled := 1 ; set this so the RomTableCheck is canceled and doesn't get stuck in an infinite loop
- Log("CreateRomTable - RocketLauncher is currently exiting, skipping romTable creation")
- Return
- }
- If !mgCandidate {
- romTableCanceled := 1 ; set this so the RomTableCheck is canceled and doesn't get stuck in an infinite loop
- Log("CreateRomTable - This rom does not qualify for MultiGame")
- Return
- }
- Log("CreateRomTable - Started")
- romCount := 0 ; initialize the var and reset it, needed in case GUI is used more then once in a session
- table := [] ; initialize and empty the table
- typeArray := ["(Disc","(Disk","(Cart","(Tape","(Cassette","(Part","(Side"]
- regExCheck = i)\s\(Disc\s[^/]*|\s\(Disk\s[^/]*|\s\(Cart\s[^/]*|\s\(Tape\s[^/]*|\s\(Cassette\s[^/]*|\s\(Part\s[^/]*|\s\(Side\s[^/]*
- dbNamePre := RegExReplace(dbName, regExCheck) ; removes the last set of parentheses if Disc,Tape, etc is in them. A Space must exist before the "(" and after the word Disc or Tape, followed by the number. This is the HS2 standard
- Loop % typeArray.MaxIndex() ; loop each item in our array
- { If matchedRom ; Once we matched our game to the typeArray, no need to search for another. This allows the loop to break out.
- Break
- indexTotal ++
- Log("CreateRomTable - Checking for match: """ . dbName . """ and """ . typeArray[A_Index] . """",4)
- If dbName contains % typeArray[A_Index] ; find the item in our array that matches our rom
- { Log("CreateRomTable - """ . dbName . """ contains """ . typeArray[A_Index] . """",4)
- typeArrayIndex := A_Index
- Loop, Parse, romPathFromIni, |
- { indexTotal ++
- currentPath := A_LoopField
- Log("CreateRomTable - Checking New Rom path: " . currentPath,4)
- Log("CreateRomTable - Now looping in: " . currentPath . "\" . dbNamePre . A_Space . typeArray[typeArrayIndex] . "*",4)
- Loop, % currentPath . "\" . dbNamePre . A_Space . typeArray[typeArrayIndex] . "*", 1,1 ; we now know to only look for files & folders that have our rom & media type in them.
- { indexTotal ++
- Log(A_LoopFileFullPath,4)
- Log("CreateRomTable - Looking for: " . currentPath . "\" . dbNamePre . A_Space . typeArray[typeArrayIndex] . "*." . A_LoopFileExt,4)
- If romExtensionOrig contains % A_LoopFileExt ; Now we narrow down to all matching files using our original extension. Next we use this data to build an array of our files to populate the GUI.
- { romCount += 1
- matchedRom := 1 ; Allows to break out of the loops once we matched our rom
- table[romCount,1] := A_LoopFileFullPath ; Store A_LoopFileFullPath (full file path and file) in column 1
- table[romCount,2] := A_LoopFileName ; Store A_LoopFileName (the full filename and extension) in column 2
- table[romCount,3] := RegExReplace(table[romCount, 2], "\..*") ; Store the filename with media type # but w/o an extension in column 3
- pos := RegExMatch(table[romCount,2], regExCheck) ; finds position of our multi media type so we can trim away and generate the imageText and check if rom is part of a set. This pulls only the filenames out of the table in column 2.
- uncleanTxt:= SubStr(table[romCount,2], pos + 1) ; remove everything but the media type and # and ext from our file name
- table[romCount,4] := dbNamePre ; store dbName w/o the media type and #, used for Pause and updating statistics in column 4
- table[romCount,5] := RegExReplace(uncleanTxt, "\(|\)|\..*") ; clean the remainder, removing () and ext, then store it as column 5 in our table to be used for our imageText, this is the media type and #
- table[romCount,6] := SubStr(table[romCount,5],1,4) ; copies just the media type to column 6
- Log("CreateRomTable - Adding found game to Rom Table: " . A_LoopFileFullPath,4)
- }
- }
- }
- }
- }
- romTableComplete := 1 ; flag to tell the RomTableCheck the function is complete in case no romTable was created for non-MG games
- romTableStarted := ""
- Log("CreateRomTable - Ended`, " . IndexTotal . " Loops to create table.")
- Return table
- }
- ; Function that gets called in some modules to wait for romTable creation if the module bases some conditionals off whether this table exists or not
- RomTableCheck() {
- Global systemName,mgEnabled,pauseEnabled,romTable,romTableStarted,romTableComplete,romTableCanceled,mgCandidate,dbName
- If mgCandidate { ; && (pauseEnabled = "true" || mgEnabled = "true")) {
- ; If (!romTableStarted && !IsObject(romTable))
- ; romTable := CreateRomTable(dbName)
- Log("RomTableCheck - Started")
- ; PauseGlobalIni := A_ScriptDir . "\Settings\Global Pause.ini" ; Pause keys have not been read into memory yet, so they must be read here so RocketLauncher knows whether to run the below loop or not
- ; PauseSystemIni := A_ScriptDir . "\Settings\" . systemName . "\Pause.ini"
- ; IniRead, changeDiscMenuG, %PauseGlobalIni%, General Options, ChangeDisc_Menu_Enabled
- ; IniRead, changeDiscMenuS, %PauseSystemIni%, General Options, ChangeDisc_Menu_Enabled
- ; changeDiscMenu := If changeDiscMenuS = "use_global" ? changeDiscMenuG : changeDiscMenuS ; calculate to use system or global setting
- ; If (mgEnabled = "true" || changeDiscMenu = "true") {
- ; Log("RomTableCheck - MultiGame and/or Pause's Change Disc Menu is enabled so checking if romTable exists yet.",4)
- If !romTable.MaxIndex()
- Log("RomTableCheck - romTable does not exist yet, waiting until it does to continue loading the module.",4)
- Loop {
- If romTableComplete { ; this var gets created when CreateRomTable is complete in case this is not an MG game
- Log("RomTableCheck - Detected CreateRomTable is finished processing. Continuing with module thread.",4)
- Break
- } Else If romTableCanceled { ; this var gets created when CreateRomTable is cancelled in cases it is no longer needed
- Log("RomTableCheck - Detected CreateRomTable is no longer needed. Continuing with module thread.",4)
- Break
- } Else If (A_Index > 200) { ; if 20 seconds pass by, log there was an issue and continue w/o romTable
- Log("RomTableCheck - Creating the romTable took longer than 20 seconds. Continuing with module thread without waiting for the table's creation.",3)
- Break
- } Else
- Sleep, 100
- }
- ; }
- Log("RomTableCheck - Ended")
- } Else
- Log("RomTableCheck - This game is not a candidate for MG or Change DIsc menu.")
- }
- ; Allows changing LEDBlinky's active profile
- ; mode can be RL or Rom which tells LEDBlinky what profile to load
- ; Ledblinky's ini gets loaded on start, so this function will never touch it
- LEDBlinky(mode) {
- Global ledblinkyEnabled,ledblinkySystemName,ledblinkyFullPath,ledblinkyProfilePath,ledblinkyRLProfile,dbName,systemName,romName
- Static ledblinkyExists,ledblinkyExe,ledblinkyPath
- If (ledblinkyEnabled != "false")
- {
- If !ledblinkyExists { ; Make sure LEDBlinky exists first before trying to use it
- If FileExist(ledblinkyFullPath) {
- ledblinkyExists := 1
- SplitPath,ledblinkyFullPath,ledblinkyExe,ledblinkyPath
- } Else
- ScriptError("You are trying to use LEDBlinky support but could not locate it here: " . ledblinkyFullPath)
- }
- Log("LEDBlinky - Started, sending mode " . mode)
- If (mode = "START")
- Run(ledblinkyExe . " """ . (If romName ? romName : dbName) . """ """ . (If ledblinkySystemName ? ledblinkySystemName : systemName) . """", ledblinkyPath) ; Game Start Event
- Else If (mode = "END")
- Run(ledblinkyExe . " 4" , ledblinkyPath) ; Game Stop Event
- Else If (mode = "RL")
- Run(ledblinkyExe . " 15 RocketLauncher RocketLauncher", ledblinkyPath) ; Load RocketLauncher profile. "15" Tells ledblinky to skip all game start options and only light the controls.
- Else If (mode = "ROM")
- Run(ledblinkyExe . " 15 """ . (If romName ? romName : dbName) . """ """ . (If ledblinkySystemName ? ledblinkySystemName : systemName) . """", ledblinkyPath) ; return to rom profile. If within the module, romName can be used, otherwise default to dbName.
- Else
- Log("LEDBlinky - Unsupported use of LEDBlinky - UNKNOWN MODE SUPPLIED: """ . mode . """",3)
- Log("LEDBlinky - Ended")
- }
- }
- ; Allows changing WinIPAC's and UltraMap's active profile, among any other tools thrown at it that would utilize similar profile structure
- ; mode = can be START, END, RL or RESUME which represents what part of RL is called the function and what profiles will be loaded
- ; tool = the name of the tool or folder that will be searched in and checked if that setting is enabled. Ex: WinIPAC or UltraMap
- ; path = because of how the function supports multiple scenarios, the fullpath to the exe must be provided. Not through making it Global as variables like %prefix%FullPath cannot be made global
- ; ext = extension of the profiles to look for
- ; type = used to basically force special modes (only keyboard for now) so the function can support multiple scenarios that all use the same folder structures for profiles
- KeymapperProfileSelect(mode,tool,path,ext,type="") {
- Global keyboardEncoderEnabled,ultraMapEnabled,profilePath,keymapperFrontEndProfileName,systemName,emuName,dbName
- Global keymapperProfiles
- If !keymapperProfiles
- keymapperProfiles := {} ; create initial object
- If (type = "keyboard")
- prefix := "keyboardEncoder"
- Else
- prefix := tool
- If (%prefix%Enabled = "true") {
- keymapperProfiles[tool,"Enabled"] := "true"
- Log(tool . " - Started with mode: " . mode)
- If !keymapperProfiles[tool,"Exist"] { ; Make sure the tool exists first before trying to use it
- If FileExist(path) {
- keymapperProfiles[tool,"Exist"] := 1
- keymapperProfiles[tool,"FullPath"] := path
- SplitPath,path,exe,path
- keymapperProfiles[tool,"Exe"] := exe
- keymapperProfiles[tool,"Path"] := path
- keymapperProfiles[tool,"Ext"] := "." . ext
- keymapperProfiles[tool,"ProfilePath"] := profilePath . "\" . tool
- keymapperProfiles[tool,"RLProfile"] := keymapperProfiles[tool,"ProfilePath"] . "\RocketLauncher"
- keymapperProfiles[tool,"FEProfile"] := keymapperProfiles[tool,"ProfilePath"] . "\" . keymapperFrontEndProfileName
- keymapperProfiles[tool,"DefaultProfile"] := keymapperProfiles[tool,"ProfilePath"] . "\_Default"
- keymapperProfiles[tool,"SystemProfile"] := keymapperProfiles[tool,"ProfilePath"] . "\" . systemName
- keymapperProfiles[tool,"EmuProfile"] := keymapperProfiles[tool,"ProfilePath"] . "\" . emuName
- keymapperProfiles[tool,"RomProfile"] := keymapperProfiles[tool,"ProfilePath"] . "\" . systemName . "\" . dbName
- ; msgbox % "fullPath: " . keymapperProfiles[tool,"FullPath"] . "`nexe: " . keymapperProfiles[tool,"Exe"] . "`npath: " . keymapperProfiles[tool,"Path"] . "`nExt: " . keymapperProfiles[tool,"Ext"] . "`nProfilePath: " . keymapperProfiles[tool,"ProfilePath"] . "`nRLProfile: " . keymapperProfiles[tool,"RLProfile"] . "`nFEProfile: " . keymapperProfiles[tool,"FEProfile"] . "`nDefaultProfile: " . keymapperProfiles[tool,"DefaultProfile"] . "`nSystemProfile: " . keymapperProfiles[tool,"SystemProfile"] . "`nEmuProfile: " . keymapperProfiles[tool,"EmuProfile"] . "`nRomProfile: " . keymapperProfiles[tool,"RomProfile"]
- } Else {
- Log(tool . " - You have your path set to " . %prefix% . " defined, but it could not be found here: " . path,2)
- keymapperProfiles[tool,"Enabled"] := "false"
- }
- }
- If (mode = "START")
- { Log(tool . " - Searching for profiles",4)
- If FileExist(keymapperProfiles[tool,"RomProfile"] . keymapperProfiles[tool,"Ext"]) {
- profile := keymapperProfiles[tool,"RomProfile"] . keymapperProfiles[tool,"Ext"]
- } Else If FileExist(keymapperProfiles[tool,"EmuProfile"] . keymapperProfiles[tool,"Ext"]) {
- profile := keymapperProfiles[tool,"EmuProfile"] . keymapperProfiles[tool,"Ext"]
- } Else If FileExist(keymapperProfiles[tool,"SystemProfile"] . keymapperProfiles[tool,"Ext"]) {
- profile := keymapperProfiles[tool,"SystemProfile"] . keymapperProfiles[tool,"Ext"]
- } Else If FileExist(keymapperProfiles[tool,"DefaultProfile"] . keymapperProfiles[tool,"Ext"]) {
- profile := keymapperProfiles[tool,"DefaultProfile"] . keymapperProfiles[tool,"Ext"]
- } Else {
- Log(tool . " - No profiles found",4)
- Return
- }
- keymapperProfiles[tool,"LastProfile"] := profile
- } Else If (mode = "END")
- { Log(tool . " - Searching for your Front End profile",4)
- If FileExist(keymapperProfiles[tool,"FEProfile"] . keymapperProfiles[tool,"Ext"]) {
- profile := keymapperProfiles[tool,"FEProfile"] . keymapperProfiles[tool,"Ext"]
- } Else {
- Log(tool . " - Profile not found",4)
- Return
- }
- } Else If (mode = "RL")
- { Log(tool . " - Searching for your RocketLauncher profile",4)
- If FileExist(keymapperProfiles[tool,"RLProfile"] . keymapperProfiles[tool,"Ext"]) {
- profile := keymapperProfiles[tool,"RLProfile"] . keymapperProfiles[tool,"Ext"]
- } Else {
- Log(tool . " - Profile not found",4)
- Return
- }
- } Else If (mode = "RESUME")
- { Log(tool . " - Restoring to your last profile",4)
- If keymapperProfiles[tool,"LastProfile"] ; only restore to a previous profile if one was found on start
- profile := keymapperProfiles[tool,"LastProfile"]
- Else {
- Log(tool . " - A profile was not loaded on start, skipping any profile loading",4)
- Return
- }
- } Else
- Log(tool . " - Unsupported mode: " . mode,2)
- Log(tool . " - Loading found profile: " . profile,4)
- Run, % keymapperProfiles[tool,"Exe"] . " " . profile . (If tool = "UltraMap" ? "/logerrors " . keymapperProfiles[tool,"Path"] . "\UltraMapLog.log" : ""), % keymapperProfiles[tool,"Path"] ; If there was a problem loading a profile, WinIPAC will pop up with a box saying so with this title/class: "WinIPAC - Downloading ahk_class ThunderRT6FormDC". It does not return any error codes unfortunately. UltraMap requires errors to be logged otherwise it pops up with an error dialog.
- Log(tool . " - Ended")
- }
- }
- ; Function to measure the size of an text
- MeasureText(Text,Options,Font="Arial",Width="", Height="", ReturnMode="W", ByRef H="", ByRef W="", ByRef X="", ByRef Y="", ByRef Chars="", ByRef Lines=""){
- hdc_MeasureText := GetDC("MeasureText_hwnd")
- G_MeasureText := Gdip_GraphicsFromHDC(hdc_MeasureText)
- RECTF_STR := Gdip_TextToGraphics(G_MeasureText, Text, Options, Font, Width, Height, 1)
- StringSplit,RCI,RECTF_STR, |
- W := Ceil(RCI3)
- H := Ceil(RCI4)
- X := Ceil(RCI1)
- Y := Ceil(RCI2)
- Chars := Ceil(RCI5)
- Lines := Ceil(RCI6)
- DeleteDC(hdc_MeasureText), Gdip_DeleteGraphics(G_MeasureText)
- Return (ReturnMode="X") ? X : (ReturnMode="Y") ? Y :(ReturnMode="W") ? W :(ReturnMode="H") ? H : (ReturnMode="Chars") ? Chars : Lines
- }
- ; Function that allows making applications transparent so they can be hidden completely w/o moving them
- FadeApp(title,direction,time=0){
- startTime := A_TickCount
- Loop{
- t := ((TimeElapsed := A_TickCount-startTime) < time) ? (If direction="in" ? 255*(timeElapsed/time) : 255*(1-(timeElapsed/time))) : (If direction="in" ? 255 : 0)
- WinSet, Transparent, %t%, %title%
- If (direction = "in" && t >= 255) or (direction = "out" && t <= 0) {
- If (direction = "in")
- WinSet, Transparent, Off, %title%
- Break
- }
- }
- Log("HideFE - " . (If direction = "out" ? "Hiding Frontend by making it transparent" : "Showing Frontend and removing transparency"))
- }
- ; SplitPath function with support for roms that contain multiple periods in their name. AHK SplitPath does not support this.
- SplitPath(in,Byref outFileName,Byref outPath,Byref outExt,Byref outNameNoExt) {
- regx := "(\\{2}|(^[\w]:\\))([\w].+\w\\)" ; return path on regexmath and file on regexreplace
- regext := "((\.[^.\s]+)+)$" ; return extension with period (match literal period, match one or more at beginning any character and white space, one or more of all previous, and entire match must appear at end)
- in := RegExReplace(in,"/","\") ; replace all occurences of / with \
- RegExMatch(in, regx, outPathBSlash) ; path with backslash
- pathLen := StrLen(outPathBSlash) ; get length of path with slash
- outPath := SubStr(outPathBSlash, 1, pathLen - 1) ; grab path w/o slash
- RegExMatch(in, regext, outExtP) ; get ext with period
- outExt := SubStr(outExtP, 2) ; get ext and remove period
- outFileName := RegExReplace(in, regx) ; get name with ext
- nameLen := StrLen(outFileName) ; get length of name
- extLen := StrLen(outExt) ; get length of ext
- outNameNoExt := SubStr(outFileName, 1, nameLen - extLen - 1) ; get name w/o ext
- }
- ; This function converts a relative path to absolute
- GetFullName( fn ) {
- ; http://msdn.microsoft.com/en-us/library/Aa364963
- Static buf ;, i ; removing i from static because it needs to be reset from one call to the next
- ; If !i
- i := VarSetCapacity(buf, 512)
- DllCall("GetFullPathNameA", "str", fn, "uint", 512, "str", buf, "str*", 0)
- Return buf
- }
- ; Converts a relative path to an absolute one after providing the base path
- AbsoluteFromRelative(MasterPath, RelativePath)
- {
- VarSetCapacity(AbsP,260,0)
- DllCall( "shlwapi\PathCombineA", Str,AbsP, Str,MasterPath, Str,RelativePath )
- Return AbsP
- }
- ; FileGetVersionInfo_AW which gets file attributes
- FileGetVersionInfo_AW( peFile="", StringFileInfo="", Delimiter="|") {
- Static CS, HexVal, Sps=" ", DLL="Version\"
- If ( CS = "" )
- CS := A_IsUnicode ? "W" : "A", HexVal := "msvcrt\s" (A_IsUnicode ? "w": "" ) "printf"
- If ! FSz := DllCall( DLL "GetFileVersionInfoSize" CS , Str,peFile, UInt,0 )
- Return "", DllCall( "SetLastError", UInt,1 )
- VarSetCapacity( FVI, FSz, 0 ), VarSetCapacity( Trans,8 * ( A_IsUnicode ? 2 : 1 ) )
- DllCall( DLL "GetFileVersionInfo" CS, Str,peFile, Int,0, UInt,FSz, UInt,&FVI )
- If ! DllCall( DLL "VerQueryValue" CS, UInt,&FVI, Str,"\VarFileInfo\Translation", UIntP,Translation, UInt,0 )
- Return "", DllCall( "SetLastError", UInt,2 )
- If ! DllCall( HexVal, Str,Trans, Str,"%08X", UInt,NumGet(Translation+0) )
- Return "", DllCall( "SetLastError", UInt,3 )
- Loop, Parse, StringFileInfo, %Delimiter%
- { subBlock := "\StringFileInfo\" SubStr(Trans,-3) SubStr(Trans,1,4) "\" A_LoopField
- If ! DllCall( DLL "VerQueryValue" CS, UInt,&FVI, Str,SubBlock, UIntP,InfoPtr, UInt,0 )
- Continue
- Value := DllCall( "MulDiv", UInt,InfoPtr, Int,1, Int,1, "Str" )
- Info .= Value ? ( ( InStr( StringFileInfo,Delimiter ) ? SubStr( A_LoopField Sps,1,24 ) . A_Tab : "" ) . Value . Delimiter ) : ""
- } StringTrimRight, Info, Info, 1
- Return Info
- }
- GetOSVersion() {
- VarSetCapacity(v,148), NumPut(148,v)
- DllCall("GetVersionEx", "uint", &v)
- ; Return formatted version string similar to A_AhkVersion.
- ; Assume build number will never be more than 4 characters.
- return NumGet(v,4) ; major
- . "." NumGet(v,8) ; minor
- . "." SubStr("0000" NumGet(v,12), -3) ; build
- }
- ; Returns system paths
- ; For example, GetCommonPath("LOCAL_APPDATA") will return the full path to yout local appdata folder: C:\Users\NAME\AppData\Local
- GetCommonPath(csidl) {
- Static init
- If !init
- {
- CSIDL_APPDATA := 0x001A ; Application Data, new for NT4
- CSIDL_COMMON_APPDATA := 0x0023 ; All Users\Application Data
- CSIDL_COMMON_DOCUMENTS := 0x002e ; All Users\Documents
- CSIDL_DESKTOP := 0x0010 ; C:\Documents and Settings\username\Desktop
- CSIDL_FONTS := 0x0014 ; C:\Windows\Fonts
- CSIDL_LOCAL_APPDATA := 0x001C ; non roaming, user\Local Settings\Application Data
- CSIDL_MYMUSIC := 0x000d ; "My Music" folder
- CSIDL_MYPICTURES := 0x0027 ; My Pictures, new for Win2K
- CSIDL_PERSONAL := 0x0005 ; My Documents
- CSIDL_PROGRAM_FILES_COMMON := 0x002b ; C:\Program Files\Common
- CSIDL_PROGRAM_FILES := 0x0026 ; C:\Program Files
- CSIDL_PROGRAMS := 0x0002 ; C:\Documents and Settings\username\Start Menu\Programs
- CSIDL_RESOURCES := 0x0038 ; %windir%\Resources\, For theme and other windows resources.
- CSIDL_STARTMENU := 0x000b ; C:\Documents and Settings\username\Start Menu
- CSIDL_STARTUP := 0x0007 ; C:\Documents and Settings\username\Start Menu\Programs\Startup.
- CSIDL_SYSTEM := 0x0025 ; GetSystemDirectory()
- CSIDL_WINDOWS := 0x0024 ; GetWindowsDirectory()
- }
- val := CSIDL_%csidl%
- VarSetCapacity(fpath, 256)
- DllCall("shell32\SHGetFolderPathA", "uint", 0, "int", val, "uint", 0, "int", 0, "str", fpath)
- Return %fpath%
- }
- ; StrX function because some modules use it and Pause needs it for XML reading
- StrX( H, BS="",BO=0,BT=1, ES="",EO=0,ET=1, ByRef N="" ) {
- Return SubStr(H,P:=(((Z:=StrLen(ES))+(X:=StrLen(H))+StrLen(BS)-Z-X)?((T:=InStr(H,BS,0,((BO
- <0)?(1):(BO))))?(T+BT):(X+1)):(1)),(N:=P+((Z)?((T:=InStr(H,ES,0,((EO)?(P+1):(0))))?(T-P+Z
- +(0-ET)):(X+P)):(X)))-P)
- }
- HexCompareWrite(file,Pos,Value){
- If (value = "") {
- Log("HexCompareWrite - NULL value supplied",2)
- Return
- }
- curBin := BinRead(file,nvramData,1,Pos) ; read binary
- Bin2Hex(curHex,nvramData,curBin) ; convert to hex
- If (curHex != value) {
- Log("HexCompareWrite - Changing " . curHex . " to " . value . " in: " . file,4)
- Hex2Bin(binData,value)
- BinWrite(file,binData,1,Pos)
- }
- }
- i18n(key, defaultLocale = "English_United_States", p0 = "-0", p1 = "-0", p2 = "-0", p3 = "-0", p4 = "-0", p5 = "-0", p6 = "-0", p7 = "-0", p8 = "-0", p9 = "-0") {
- Global sysLang,langFile
- Log("i18n - Started",4)
- IniRead, phrase, %langFile%, %sysLang%, %key%
- If (phrase = "ERROR" || phrase = "")
- {
- ; Nothing found, test with generic language
- StringSplit, keyArray, sysLang, _
- Log("i18n - Section """ . sysLang . """ & key """ . key . """ not found, trying section """ . keyArray1 . """",4)
- IniRead, phrase, %langFile% , %keyArray1%, %key%
- If (phrase = "ERROR" || phrase = "")
- {
- Log("i18n - Section """ . keyArray1 . """ & key """ . key . """ not found, trying section """ . defaultLocale . """",4)
- ; Nothing found, test with default locale if one is provided
- If (defaultLocale != "")
- {
- IniRead, phrase, %langFile% , %defaultLocale%, %key%
- If (phrase = "ERROR" || phrase = "")
- {
- ; Nothing found, test with generic language for default locale as well
- StringSplit, keyArray, defaultLocale, _
- Log("i18n - Section """ . defaultLocale . """ & key """ . key . """ not found, trying section """ . keyArray1 . """",4)
- IniRead, phrase, %langFile% , %keyArray1%, %key%
- }
- }
- ; Nothing found return original value
- If (defaultLocale = "" || phrase = "ERROR" || phrase = "") {
- Log("i18n - Ended, no phrase found for """ . key . """ in language """ . sysLang . """. Using default """ . key . """",2)
- Return % key
- }
- }
- }
- StringReplace, phrase, phrase, `\n, `r`n, ALL
- StringReplace, phrase, phrase, `\t, % A_Tab, ALL
- Loop 10
- {
- idx := A_Index - 1
- IfNotEqual, p%idx%, -0
- phrase := RegExReplace(phrase, "\{" . idx . "\}", p%idx%)
- }
- Log("i18n - Ended, using """ . phrase . """ for """ . key . """",4)
- Return % phrase
- }
- ; Debug console handler
- DebugMessage(str) {
- Global rlTitle,rlVersion,rlDebugConsoleStdout
- If !rlDebugConsoleStdout
- DebugConsoleInitialize(rlDebugConsoleStdout, rlTitle . " v" . rlVersion . " Debug Console") ; start console window if not yet started
- str .= "`n" ; add line feed
- FileAppend %str%, CONOUT$
- ; FileAppend %str%`n, * ; Works with SciTE and similar editors.
- ; OutputDebug %str%`n ; Works with Visual Studio and DbgView.
- WinSet, Bottom,, ahk_id %rlDebugConsoleStdout% ; keep console on bottom
- }
- DebugConsoleInitialize(ByRef handle, title="") {
- ; two calls to open, no error check (it's debug, so you know what you are doing)
- DllCall("AttachConsole", int, -1, int)
- DllCall("AllocConsole", int)
- DllCall("SetConsoleTitle", "str", (If title ? title : a_scriptname)) ; Set the title
- handle := DllCall("GetStdHandle", "int", -11) ; get the handle
- WinSet, Bottom,, ahk_id %handle% ; make sure it's on the bottom
- Return
- }
- ;Sends a command to the active window using AHK key names. It will always send down/up keypresses for better compatibility
- ;A special command {Wait} can be used to force a sleep of the time defined by WaitTime
- ;WaitCommandOffset will affect all Wait events passed in the Command string by this amount
- SendCommand(Command, SendCommandDelay=2000, WaitTime=500, WaitBetweenSends=0, Delay=50, PressDuration=-1, WaitCommandOffset=0) {
- Log("SendCommand - Started")
- Log("SendCommand - Command: " . Command . "`r`n`t`t`t`t`tSendCommandDelay: " . SendCommandDelay . "`r`n`t`t`t`t`tWaitTime: " . WaitTime . "`r`n`t`t`t`t`tWaitBetweenSends: " . WaitBetweenSends . "`r`n`t`t`t`t`tDelay: " . Delay . "`r`n`t`t`t`t`tPressDuration: " . PressDuration . "`r`n`t`t`t`t`tWaitCommandOffset: " . WaitCommandOffset,4)
- ArrayCount := 0 ;Keeps track of how many items are in the array.
- InsideBrackets := 0 ;If 1 it means the current array item starts with {
- SavedKeyDelay := A_KeyDelay ;Saving previous key delay and setting the new one
- SetKeyDelay, %Delay%, %PressDuration%
- Sleep, %SendCommandDelay% ;Wait before starting to send any command
- ;Create an array with each command as an array element
- Loop, % StrLen(Command)
- { StrValue := SubStr(Command,A_Index,1)
- ; { StringMid, StrValue, Command, A_Index, 1
- If (StrValue != A_Space || InsideBrackets = 1) ; Spaces must be allowed when inside brackets so we can issue {Shift Down} for instance
- { If (InsideBrackets = 0)
- ArrayCount += 1
- If (StrValue = "{")
- { If (InsideBrackets = 1)
- ScriptError("Non-Matching brackets detected in the SendCommand parameter, please correct it")
- Else
- InsideBrackets := 1
- } Else If (StrValue = "}")
- { If (InsideBrackets = 0)
- ScriptError("Non-Matching brackets detected in the SendCommand parameter, please correct it")
- Else
- InsideBrackets := 0
- }
- Array%ArrayCount% := Array%ArrayCount% . StrValue ;Update the array data
- }
- }
- ;Loop through the array and send the commands
- Loop %ArrayCount%
- { element := Array%A_Index%
- If (WaitBetweenSends = 1)
- Sleep, %WaitTime%
- ;Particular cases check if the commands already come with down or up suffixes on them and if so send the commands directly without appending Up/Down
- If RegExMatch(element,"i)Down}")
- { If (element != "{Down}")
- { Send, %element%
- continue
- }
- }
- Else If RegExMatch(element,"i)Up}")
- { If (element != "{Up}")
- { Send, %element%
- Continue
- }
- }
- Else If (element = "{Wait}") ;Special non-ahk tag to issue a sleep
- { NewWaitTime := WaitTime + WaitCommandOffset
- Sleep, %NewWaitTime%
- Continue
- }
- Else If RegExMatch(element,"i)\{Wait:")
- { ;Wait for a specified amount of time {Wait:xxx}
- ; StringMid, NewWaitTime, element, 7, StrLen(element) - 7
- NewWaitTime := SubStr(element,7,StrLen(element) - 7)
- NewWaitTime := NewWaitTime + WaitCommandOffset
- Sleep, %NewWaitTime%
- Continue
- }
- ;the rest of the commands, send a keypress with down and up suffixes
- If RegExMatch(element,"}")
- { StrElement := SubStr(element,1,StrLen(element) - 1)
- ; { StringLeft, StrElement, element, StrLen(element) - 1
- Send, %StrElement% down}%StrElement% up}
- } Else
- Send, {%element% down}{%element% up}
- }
- ;Restore key delay values
- SetKeyDelay(SavedKeyDelay, -1)
- Log("SendCommand - Ended")
- }
- ; Purpose: Tell a ServoStik to transition to 4 or 8-way mode
- ; Parameters:
- ; direction = Can be 4 or 8, self-explanatory
- ServoStik(direction) {
- Log("ServoStik - Started")
- Global PacDriveDllFile,servoStikEnabled
- Static dllExists
- If !RegExMatch(direction,"4|8")
- {
- Log("ServoStik - """ . direction . """ is not a supported direction for ServoSticks. Only 4 and 8 are supported. Leaving your ServoStik as is.",2)
- Return
- }
- If !dllExists {
- CheckFile(pacDrivedllFile, "Following file is required for RocketLauncher ServoStik support, but could not be found:`n" . pacDrivedllFile)
- dllExists := 1 ; do not run this check again
- }
- pacDriveLoadModule := DllCall("LoadLibrary", "Str", PacDriveDllFile) ; Avoids the need for ahk to load and free the dll's library multiple times
- pacInitialize := DllCall(PacDriveDllFile . "\PacInitialize") ; Initialize all PacDrive, PacLED64 and U-HID Devices and return the amount connected to system
- If !pacInitialize {
- Log("ServoStik - No devices found on system",2)
- Log("ServoStik - Ended")
- Return
- } Else
- Log("ServoStik - " . pacInitialize . " devices found on system. If you have multiple devices, this should list more than one and may not specifically mean a ServoStik was found")
- result := DllCall(PacDriveDllFile . "\PacSetServoStik" . direction . "Way") ; Tell ServoStiks to change to desired direction
- If !result
- Log("ServoStik - There was a problem telling your ServoStik(s) to go " . direction . "-Way",3)
- Else
- Log("ServoStik - ServoStik(s) were told to go " . direction . "-Way")
- ; pacDriveUnloadModule := DllCall("FreeLibrary", "UInt", pacDriveLoadModule) ; To conserve memory, the DLL is unloaded after using it.
- Log("ServoStik - Ended")
- }
- GetTimeString(time) {
- If (time<0)
- Return time
- If time is not number
- Return time
- Days := time // 86400
- Hours := Mod(time, 86400) // 3600
- Minutes := Mod(time, 3600) // 60
- Seconds := Mod(time, 60)
- If (Days<>0) {
- If Strlen(Hours) = 1
- Hours = 0%Hours%
- If Strlen(Minutes) = 1
- Minutes = 0%Minutes%
- If Strlen(Seconds) = 1
- Seconds = 0%Seconds%
- TimeString = %Days%d %Hours%h %Minutes%m %Seconds%s
- } Else If (Hours<>0) {
- If Strlen(Minutes) = 1
- Minutes = 0%Minutes%
- If Strlen(Seconds) = 1
- Seconds = 0%Seconds%
- TimeString = %Hours%h %Minutes%m %Seconds%s
- } Else If (Minutes<>0) {
- If Strlen(Seconds) = 1
- Seconds = 0%Seconds%
- TimeString = %Minutes%m %Seconds%s
- } Else If (Seconds<>0)
- TimeString = %Seconds%s
- Else
- TimeString := ""
- Return TimeString
- }
- ReplaceFileNameInvalidChar(ByRef hastack,list,replaceChar){
- Loop, Parse, list, `,
- StringReplace, hastack, hastack, %a_loopfield%, %replaceChar%, All
- Return hastack
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;-------------------------------------------- RL Media Functions ---------------------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- rndRLMediaLogoPath(assetType){
- Global RLMedia, feMedia, gameInfo
- If !(RLMedia)
- RLMedia := loadRLMediaLogos(gameInfo)
- LogoImageList := []
- for index, element in RLMedia["Logos"]
- If (element.Label)
- If (element.AssetType=assetType)
- Loop, % element.TotalItems
- LogoImageList.Insert(element["Path" . a_index])
- If !(LogoImageList[1])
- for index, element in feMedia["Logos"]
- If (element.Label)
- If (element.AssetType=assetType)
- Loop, % element.TotalItems
- LogoImageList.Insert(element["Path" . a_index])
- If (LogoImageList[1]) {
- Random, RndmLogoImage, 1, % LogoImageList.MaxIndex()
- Return LogoImageList[RndmLogoImage]
- }
- }
- LoadRLMediaLogos(gameInfoObj){
- Global RLMediaPath, RLMedia, systemname, dbname, romTable, mgCandidate
- RLMedia := {}
- LogoList := "Genre|Rating|Developer|Publisher|Year"
- Loop, Parse, LogoList, |
- { If (gameInfoObj[A_LoopField].Value){
- %A_LoopField% := gameInfoObj[A_LoopField].Value
- If (A_LoopField = "Genre"){
- ReplaceFileNameInvalidChar(%A_LoopField%,"/,|","\") ;Replacing invalid file name characters by folder separator ("\")
- ReplaceFileNameInvalidChar(%A_LoopField%,"*","-") ;Replacing invalid file name characters by hippens ("-")
- } Else
- ReplaceFileNameInvalidChar(%A_LoopField%,"/,*,|","-") ;Replacing invalid file name characters by hippens ("-")
- ReplaceFileNameInvalidChar(%A_LoopField%,":"," - ") ;Replacing invalid file name characters by hippens ("-")
- ReplaceFileNameInvalidChar(%A_LoopField%,"?," . """" . ",<,>","") ;Replacing invalid file name characters by hippens ("-")
- %A_LoopField% :=RegExReplace(%A_LoopField%,"^\s+|\s+(?=\s)|\s$") ;remove double white spaces
- If (FileExist(RLMediaPath . "\" . A_LoopField . "\" . systemname . "\" . dbname . "\" . %A_LoopField% . ".*"))
- %A_LoopField%Path := RLMediaPath . "\" . A_LoopField . "\" . systemname . "\" . dbname . "\" . %A_LoopField% . ".*"
- Else If (FileExist(RLMediaPath . "\" . A_LoopField . "\" . systemname . "\_Default\" . %A_LoopField% . ".*"))
- %A_LoopField%Path := RLMediaPath . "\" . A_LoopField . "\" . systemname . "\_Default\" . %A_LoopField% . ".*"
- Else
- %A_LoopField%Path := RLMediaPath . "\" . A_LoopField . "\_Default\" . %A_LoopField% . ".*"
- }
- }
- RLMedia.Logos := BuildAssetsTable(GenrePath . "|" . RatingPath . "|" . DeveloperPath . "|" . PublisherPath . "|" . YearPath,"Genre Logo|Rating Logo|Developer Logo|Publisher Logo|Year Logo","genre|rating|developer|publisher|year","png|bmp|gif|jpg|tif")
- systemLogoPath := RLMediaPath . "\Logos\" . systemname . "\_Default\"
- gameLogoPath1 := RLMediaPath . "\Logos\" . systemname . "\" . dbname . "\"
- ;Description name without (Disc X)
- If (!romTable && mgCandidate)
- romTable := CreateRomTable(dbName)
- Totaldiscsofcurrentgame := romTable.MaxIndex()
- If (Totaldiscsofcurrentgame > 1) {
- DescriptionNameWithoutDisc := romTable[1,4]
- gameLogoPath2 := RLMediaPath . "\Logos\" . systemname . "\" . DescriptionNameWithoutDisc . "\"
- }
- RLMedia.Logos := BuildAssetsTable(systemLogoPath . "|" . gameLogoPath1 . "|" . gameLogoPath2,"System Logo|Game Logo|Game Logo","system|game|game","png|bmp|gif|jpg|tif",RLMedia.Logos)
- Return RLMedia
- }
- ; Inject a shared function for Pause and Fade which adjusts the background image positioning
- ; Usage, params 1-4 are byref so supply the var you want to be filled with the calculated positions and size. Next 2 are the original pics width and height. Last is the position the user wants.
- GetBGPicPosition(ByRef retX,ByRef retY,ByRef retW,ByRef retH,w,h,pos){
- Global baseScreenWidth, baseScreenHeight
- widthMaxPercent := ( baseScreenWidth / w ) ; get the percentage needed to maximumise the image so it reaches the screen's width
- heightMaxPercent := ( baseScreenHeight / h )
- If (pos = "Stretch and Lose Aspect") { ; image is stretched to screen, loosing aspect
- retW := baseScreenWidth
- retH := baseScreenHeight
- retX := 0
- retY := 0
- } Else If (pos = "Stretch and Keep Aspect") { ; image is stretched to Center screen, keeping aspect
- percentToEnlarge := If (widthMaxPercent < heightMaxPercent) ? widthMaxPercent : heightMaxPercent ; this basicallys says if the width's max reaches the screen's width first, use the width's percentage instead of the height's
- retW := Round(w * percentToEnlarge) ; multiply width by the percentage from above to reach as close to the edge as possible
- retH := Round(h * percentToEnlarge) ; multiply height by the percentage from above to reach as close to the edge as possible
- retX := ( baseScreenWidth / 2 ) - ( retW / 2 ) ; find where to place the X of the image
- retY := ( baseScreenHeight / 2 ) - ( retH / 2 ) ; find where to place the Y of the image
- } Else If (pos = "Center Width") { ; image is stretched to Center screen's width, keeping aspect
- percentToEnlarge := widthMaxPercent ; increase the image size by the percentage it takes to reaches the screen's width, cropping may occur on top and bottom
- retW := Round(w * percentToEnlarge) ; multiply width by the percentage from above to reach as close to the edge as possible
- retH := Round(h * percentToEnlarge) ; multiply height by the percentage from above to reach as close to the edge as possible
- retX := ( baseScreenWidth / 2 ) - ( retW / 2 ) ; find where to place the X of the image
- retY := ( baseScreenHeight / 2 ) - ( retH / 2 ) ; find where to place the Y of the image
- } Else If (pos = "Center Height") { ; image is stretched to Center screen's height, keeping aspect
- percentToEnlarge := heightMaxPercent ; increase the image size by the percentage it takes to reaches the screen's height, cropping may occur on left and right
- retW := Round(w * percentToEnlarge) ; multiply width by the percentage from above to reach as close to the edge as possible
- retH := Round(h * percentToEnlarge) ; multiply height by the percentage from above to reach as close to the edge as possible
- retX := ( baseScreenWidth / 2 ) - ( retW / 2 ) ; find where to place the X of the image
- retY := ( baseScreenHeight / 2 ) - ( retH / 2 ) ; find where to place the Y of the image
- } Else If (pos = "Center") { ; original image size and aspect
- retX := ( baseScreenWidth / 2 ) - ( w / 2 ) ; find where to place the X of the image
- retY := ( baseScreenHeight / 2 ) - ( h / 2 ) ; find where to place the Y of the image
- } Else If (pos = "Align to Bottom Left") { ; place the pic so the bottom left corner matches the screen's bottom left corner
- retH := baseScreenHeight
- retW := Round( w / ( h / baseScreenHeight ))
- If ( retW < baseScreenWidth ){
- retW := baseScreenWidth
- retH := Round( h / ( w / retW ))
- }
- retY := baseScreenHeight - retH
- } Else If (pos = "Align to Bottom Right") { ; place the pic so the bottom right corner matches the screen's bottom right corner
- retH := baseScreenHeight
- retW := Round( w / ( h / baseScreenHeight ))
- If ( retW < baseScreenWidth ){
- retW := baseScreenWidth
- retH := Round( h / ( w / retW ))
- }
- retX := baseScreenWidth - retW
- retY := baseScreenHeight - retH
- } Else If (pos = "Align to Top Right") { ; place the pic so the top right corner matches the screen's top right corner
- retH := baseScreenHeight
- retW := Round( w / ( h / baseScreenHeight ))
- If ( retW < baseScreenWidth ){
- retW := baseScreenWidth
- retH := Round( h / ( w / retW ))
- }
- retX := baseScreenWidth - retW
- } Else { ; place the pic so the top left corner matches the screen's top left corner, also the default
- retH := baseScreenHeight
- retW := Round( w / ( h / baseScreenHeight ))
- If ( retW < baseScreenWidth ){
- retW := baseScreenWidth
- retH := Round( h / ( w / retW ))
- }
- }
- }
- ; Usage, params 1&2 are byref so supply the var you want to be filled with the calculated positions. Next 4 are the original pics xy,w,h. Last is the position the user wants.
- GetFadePicPosition(ByRef retX, ByRef retY,x,y,w,h,pos){
- Global baseScreenWidth, baseScreenHeight
- If (pos = "Stretch and Lose Aspect"){ ; image is stretched to screen, loosing aspect
- retX := 0
- retY := 0
- } Else If (pos = "Stretch and Keep Aspect") { ; image is stretched to screen, keeping aspect
- retX := round(( baseScreenWidth / 2 ) - ( w / 2 ))
- retY := round(( baseScreenHeight / 2 ) - ( h / 2 ))
- } Else If (pos = "Center") {
- retX := round(( baseScreenWidth / 2 ) - ( w / 2 ))
- retY := round(( baseScreenHeight / 2 ) - ( h / 2 ))
- } Else If (pos = "Top Left Corner") {
- retX := 0
- retY := 0
- } Else If (pos = "Top Right Corner") {
- retX := baseScreenWidth - w
- retY := 0
- } Else If (pos = "Bottom Left Corner") {
- retX := 0
- retY := baseScreenHeight - h
- } Else If (pos = "Bottom Right Corner") {
- retX := baseScreenWidth - w
- retY := baseScreenHeight - h
- } Else If (pos = "Top Center") {
- retX := round(( baseScreenWidth / 2 ) - ( w / 2 ))
- retY := 0
- } Else If (pos = "Bottom Center") {
- retX := round(( baseScreenWidth / 2 ) - ( w / 2 ))
- retY := baseScreenHeight - h
- } Else If (pos = "Left Center") {
- retX := 0
- retY := round(( baseScreenHeight / 2 ) - ( h / 2 ))
- } Else If (pos = "Right Center") {
- retX := baseScreenWidth - w
- retY := round(( baseScreenHeight / 2 ) - ( h / 2 ))
- } Else {
- retX := x
- retY := y
- }
- }
- GetRLMediaFiles(mediaType,supportedFileTypes,returnArray=0) {
- Log("GetRLMediaFiles - Started",4)
- Global RLMediaPath,dbName,systemName,romTable,mgCandidate
- If (!romTable && mgCandidate)
- romTable:=CreateRomTable(dbName)
- DescriptionNameWithoutDisc := romTable[1,4]
- romFolder := RLMediaPath . "\" . mediaType . "\" . systemName . "\" . dbName . "\"
- romDisckLessFolder := RLMediaPath . "\" . mediaType . "\" . systemName . "\" . DescriptionNameWithoutDisc . "\"
- systemFolder := RLMediaPath . "\" . mediaType . "\" . systemName . "\_Default\"
- globalFolder := RLMediaPath . "\" . mediaType . "\_Default\"
- imagesArray := []
- Loop, Parse, supportedFileTypes, |
- If FileExist(romFolder . "*." . A_LoopField) {
- Loop % romFolder . "*." . A_LoopField
- imagesArray[A_Index] := A_LoopFileFullPath
- }
- If imagesArray.MaxIndex() <= 0
- Loop, Parse, supportedFileTypes, |
- If FileExist(romDisckLessFolder . "*." . A_LoopField) {
- Loop % romDisckLessFolder . "*." . A_LoopField
- imagesArray[A_Index] := A_LoopFileFullPath
- }
- If imagesArray.MaxIndex() <= 0
- Loop, Parse, supportedFileTypes, |
- If FileExist(systemFolder . "*." . A_LoopField) {
- Loop % systemFolder . "*." . A_LoopField
- imagesArray[A_Index] := A_LoopFileFullPath
- }
- If imagesArray.MaxIndex() <= 0
- Loop, Parse, supportedFileTypes, |
- If FileExist(globalFolder . "*." . A_LoopField) {
- Loop % globalFolder . "*." . A_LoopField
- imagesArray[A_Index] := A_LoopFileFullPath
- }
- If returnArray {
- Log("GetRLMediaFiles - Ended, returning array",4)
- Return imagesArray
- }
- Else {
- Random, RndmImagePic, 1, % imagesArray.MaxIndex()
- file := imagesArray[RndmImagePic]
- Log("GetRLMediaFiles - Ended, randomized RocketLauncher " . mediaType . " file selected: " . file)
- Return file
- }
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;----------------------------------------- DXWnd Functions -----------------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- ; If you provide a value, DxwndIniRW assumes you want to write to the ini
- ; If no value is provided, DxwndIniRW assumes you want to read from the ini and returns the value
- ; DxwndIniRW is only used to read and write settings to dxwnd.ini
- ; DxwndRun is for launching dxwnd
- ; DxwndClose is for closing dxwnd
- ; DxwndUpdateIniPath is for updating the dxwndIni variable
- DxwndIniRW(sec="",key="",val="", default="", cTarget="") {
- Log("DxwndIniRW - Started")
- Global dxwndIni,romName
- Static pos,iniExists
- If !iniExists {
- CheckFile(dxwndIni)
- iniExists := 1 ; do not run this check again
- }
- If !pos { ; the current romName or cTarget position has not been found, loop through the ini to find it first
- targetGame := If cTarget ? cTarget : romName
- Loop {
- pos := a_index-1
- IniRead, dxwndName, %dxwndIni%, target, title%pos%
- If (dxwndName = targetGame)
- Break
- If (dxwndName = "ERROR")
- ScriptError("There was a problem finding """ . targetGame . """ in the DXWnd Ini. Please make sure you have added this game to DXWnd before attempting to launch DXWnd through it.")
- }
- }
- errLvl := Process("Exist", "dxwnd.exe") ; Make sure dxwnd is not running first so settings don't get reverted
- If errLvl {
- DxwndClose()
- Process("WaitClose", "dxwnd.exe")
- }
- If val {
- IniWrite, %val%, %dxwndIni%, %sec%, %key%%pos%
- Log("DxwndIniRW - Wrote """ . val . """ to game #" . pos,4)
- } Else {
- IniRead, val, %dxwndIni%, %sec%, %key%%pos%
- Log("DxwndIniRW - Read """ . val . """",4)
- Log("DxwndIniRW - Ended")
- Return val
- }
- Log("DxwndIniRW - Ended")
- }
- DxwndRun(ByRef outPID="") {
- Log("DxwndRun - Started")
- Global dxwndFullPath,dxwndExe,dxwndPath,dxwndIni
- Static exeExists
- If !exeExists {
- CheckFile(dxwndFullPath, "Following file is required for DXWnd support, but its file could not be found:`n" . dxwndFullPath)
- exeExists := 1 ; do not run this check again
- }
- If !dxwndExe
- SplitPath, dxwndFullPath, dxwndExe, dxwndPath
- SplitPath, dxwndIni, dxwndIniFile
- Run(dxwndExe . " /T /C:""" . dxwndIniFile . """", dxwndPath, "Min", outPID)
- errLvl := Process("Wait", dxwndExe, 10) ; waiting 10 seconds for dxwnd to start
- If (errLvl = "")
- ScriptError("DXWnd did not start after waiting for 10 seconds. Please check you can run it manually and try again.")
- Else
- Log("DxwndRun - DxwndRun is now running")
- Log("DxwndRun - Ended")
- }
- DxwndClose() {
- Log("DxwndClose - Started")
- Global dxwndFullPath,dxwndExe,dxwndPath
- If !dxwndExe
- SplitPath, dxwndFullPath, dxwndExe, dxwndPath
- PostMessage, 0x111, 32810,,,ahk_exe %dxwndExe% ; this tells dxwnd to close itself
- Process("WaitClose", dxwndExe, 1) ; waits 1 second for dxwnd to close
- errLvl := Process("Exist", dxwndExe) ; checks if dxwnd is still running
- If errLvl
- Process("Close", dxwndExe) ; only needed when RocketLauncher is not ran as admin or RocketLauncher cannot close dxwnd for some reason
- Log("DxwndClose - Ended")
- }
- DxwndUpdateIniPath() {
- Global dxwndFullPath,dxwndPath,dxwndIni,systemName
- SplitPath,dxwndFullPath,,dxwndPath
- If FileExist( dxwndPath . "\" . systemName . ".ini" )
- dxwndIni := dxwndPath . "\" . systemName . ".ini"
- Else
- dxwndIni := dxwndPath . "\dxwnd.ini"
- Log("DxwndUpdateIniPath - DxwndIni set to " . dxwndIni)
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;----------------------------------- Cursor Control Functions ------------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- ToggleCursor:
- Log("ToggleCursor - Hotkey """ . toggleCursorKey . """ pressed, toggling cursor visibility")
- SystemCursor("Toggle")
- Return
- ; Function to hide/unhide the mouse cursor
- SystemCursor(OnOff=1) ; INIT = "I","Init"; OFF = 0,"Off"; TOGGLE = -1,"T","Toggle"; ON = others
- { Global mouseCursorHidden
- Static AndMask, XorMask, cursor, h_cursor
- ,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13 ; system cursors
- , b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13 ; blank cursors
- , h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,h12,h13 ; handles of default cursors
- If (OnOff = "Init" or OnOff = "I" or cursor = "") ; init when requested or at first call
- {
- cursor := "h" ; active default cursors
- VarSetCapacity( h_cursor,4444, 1 )
- VarSetCapacity( AndMask, 32*4, 0xFF )
- VarSetCapacity( XorMask, 32*4, 0 )
- system_cursors = 32512,32513,32514,32515,32516,32642,32643,32644,32645,32646,32648,32649,32650
- StringSplit c, system_cursors, `,
- Loop %c0%
- {
- h_cursor := DllCall( "LoadCursor", "uint",0, "uint",c%A_Index% )
- h%A_Index% := DllCall( "CopyImage", "uint",h_cursor, "uint",2, "int",0, "int",0, "uint",0 )
- b%A_Index% := DllCall("CreateCursor","uint",0, "int",0, "int",0
- , "int",32, "int",32, "uint",&AndMask, "uint",&XorMask )
- }
- }
- If (OnOff = 0 or OnOff = "Off" or cursor = "h" and (OnOff < 0 or OnOff = "Toggle" or OnOff = "T")){
- cursor := "b" ; use blank cursors
- Log("SystemCursor - Hiding mouse cursor")
- CoordMode, Mouse ; Also lets move it to the side since some emu's flash a cursor real quick even if we hide it.
- MouseMove, 0, 0, 0
- } Else {
- cursor := "h" ; use the saved cursors
- SPI_SETCURSORS := 0x57 ; Emergency restore cursor, just in case something goes wrong
- DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 )
- mouseCursorHidden := ""
- Log("SystemCursor - Restoring mouse cursor")
- }
- Loop %c0%
- {
- h_cursor := DllCall( "CopyImage", "uint",%cursor%%A_Index%, "uint",2, "int",0, "int",0, "uint",0 )
- DllCall( "SetSystemCursor", "uint",h_cursor, "uint",c%A_Index% )
- }
- }
- SetSystemCursor( Cursor = "", cx = 0, cy = 0 ) {
- BlankCursor := 0, SystemCursor := 0, FileCursor := 0 ; init
- SystemCursors = 32512IDC_ARROW,32513IDC_IBEAM,32514IDC_WAIT,32515IDC_CROSS
- ,32516IDC_UPARROW,32640IDC_SIZE,32641IDC_ICON,32642IDC_SIZENWSE
- ,32643IDC_SIZENESW,32644IDC_SIZEWE,32645IDC_SIZENS,32646IDC_SIZEALL
- ,32648IDC_NO,32649IDC_HAND,32650IDC_APPSTARTING,32651IDC_HELP
- If (Cursor = "") ; empty, so create blank cursor
- {
- Log("SetSystemCursor - Creating blank cursor",4)
- VarSetCapacity( AndMask, 32*4, 0xFF ), VarSetCapacity( XorMask, 32*4, 0 )
- BlankCursor := 1 ; flag for later
- }
- Else If SubStr( Cursor,1,4 ) = "IDC_" ; load system cursor
- {
- Log("SetSystemCursor - Loading system cursor",4)
- Loop, Parse, SystemCursors, `,
- {
- CursorName := SubStr( A_Loopfield, 6, 15 ) ; get the cursor name, no trailing space with substr
- CursorID := SubStr( A_Loopfield, 1, 5 ) ; get the cursor id
- SystemCursor := 1
- If ( CursorName = Cursor ) {
- CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID )
- Break
- }
- }
- If (CursorHandle = "") ; invalid cursor name given
- {
- Log("SetSystemCursor - Invalid cursor name supplied: """ . CursorHandle . """",2)
- ; Msgbox,, SetCursor, Error: Invalid cursor name
- CursorHandle := "Error"
- }
- }
- Else If FileExist( Cursor )
- {
- Log("SetSystemCursor - Found this cursor: """ . Cursor . """",4)
- SplitPath, Cursor,,, Ext ; auto-detect type
- If (Ext = "ico")
- uType := 0x1
- Else If RegExMatch("cur|ani","i)" . Ext)
- uType := 0x2
- Else ; invalid file ext
- {
- Log("SetSystemCursor - Invalid cursor extension: """ . Ext . """",2)
- ; Msgbox,, SetCursor, Error: Invalid file type
- CursorHandle := "Error"
- }
- FileCursor := 1
- }
- Else
- {
- Log("SetSystemCursor - Invalid cursor name or path: """ . Cursor . """",2)
- ; Msgbox,, SetCursor, Error: Invalid file path or cursor name
- CursorHandle := "Error" ; raise for later
- }
- If (CursorHandle != "Error")
- {
- Loop, Parse, SystemCursors, `,
- {
- If (BlankCursor = 1)
- {
- Type := "BlankCursor"
- %Type%%A_Index% := DllCall( "CreateCursor", Uint,0, Int,0, Int,0, Int,32, Int,32, Uint,&AndMask, Uint,&XorMask )
- CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 )
- DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) )
- }
- Else If (SystemCursor = 1)
- {
- Type := "SystemCursor"
- CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID )
- %Type%%A_Index% := DllCall( "CopyImage", Uint,CursorHandle, Uint,0x2, Int,cx, Int,cy, Uint,0 )
- CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 )
- DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) )
- }
- Else If (FileCursor = 1)
- {
- Type := "FileCursor"
- %Type%%A_Index% := DllCall( "LoadImage", UInt,0, Str,Cursor, UInt,uType, Int,cx, Int,cy, UInt,0x10 )
- DllCall( "SetSystemCursor", Uint,%Type%%A_Index%, Int,SubStr( A_Loopfield, 1, 5 ) )
- }
- }
- }
- }
- RestoreCursors() {
- SPI_SETCURSORS := 0x57
- DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 )
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;------------------ Read and Write Wrapper Functions for IniFileEdit ------------------
- ;-------------------------------------------------------------------------------------------------------------
- ; Usage - Read and Write to config files that are not valid inis with [sections], like RetroArch's cfg
- ; cfgFile - path to the file to read, only need to send this once, it stays in memory until SavePropertiesCfg is used
- ; Returns a reference number to the array where the cfg is stored in memory so multiple files can be edited at once
- LoadProperties(cfgFile) {
- Log("LoadProperties - Started and loading this cfg into memory: " . cfgFile,4)
- cfgtable := Object()
- Loop, Read, %cfgFile% ; This loop retrieves each line from the file, one at a time.
- cfgtable.Insert(A_LoopReadLine) ; Append this line to the array.
- Log("LoadProperties - Ended",4)
- Return cfgtable
- }
- ; cfgFile - path to the file to read, only need to send this once, it stays in memory until SavePropertiesCfg is used
- ; cfgArray - reference number of array in memory that should be saved to the cfgFile
- SaveProperties(cfgFile,cfgArray) {
- Log("SaveProperties - Started and saving this cfg to disk: " . cfgFile,4)
- FileDelete, %cfgFile%
- Loop % cfgArray.MaxIndex()
- { element := cfgArray[A_Index]
- trimmedElement := LTrim(element)
- finalCfg .= trimmedElement . "`n"
- }
- FileAppend, %finalCfg%, %cfgFile%
- Log("SaveProperties - Ended",4)
- }
- ; cfgArray - reference number of array in memory that you want to read
- ; keyName = key whose value you want to read
- ; Separator = the separator to use, defaults to =
- ReadProperty(cfgArray,keyName,Separator="=") {
- Log("ReadProperty - Started",4)
- Loop % cfgArray.MaxIndex()
- { element := cfgArray[A_Index]
- trimmedElement := Trim(element)
- ;MsgBox % "Element number " . A_Index . " is " . element
- StringGetPos, pos, trimmedElement, [
- If (pos = 0)
- Break ; Section was found, do not search anymore, global section has ended
- If element contains %Separator%
- { StringSplit, keyValues, element, %Separator%
- CfgValue := Trim(keyValues1)
- If (CfgValue = keyName)
- Return Trim(keyValues2) ; Found it & trim any whitespace
- }
- }
- Log("ReadProperty - Ended",4)
- }
- ; cfgArray - reference number of array in memory that you want to read
- ; keyName = key whose value you want to write
- ; Value = value that you want to write to the keyName
- ; AddSpaces = If the seperator (=) has spaces on either side, set this parameter to 1 and it will wrap the seperator in spaces
- ; AddQuotes = If the Value needs to be wrapped in double quotes (like in retroarch's config), set this parameter to 1
- ; Separator = the separator to use, defaults to =
- WriteProperty(cfgArray,keyName,Value,AddSpaces=0,AddQuotes=0,Separator="=") {
- added := 0
- Loop % cfgArray.MaxIndex()
- { lastIndex := A_Index
- element := cfgArray[A_Index]
- trimmedElement := Trim(element)
- StringGetPos, pos, trimmedElement, [
- If (pos = 0)
- { lastIndex := lastIndex - 1 ; Section was found, do not search anymore
- Break
- }
- If element contains %Separator%
- { StringSplit, keyValues, element, %Separator%
- CfgValue := Trim(keyValues1)
- If (CfgValue = keyName)
- { cfgArray[A_Index] := CfgValue . (If AddSpaces=1 ? (" " . Separator . " ") : Separator) . (If AddQuotes=1 ? ("""" . Value . """") : Value) ; Found it
- added := 1
- Break
- }
- }
- }
- If (added = 0)
- cfgArray.Insert(lastIndex+1, keyName . (If AddSpaces=1 ? (" " . Separator . " ") : Separator) . (If AddQuotes=1 ? ("""" . Value . """") : Value)) ; Add the new entry to the file
- Log("WriteProperty - Writing - " . keyName . ": " . value,4)
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;----------------------------------------- Player Select Menu --------------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- ; function to create a small menu with the number of players option
- NumberOfPlayersSelectionMenu(maxPlayers=4) {
- Global screenRotationAngle,baseScreenWidth,baseScreenHeight,xTranslation,yTranslation
- Global navSelectKey,navUpKey,navDownKey,navP2SelectKey,navP2UpKey,navP2DownKey,exitEmulatorKey,exitEmulatorKey
- Global keymapper,keymapperEnabled,keymapperRocketLauncherProfileEnabled
- If !pToken
- pToken := Gdip_Startup()
- Gdip_Alt_GetRotatedDimensions(A_ScreenWidth, A_ScreenHeight, screenRotationAngle, baseScreenWidth, baseScreenHeight)
- Gdip_GetRotatedTranslation(baseScreenWidth, baseScreenHeight, screenRotationAngle, xTranslation, yTranslation)
- xTranslation:=round(xTranslation), yTranslation:=round(yTranslation)
- Loop, 2 {
- Gui, playersMenu_GUI%A_Index%: +Disabled -Caption +E0x80000 +OwnDialogs +LastFound +ToolWindow +AlwaysOnTop
- Gui, playersMenu_GUI%A_Index%: Margin,0,0
- Gui, playersMenu_GUI%A_Index%: Show,, playersMenuLayer%A_Index%
- playersMenu_hwnd%A_Index% := WinExist()
- playersMenu_hbm%A_Index% := CreateDIBSection(A_ScreenWidth, A_ScreenHeight)
- playersMenu_hdc%A_Index% := CreateCompatibleDC()
- playersMenu_obm%A_Index% := SelectObject(playersMenu_hdc%A_Index%, playersMenu_hbm%A_Index%)
- playersMenu_G%A_Index% := Gdip_GraphicsFromhdc(playersMenu_hdc%A_Index%)
- Gdip_SetSmoothingMode(playersMenu_G%A_Index%, 4)
- Gdip_TranslateWorldTransform(playersMenu_G%A_Index%, xTranslation, yTranslation)
- Gdip_RotateWorldTransform(playersMenu_G%A_Index%, screenRotationAngle)
- }
- ;Initializing parameters
- playersMenuTextFont := "Bebas Neue"
- CheckFont(playersMenuTextFont)
- playersMenuSelectedTextSize := 50
- playersMenuSelectedTextColor := "FFFFFFFF"
- playersMenuDisabledTextColor := "FFAAAAAA"
- playersMenuDisabledTextSize := 30
- playersMenuMargin := 50
- playersMenuSpaceBtwText := 30
- playersMenuCornerRadius := 10
- ;menu scalling factor
- XBaseRes := 1920, YBaseRes := 1080
- If (((A_screenWidth < A_screenHeight) and ((screenRotationAngle=0) or (screenRotationAngle=180))) or ((A_screenWidth > A_screenHeight) and ((screenRotationAngle=90) or (screenRotationAngle=270))))
- XBaseRes := 1080, YBaseRes := 1920
- If !playersMenuXScale
- playersMenuXScale := baseScreenWidth/XBaseRes
- If !playersMenuYScale
- playersMenuYScale := baseScreenHeight/YBaseRes
- OptionScale(playersMenuSelectedTextSize, playersMenuYScale)
- OptionScale(playersMenuDisabledTextSize, playersMenuYScale)
- OptionScale(playersMenuMargin, playersMenuXScale)
- OptionScale(playersMenuSpaceBtwText, playersMenuYScale)
- OptionScale(playersMenuCornerRadius, playersMenuXScale)
- playersMenuW := MeasureText("X Players", "Left r4 s" . playersMenuSelectedTextSize . " Bold",playersMenuTextFont) + 2*playersMenuMargin
- playersMenuH := maxPlayers*playersMenuSelectedTextSize + (maxPlayers-1)*playersMenuSpaceBtwText + 2*playersMenuMargin
- playersMenuX := (baseScreenWidth-playersMenuW)//2
- playersMenuY := (baseScreenHeight-playersMenuH)//2
- playersMenuBackgroundBrush := Gdip_BrushCreateSolid("0xDD000000")
- pGraphUpd(playersMenu_G1,playersMenuW,playersMenuH)
- pGraphUpd(playersMenu_G2,playersMenuW,playersMenuH)
- ;Drawing Background
- Gdip_Alt_FillRoundedRectangle(playersMenu_G1, playersMenuBackgroundBrush, 0, 0, playersMenuW, playersMenuH,playersMenuCornerRadius)
- Alt_UpdateLayeredWindow(playersMenu_hwnd1, playersMenu_hdc1, playersMenuX, playersMenuY, playersMenuW, playersMenuH)
- ;Drawing choice list
- SelectedNumberofPlayers := 1
- gosub, DrawPlayersSelectionMenu
- ;Enabling Keys
- If (keymapperEnabled = "true") and (keymapperRocketLauncherProfileEnabled = "true")
- RunKeymapper%zz%("menu",keymapper)
- If keymapperAHKMethod = External
- RunAHKKeymapper%zz%("menu")
- Gosub, EnablePlayersMenuKeys
- LEDBlinky("RL") ; trigger ledblinky profile change if enabled
- ;Waiting for menu to exit
- Loop
- { If PlayersMenuExit
- Break
- Sleep, 100
- }
- LEDBlinky("ROM") ; trigger ledblinky profile change if enabled
- Return SelectedNumberofPlayers
- ;labels to treat menu changes
- DrawPlayersSelectionMenu:
- currentY := 0
- Gdip_GraphicsClear(playersMenu_G2)
- Loop, % maxPlayers
- {
- If (a_index=SelectedNumberofPlayers) {
- currentTextSize := playersMenuSelectedTextSize
- currentTextColor := playersMenuSelectedTextColor
- currentTextStyle := "bold"
- } Else {
- currentTextSize := playersMenuDisabledTextSize
- currentTextColor := playersMenuDisabledTextColor
- currentTextStyle := "normal"
- }
- If (a_index=1)
- currentText := "1 Player"
- Else
- currentText := a_index . " Players"
- currentY := playersMenuMargin + (a_index-1)*(playersMenuSelectedTextSize+playersMenuSpaceBtwText)+(playersMenuSelectedTextSize-currentTextSize)//2
- Gdip_Alt_TextToGraphics(playersMenu_G2, currentText, "x0 y" . currentY . " Center c" . currentTextColor . " r4 s" . currentTextSize . " " . currentTextStyle, playersMenuTextFont, playersMenuW, playersMenuSelectedTextSize)
- }
- Alt_UpdateLayeredWindow(playersMenu_hwnd2, playersMenu_hdc2, playersMenuX, playersMenuY, playersMenuW, playersMenuH)
- Return
- EnablePlayersMenuKeys:
- XHotKeywrapper(navSelectKey,"PlayersMenuSelect","ON")
- XHotKeywrapper(navUpKey,"PlayersMenuUP","ON")
- XHotKeywrapper(navDownKey,"PlayersMenuDown","ON")
- XHotKeywrapper(navP2SelectKey,"PlayersMenuSelect","ON")
- XHotKeywrapper(navP2UpKey,"PlayersMenuUP","ON")
- XHotKeywrapper(navP2DownKey,"PlayersMenuDown","ON")
- XHotKeywrapper(exitEmulatorKey,"CloseProcess","OFF")
- XHotKeywrapper(exitEmulatorKey,"ClosePlayersMenu","ON")
- Return
- DisablePlayersMenuKeys:
- XHotKeywrapper(navSelectKey,"PlayersMenuSelect","OFF")
- XHotKeywrapper(navUpKey,"PlayersMenuUP","OFF")
- XHotKeywrapper(navDownKey,"PlayersMenuDown","OFF")
- XHotKeywrapper(navP2SelectKey,"PlayersMenuSelect","OFF")
- XHotKeywrapper(navP2UpKey,"PlayersMenuUP","OFF")
- XHotKeywrapper(navP2DownKey,"PlayersMenuDown","OFF")
- XHotKeywrapper(exitEmulatorKey,"ClosePlayersMenu","OFF")
- XHotKeywrapper(exitEmulatorKey,"CloseProcess","ON")
- Return
- PlayersMenuUP:
- SelectedNumberofPlayers--
- If (SelectedNumberofPlayers<1)
- SelectedNumberofPlayers:=maxPlayers
- gosub, DrawPlayersSelectionMenu
- Return
- PlayersMenuDown:
- SelectedNumberofPlayers++
- If (SelectedNumberofPlayers>maxPlayers)
- SelectedNumberofPlayers:=1
- gosub, DrawPlayersSelectionMenu
- Return
- ClosePlayersMenu:
- ClosedPlayerMenu := true
- PlayersMenuSelect:
- Gosub, DisablePlayersMenuKeys
- Gdip_DeleteBrush(playersMenuBackgroundBrush)
- Loop, 2 {
- SelectObject(playersMenu_hdc%A_Index%, playersMenu_obm%A_Index%)
- DeleteObject(playersMenu_hbm%A_Index%)
- DeleteDC(playersMenu_hdc%A_Index%)
- Gdip_DeleteGraphics(playersMenu_G%A_Index%)
- Gui, playersMenu_GUI%A_Index%: Destroy
- }
- If ClosedPlayerMenu
- { Log("User cancelled the launch at the Player Select Menu")
- PlayersMenuExit := true
- ExitModule()
- } Else
- Log("Number of Players Selected: " . SelectedNumberofPlayers)
- If (keymapperEnabled = "true") and (keymapperRocketLauncherProfileEnabled = "true")
- RunKeymapper%zz%("load", keymapper)
- If keymapperAHKMethod = External
- RunAHKKeymapper%zz%("load")
- PlayersMenuExit := true
- Return
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;----------------------------------------- HideEmu Functions ---------------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- ; Default is 2ms so it picks up windows as soon as possible
- HideEmuStart(ms=2) {
- Global hideEmu
- Global hideEmuObj
- If (hideEmu = "true")
- { Log("HideEmuStart - Starting HideEmuTimer, scanning for windows defined in hideEmuObj every " . ms . "ms")
- ; First rebuild the single line object into a better one that's easier to track and work with
- newObject := Object()
- For key, value in hideEmuObj
- { currentObj++
- newObject[currentObj,"window"] := key
- newObject[currentObj,"method"] := value
- newObject[currentObj,"status"] := "" ; default is 0 (0 = not hidden yet, 1 = hidden already)
- }
- hideEmuObj := newObject ; overwrite hideEmuObj with the updated one
- ; SetTimer, HideEmuTimer, %ms%
- SetTimerF("HideEmuTimer",ms,hideEmuObj,10) ;create a higher priority timer
- Log("HideEmuStart - Ended")
- }
- }
- HideEmuEnd() {
- Global hideEmu
- Global hideEmuObj
- If (hideEmu = "true")
- { Log("HideEmuEnd - Stopping HideEmuTimer and unhiding flagged windows",4)
- ; SetTimer, HideEmuTimer, Off
- SetTimerF("HideEmuTimer","off")
- For key, value in hideEmuObj
- If (hideEmuObj[A_Index,"method"] && hideEmuObj[A_Index,"status"]) { ; if one of the windows was hidden and needs to be unhidden
- WinSet, Transparent, Off, % hideEmuObj[A_Index,"window"]
- Log("HideEmu - Revealed window: " . hideEmuObj[A_Index,"window"],4)
- }
- Log("HideEmuEnd - Ended",4)
- }
- }
- HideEmuTimer(obj) {
- Log("HideEmuTimer",3)
- For key, value in obj
- { If !obj[A_Index,"status"]
- { If (A_DetectHiddenWindows != "On")
- DetectHiddenWindows, On
- ; msgbox % obj[A_Index,"window"]
- If WinExist(obj[A_Index,"window"])
- { WinSet, Transparent, 0, % obj[A_Index,"window"]
- Log("HideEmu - Found a new window to hide: " . obj[A_Index,"window"],4)
- WinGet, currentTran, Transparent, % obj[A_Index,"window"]
- If (currentTran = 0)
- obj[A_Index,"status"] := 1 ; update object that this window is now hidden
- }
- }
- }
- Return
- }
- HideEmuTimer:
- For key, value in hideEmuObj
- { If !hideEmuObj[A_Index,"status"]
- { If (A_DetectHiddenWindows != "On")
- DetectHiddenWindows, On
- If WinExist(hideEmuObj[A_Index,"window"])
- { WinSet, Transparent, 0, % hideEmuObj[A_Index,"window"]
- Log("HideEmu - Found a new window to hide: " . hideEmuObj[A_Index,"window"],4)
- WinGet, currentTran, Transparent, % hideEmuObj[A_Index,"window"]
- If (currentTran = 0)
- hideEmuObj[A_Index,"status"] := 1 ; update object that this window is now hidden
- }
- }
- }
- Return
- SetTimerF( Function, Period=0, ParmObject=0, Priority=0 ) {
- Static current,tmrs:=[] ;current will hold timer that is currently running
- If IsFunc( Function ) {
- If IsObject(tmr:=tmrs[Function]) ;destroy timer before creating a new one
- ret := DllCall( "KillTimer", UInt,0, PTR, tmr.tmr)
- , DllCall("GlobalFree", PTR, tmr.CBA)
- , tmrs.Remove(Function)
- If (Period = 0 || Period = "off")
- Return ret ;Return as we want to turn off timer
- ; create object that will hold information for timer, it will be passed trough A_EventInfo when Timer is launched
- tmr:=tmrs[Function]:={func:Function,Period:Period="on" ? 250 : Period,Priority:Priority
- ,OneTime:Period<0,params:IsObject(ParmObject)?ParmObject:Object()
- ,Tick:A_TickCount}
- tmr.CBA := RegisterCallback(A_ThisFunc,"F",4,&tmr)
- Return !!(tmr.tmr := DllCall("SetTimer", PTR,0, PTR,0, UInt
- , (Period && Period!="On") ? Abs(Period) : (Period := 250)
- , PTR,tmr.CBA,"PTR")) ;Create Timer and return true if a timer was created
- , tmr.Tick:=A_TickCount
- }
- tmr := Object(A_EventInfo) ;A_Event holds object which contains timer information
- If IsObject(tmr) {
- DllCall("KillTimer", PTR,0, PTR,tmr.tmr) ;deactivate timer so it does not run again while we are processing the function
- If (current && tmr.Priority<current.priority) ;Timer with higher priority is already current so return
- Return (tmr.tmr:=DllCall("SetTimer", PTR,0, PTR,0, UInt, 100, PTR,tmr.CBA,"PTR")) ;call timer again asap
- current:=tmr
- ,tmr.tick:=ErrorLevel :=Priority ;update tick to launch function on time
- ,tmr.func(tmr.params*) ;call function
- If (tmr.OneTime) ;One time timer, deactivate and delete it
- Return DllCall("GlobalFree", PTR,tmr.CBA)
- ,tmrs.Remove(tmr.func)
- tmr.tmr:= DllCall("SetTimer", PTR,0, PTR,0, UInt ;reset timer
- ,((A_TickCount-tmr.Tick) > tmr.Period) ? 0 : (tmr.Period-(A_TickCount-tmr.Tick)), PTR,tmr.CBA,"PTR")
- current= ;reset timer
- }
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;---------------------------------------- Decryption Functions -------------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- Decrypt(T,key) ; Text, key-name
- {
- Local p, i, L, u, v, k5, a, c
- StringLeft p, T, 8
- If p is not xdigit ; if no IV: Error
- {
- ErrorLevel := 1
- Return
- }
- StringTrimLeft T, T, 8 ; remove IV from text (no separator)
- k5 = 0x%p% ; set new IV
- p := 0 ; counter to be Encrypted
- i := 9 ; pad-index, force restart
- L := "" ; processed text
- k0 := %key%0
- k1 := %key%1
- k2 := %key%2
- k3 := %key%3
- Loop % StrLen(T)
- {
- i++
- IfGreater i,8, { ; all 9 pad values exhausted
- u := p
- v := k5 ; IV
- p++ ; increment counter
- TEA(u,v, k0,k1,k2,k3)
- Stream9(u,v) ; 9 pads from Encrypted counter
- i := 0
- }
- StringMid c, T, A_Index, 1
- a := Asc(c)
- if a between 32 and 126
- { ; chars > 126 or < 31 unchanged
- a -= s%i%
- IfLess a, 32, SetEnv, a, % a+95
- c := Chr(a)
- }
- L := L . c ; attach Encrypted character
- }
- Return L
- }
- TEA(ByRef y,ByRef z,k0,k1,k2,k3) ; (y,z) = 64-bit I/0 block
- { ; (k0,k1,k2,k3) = 128-bit key
- IntFormat := A_FormatInteger
- SetFormat Integer, D ; needed for decimal indices
- s := 0
- d := 0x9E3779B9
- Loop 32
- {
- k := "k" . s & 3 ; indexing the key
- y := 0xFFFFFFFF & (y + ((z << 4 ^ z >> 5) + z ^ s + %k%))
- s := 0xFFFFFFFF & (s + d) ; simulate 32 bit operations
- k := "k" . s >> 11 & 3
- z := 0xFFFFFFFF & (z + ((y << 4 ^ y >> 5) + y ^ s + %k%))
- }
- SetFormat Integer, %IntFormat%
- y += 0
- z += 0 ; Convert to original ineger format
- }
- Stream9(x,y) ; Convert 2 32-bit words to 9 pad values
- { ; 0 <= s0, s1, ... s8 <= 94
- Local z ; makes all s%i% global
- s0 := Floor(x*0.000000022118911147) ; 95/2**32
- Loop 8
- {
- z := (y << 25) + (x >> 7) & 0xFFFFFFFF
- y := (x << 25) + (y >> 7) & 0xFFFFFFFF
- x := z
- s%A_Index% := Floor(x*0.000000022118911147)
- }
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;------------------------------------ Registry Access Functions ----------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- RegRead(RootKey, SubKey, ValueName = "", RegistryVersion="32")
- { Global winVer
- Log("RegRead - Reading from Registry : RootKey=" . RootKey . ", SubKey=" . SubKey . ", ValueName=" . ValueName . ",RegistryVersion=" . RegistryVersion, 4)
- If (RegistryVersion = "Auto") ;Try finding the correct registry reading based on the windows version
- {
- If (winVer = "64")
- If !OutputVar := RegRead(RootKey, SubKey, ValueName, "64")
- OutputVar := RegRead(RootKey, SubKey, ValueName, "32")
- Else
- OutputVar := RegRead(RootKey, SubKey, ValueName)
- }
- Else If (RegistryVersion = "32")
- RegRead, OutputVar, %RootKey%, %SubKey%, %ValueName%
- Else
- OutputVar := RegRead64(RootKey, SubKey, ValueName)
- Log("RegRead - Registry Read finished, returning " . OutputVar, 4)
- Return OutputVar
- }
- RegWrite(ValueType, RootKey, SubKey, ValueName = "", Value = "", RegistryVersion="32")
- {
- Log("RegWrite - Writing to Registry : RootKey=" . RootKey . ", SubKey=" . SubKey . ", ValueName=" . ValueName . ",Value=" . Value . ",ValueType=" . ValueType . ",RegistryVersion=" . RegistryVersion, 4)
- If (RegistryVersion = "32")
- RegWrite, %ValueType%, %RootKey%, %SubKey%, %ValueName%, %Value%
- Else
- RegWrite64(ValueType, RootKey, SubKey, ValueName, Value)
- Log("RegWrite - Registry Write finished", 4)
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;----------------------------------------- Display Resolution Functions ----------------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- ; Grab current display settings for each monitor
- ; Returns object:
- ; obj[#] = Display Number
- ; obj[#].Name = Display's Name as known in windows. Ex: \\.\DISPLAY1
- ; obj[#].Width = Display's Width
- ; obj[#].Height = Display's Height
- ; obj[#].BitDepth = Display's BitDepth
- ; obj[#].Frequency = Display's Frequency
- ; obj[#].Orientation = Display's Orientation
- ; obj[#].Left = Where this display's Left position starts
- ; obj[#].Right = Where this display's Right position ends
- ; obj[#].Top = Where this display's Top position starts
- ; obj[#].Bottom = Where this display's Bottom position ends
- ; obj[#].WorkingWidth = Display's Working Width. This is the usable space w/o the task bar
- ; obj[#].WorkingHeight = Display's Working Height
- GetDisplaySettings() {
- Global RLObject
- obj := Object()
- monOrientation := Object(0,"Landscape",1,"Portrait",2,"Landscape (Flipped)",3,"Portrait (Flipped)")
- getDisplaySettingsObj := Object(1,"Width",2,"Height",3,"BitDepth",4,"Frequency",5,"Orientation")
- SysGet, MonitorCount, 80 ; MonitorCount
- SysGet, MonitorPrimary, MonitorPrimary
- Loop, %MonitorCount% ; get each monitor's stats for the log
- {
- SysGet, MonitorName, MonitorName, %A_Index%
- SysGet, Monitor, Monitor, %A_Index%
- SysGet, MonitorWorkArea, MonitorWorkArea, %A_Index%
- currentobj:={}
- currentobj.Number := A_Index ; this is the monitor #, an integer
- currentobj.Name := MonitorName ; store monitor's name as it is known as in Windows
- monDetails := RL_getDisplaySettings(MonitorName) ; return 0 if something went wrong, like an invalid displayName is passed. Otherwise it returns a string with this format "width|height|bits|frequency|orientation"
- Loop, Parse, monDetails, |
- currentObj[getDisplaySettingsObj[A_Index]] := A_LoopField ; parse RLObject's return and store into the object
- currentobj.Orientation := monOrientation[currentobj.Orientation] ; replace orientation integer with name from object instead
- currentobj.Left := MonitorLeft ; store where this monitor's Left position starts
- currentobj.Right := MonitorRight ; store where this monitor's Right position ends
- currentobj.Top := MonitorTop ; store where this monitor's Top position starts
- currentobj.Bottom := MonitorBottom ; store where this monitor's Bottom position ends
- currentobj.WorkingWidth := MonitorWorkAreaRight - MonitorWorkAreaLeft ; store this monitor's working width
- currentobj.WorkingHeight := MonitorWorkAreaBottom - MonitorWorkAreaTop ; store this monitor's working height
- obj.Insert(currentobj["Number"], currentobj)
- Log("GetDisplaySettings - Monitor #" . A_Index . " (" . MonitorName . "): " . MonitorRight - MonitorLeft . "x" . MonitorBottom - MonitorTop . " (" . MonitorWorkAreaRight - MonitorWorkAreaLeft . "x" . MonitorWorkAreaBottom - MonitorWorkAreaTop . " work) [" . currentobj.BitDepth . "bit] [" . currentobj.Frequency . "hz] [" . currentobj.Orientation . "] " . (If MonitorPrimary = A_Index ? " (Primary)" : ""),4)
- }
- Return obj
- }
- ; This function will take the | delimited user settings from theses places:
- ; A) RLUI for all monitor/resolution settings and break it apart so it can be used in the various display functions then sent to the DLL
- ; B) Module when called to change the display setting(s)
- ; It supports multiple monitors and parameters for each
- ; array = | delimted string in this order where each monitor is delimted by ; monNumber|monWidth|monHeight|monBitDepth|monFrequency
- ; Example = 1|1600|1200|32|60&2|1024|768|32|60
- ConvertToMonitorObject(array) {
- Global monitorTable
- displaySettingsObj := Object(1,"Name",2,"Width",3,"Height",4,"BitDepth",5,"Frequency")
- obj := Object()
- Loop, Parse, array, &
- {
- currentobj:={}
- currentobj.Number := A_Index ; this is the monitor #, an integer
- Loop, Parse, A_LoopField, |
- {
- If !A_LoopField {
- Log("ConvertToMonitorObject - " . displaySettingsObj[A_Index] . " not supplied in array. Object creation terminated.",3)
- Return
- }
- currentobj[displaySettingsObj[A_Index]] := If displaySettingsObj[A_Index] = "Name" && !InStr(A_LoopField,"DISPLAY") ? "\\.\DISPLAY" . A_LoopField : A_LoopField
- }
- obj.Insert(currentobj["Number"], currentobj)
- }
- Return obj
- }
- ; Handle the supplied object by first checking if parameters are supported by the monitor, then setting them.
- ; This is the function that will be called in features and modules to change display settings.
- SetDisplaySettings(monObj) {
- Global monitorTable
- Log("SetDisplaySettings - Started")
- currentMon := GetDisplaySettings() ; get current parameters to see if res needs to be changed or it can be skipped
- Loop % monObj.MaxIndex()
- {
- ; msgbox % "SetDisplaySettings`n`nobj[" . A_Index . "].Name: " . monObj[A_Index].Name . "`nobj.Width: " . monObj[A_Index].Width . "`nobj.Height: " . monObj[A_Index].Height . "`nobj.BitDepth: " . monObj[A_Index].BitDepth . "`nobj.Frequency: " . monObj[A_Index].Frequency
- x := CheckDisplaySettings(monObj[A_Index].Name,monObj[A_Index].Width,monObj[A_Index].Height,monObj[A_Index].BitDepth,monObj[A_Index].Frequency)
- If x {
- If ((monObj[A_Index].Width = currentMon[A_Index].Width) && (monObj[A_Index].Height = currentMon[A_Index].Height) && (monObj[A_Index].BitDepth = currentMon[A_Index].BitDepth) && (monObj[A_Index].Frequency = currentMon[A_Index].Frequency)) {
- Log("SetDisplaySettings - Not changing " . monObj[A_Index].Name . " as it is already set to " . monObj[A_Index].Width . "x" . monObj[A_Index].Height . " " . monObj[A_Index].BitDepth . "bit " . monObj[A_Index].Frequency . "hz")
- } Else {
- Log("SetDisplaySettings - Changing " . monObj[A_Index].Name . " to " . monObj[A_Index].Width . "x" . monObj[A_Index].Height . " " . monObj[A_Index].BitDepth . "bit " . monObj[A_Index].Frequency . "hz")
- ChangeDisplaySettings(monObj[A_Index].Name,monObj[A_Index].Width,monObj[A_Index].Height,monObj[A_Index].BitDepth,monObj[A_Index].Frequency)
- ; Update monitorTable with new settings so it stays current
- SysGet, Monitor, Monitor, %A_Index%
- SysGet, MonitorWorkArea, MonitorWorkArea, %A_Index%
- monitorTable[A_Index].Width := monObj[A_Index].Width
- monitorTable[A_Index].Height := monObj[A_Index].Height
- monitorTable[A_Index].BitDepth := monObj[A_Index].BitDepth
- monitorTable[A_Index].Frequency := monObj[A_Index].Frequency
- monitorTable[A_Index].Left := MonitorLeft
- monitorTable[A_Index].Right := MonitorRight
- monitorTable[A_Index].Top := MonitorTop
- monitorTable[A_Index].Bottom := MonitorBottom
- monitorTable[A_Index].WorkingWidth := MonitorWorkAreaRight - MonitorWorkAreaLeft
- monitorTable[A_Index].WorkingHeight := MonitorWorkAreaBottom - MonitorWorkAreaTop
- }
- } Else
- Log("SetDisplaySettings - " . monObj[A_Index].Name . " does not support " . monObj[A_Index].Width . "x" . monObj[A_Index].Height . " " . monObj[A_Index].BitDepth . "bit " . monObj[A_Index].Frequency . "hz",2)
- }
- Log("SetDisplaySettings - Ended")
- }
- ; Change screen resolution to supplied parameters
- ; Do not call this function directly, allow SetDisplaySettings to handle it
- ; n = Display Name
- ; w = Screen Width
- ; h = Screen Height
- ; b = Bit Depth
- ; f = Frequency
- ChangeDisplaySettings(n,w,h,b,f) {
- Global RLObject
- Return RL_changeDisplaySettings(n,w,h,b,f)
- }
- ; Check monitor if it can support the screen parameters supplied
- ; Do not call this function directly, allow SetDisplaySettings to handle it
- ; Use this before calling ChangeDisplaySettings
- ; n = Display Name
- ; w = Screen Width
- ; h = Screen Height
- ; b = Bit Depth
- ; f = Frequency
- CheckDisplaySettings(n,w,h,b,f) {
- Global RLObject
- Return RL_checkDisplaySettings(n,w,h,b,f)
- }
- ; http://www.autohotkey.com/forum/topic8355.html
- ; ChangeDisplaySettings( sW, sH, cD, rR ) { ; Change Screen Resolution
- ; VarSetCapacity(dM,156,0), NumPut(156,dM,36)
- ; DllCall( "EnumDisplaySettingsA", UInt,0, UInt,-1, UInt,&dM ), NumPut(0x5c0000,dM,40)
- ; NumPut(cD,dM,104), NumPut(sW,dM,108), NumPut(sH,dM,112), NumPut(rR,dM,120)
- ; Return DllCall( "ChangeDisplaySettingsA", UInt,&dM, UInt,0 )
- ; }
- ; Acquire display "index" screen resolution (index=0,1,...)
- ; GetDisplaySettings(Index) {
- ; VarSetCapacity(device_mode,156,0)
- ; success:=DllCall("EnumDisplaySettings","uint",0,"uint",Index-1,"uint",&device_mode)
- ; If (ErrorLevel or !success)
- ; Return "Break"
- ; Out_1:=NumGet(&device_mode,108,"uint4") ;width
- ; Out_2:=NumGet(&device_mode,112,"uint4") ;height
- ; Out_3:=NumGet(&device_mode,104,"uint4") ;quality
- ; Out_4:=NumGet(&device_mode,120,"uint4") ;frequency
- ; Return Out_1 "|" Out_2 "|" Out_3 "|" Out_4
- ; } ; out "Break"
- ; Acquire current display screen resolution (1=width 2=height 3=quality 4=frequency)
- ; CurrentDisplaySettings(in=0) {
- ; VarSetCapacity(device_mode,156,0),NumPut(156,2,&device_mode,36)
- ; success := DllCall("EnumDisplaySettings","uint",0,"uint",-1,"uint",&device_mode)
- ; Out_1:=NumGet(&device_mode,108,"uint4") ;width
- ; Out_2:=NumGet(&device_mode,112,"uint4") ;height
- ; Out_3:=NumGet(&device_mode,104,"uint4") ;quality
- ; Out_4:=NumGet(&device_mode,120,"uint4") ;frequency
- ; If in = 0
- ; Return Out_1 "|" Out_2 "|" Out_3 "|" Out_4
- ; Else Return (Out_%in%)
- ; }
- ; Check if a given screen resolution is supported by the monitor, and if not, choose the nearest one that is
- ; desiredResTable uses the object defined by ConvertToMonitorObject
- CheckForNearestSupportedRes(monNumber,desiredResTable){
- Log("CheckForNearestSupportedRes - Started")
- If !desiredResTable {
- Log("CheckForNearestSupportedRes - Supplied desired resolution does not contain any data.",3)
- Return
- }
- listOfSupportedRes := EnumDisplaySettings(monNumber)
- If !listOfSupportedRes
- { Log("CheckForNearestSupportedRes - Ended, was supplied a monitor number that is not attached to this system: " . monNumber,3)
- Return
- }
- If RegExMatch(listOfSupportedRes, "i)" desiredResTable[monNumber].Width . "\|" . desiredResTable[monNumber].Height . "\|" . desiredResTable[monNumber].BitDepth . "\|" . desiredResTable[monNumber].Frequency)
- { Log("CheckForNearestSupportedRes - Ended, this resolution is already supported by this display: " . desiredResTable[monNumber].Width . "|" . desiredResTable[monNumber].Height . "|" . desiredResTable[monNumber].BitDepth . "|" . desiredResTable[monNumber].Frequency,4)
- Return desiredResTable
- }
- Log("CheckForNearestSupportedRes - This resolution is not directly supported by your monitor, finding the closest match.",4)
- SupportedResObj := {}
- nearestSupportedRes := {}
- Loop, Parse, listOfSupportedRes, `,
- {
- currentRes := A_Index
- SupportedResObj[currentRes] := {}
- StringSplit,curRes,A_LoopField,|
- SupportedResObj[currentRes].Width := curRes1
- SupportedResObj[currentRes].Height := curRes2
- SupportedResObj[currentRes].BitDepth := curRes3
- SupportedResObj[currentRes].Frequency := curRes4
- SupportedResObj[currentRes]["Distance"] := {}
- SupportedResObj[currentRes]["Distance"].Width := SupportedResObj[currentRes].Width - desiredResTable[monNumber].Width
- SupportedResObj[currentRes]["Distance"].Height := SupportedResObj[currentRes].Height - desiredResTable[monNumber].Height
- SupportedResObj[currentRes]["Distance"].BitDepth := SupportedResObj[currentRes].BitDepth - desiredResTable[monNumber].BitDepth
- SupportedResObj[currentRes]["Distance"].Frequency := SupportedResObj[currentRes].Frequency - desiredResTable[monNumber].Frequency
- }
- previousDeviation := 10**9
- Loop, %currentRes%
- {
- currentDeviation := 100*SupportedResObj[A_Index]["Distance"].Width*SupportedResObj[A_Index]["Distance"].Width + 100*SupportedResObj[A_Index]["Distance"].Height*SupportedResObj[A_Index]["Distance"].Height + 10*SupportedResObj[A_Index]["Distance"].BitDepth*SupportedResObj[A_Index]["Distance"].BitDepth + SupportedResObj[A_Index]["Distance"].Frequency*SupportedResObj[A_Index]["Distance"].Frequency
- If (currentDeviation < previousDeviation) {
- previousDeviation := currentDeviation
- nearestSupportedRes.Width := SupportedResObj[A_Index].Width
- nearestSupportedRes.Height := SupportedResObj[A_Index].Height
- nearestSupportedRes.BitDepth := SupportedResObj[A_Index].BitDepth
- nearestSupportedRes.Frequency := SupportedResObj[A_Index].Frequency
- }
- }
- supportedRes := ConvertToMonitorObject(monNumber . "|" . nearestSupportedRes.Width . "|" . nearestSupportedRes.Height . "|" . nearestSupportedRes.BitDepth . "|" nearestSupportedRes.Frequency) ; convert to object
- Log("CheckForNearestSupportedRes - Ended, closest match found is: " . supportedRes[monNumber].Width . "|" . supportedRes[monNumber].Height . "|" . supportedRes[monNumber].BitDepth . "|" supportedRes[monNumber].Frequency,4)
- Return supportedRes
- }
- ; Enumerate Supported Screen Resolutions
- ; display = the number of the monitor to enumerate supported resolutions for. 1 = Display 1, 2 = display 2, etc
- ; Returns | delimited list of all supported settings
- EnumDisplaySettings(display) {
- VarSetCapacity(DM,156,0), NumPut(156,&DM,36, "UShort")
- DllCall( "EnumDisplaySettings", str,"\\.\DISPLAY" Display, UInt,-1, UInt,&DM )
- CS:=NumGet(DM,108) "|" NumGet(DM,112) "|" NumGet(DM,104) "|" NumGet(DM,120)
- Loop
- If DllCall( "EnumDisplaySettings", str,"\\.\DISPLAY" Display, UInt,A_Index-1, UInt,&DM )
- { EDS:=NumGet(DM,108) "|" NumGet(DM,112) "|" NumGet(DM,104) "|" NumGet(DM,120)
- DS.=(!InStr(DS,EDS) ? "," EDS : "")
- } Else
- Break
- StringReplace, DS, DS, %CS%|, %CS%||, All
- Return SubStr(DS,2)
- }
- OptionScale(ByRef option, scale){ ;selects portrait specifc option value if needed and scales variable to adjust to screen resolution
- Global screenRotationAngle
- If InStr(option,"|")
- {
- StringSplit, opt, option, |
- If ((opt2) and (((A_screenWidth < A_screenHeight) and ((screenRotationAngle=0) or (screenRotationAngle=180))) or ((A_screenWidth > A_screenHeight) and ((screenRotationAngle=90) or (screenRotationAngle=270)))))
- option := If (SubStr(opt2, 0)="p") ? opt2 : round(opt2 * scale)
- Else
- option := If (SubStr(opt1, 0)="p") ? opt1 : round(opt1 * scale)
- } Else
- option := If (SubStr(option, 0)="p") ? option : round(option * scale)
- }
- TextOptionScale(ByRef Option,XScale, YScale){
- RegExMatch(Option, "i)X([\-\d\.]+)(p*)\|([\-\d\.]+)(p*)|X([\-\d\.]+)(p*)", xpos)
- RegExMatch(Option, "i)Y([\-\d\.]+)(p*)\|([\-\d\.]+)(p*)|Y([\-\d\.]+)(p*)", ypos)
- RegExMatch(Option, "i)W([\-\d\.]+)(p*)\|([\-\d\.]+)(p*)|W([\-\d\.]+)(p*)", Width)
- RegExMatch(Option, "i)H([\-\d\.]+)(p*)\|([\-\d\.]+)(p*)|H([\-\d\.]+)(p*)", Height)
- RegExMatch(Option, "i)S([\-\d\.]+)(p*)\|([\-\d\.]+)(p*)|S([\-\d\.]+)", Size)
- xposValue := SubStr(xpos, 2), yposValue := SubStr(ypos, 2), WidthValue := SubStr(Width, 2), HeightValue := SubStr(Height, 2), SizeValue := SubStr(Size, 2)
- OptionScale(xposValue, XScale)
- OptionScale(yposValue, YScale)
- OptionScale(WidthValue, XScale)
- OptionScale(HeightValue, YScale)
- OptionScale(SizeValue, YScale)
- Option := RegExReplace(Option, "i)X([\-\d\.]+)(p*)\|([\-\d\.]+)(p*)|X([\-\d\.]+)(p*)", "x" . xposValue)
- Option := RegExReplace(Option, "i)Y([\-\d\.]+)(p*)\|([\-\d\.]+)(p*)|Y([\-\d\.]+)(p*)", "y" . yposValue)
- Option := RegExReplace(Option, "i)W([\-\d\.]+)(p*)\|([\-\d\.]+)(p*)|W([\-\d\.]+)(p*)", "w" . WidthValue)
- Option := RegExReplace(Option, "i)H([\-\d\.]+)(p*)\|([\-\d\.]+)(p*)|H([\-\d\.]+)(p*)", "h" . HeightValue)
- Option := RegExReplace(Option, "i)S([\-\d\.]+)(p*)\|([\-\d\.]+)(p*)|S([\-\d\.]+)", "s" . SizeValue)
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;---------------------------- Open And Close Process Functions ----------------------------
- ;-------------------------------------------------------------------------------------------------------------
- ProcSus(PID_or_Name) {
- Log("ProcSus - Started",4)
- If InStr(PID_or_Name, ".") {
- Process, Exist, %PID_or_Name%
- PID_or_Name := ErrorLevel
- }
- If !(h := DllCall("OpenProcess", "uInt", 0x1F0FFF, "Int", 0, "Int", PID_or_Name)) {
- Log("ProcSus - Ended, process """ . PID_or_Name . """ not found")
- Return -1
- }
- Log("ProcSus - Suspending Process: " . PID_or_Name)
- DllCall("ntdll.dll\NtSuspendProcess", "Int", h), DllCall("CloseHandle", "Int", h)
- Log("ProcSus - Ended",4)
- }
- ProcRes(PID_or_Name) {
- Log("ProcRes - Started",4)
- If InStr(PID_or_Name, ".") {
- Process, Exist, %PID_or_Name%
- PID_or_Name := ErrorLevel
- }
- If !(h := DllCall("OpenProcess", "uInt", 0x1F0FFF, "Int", 0, "Int", PID_or_Name)) {
- Log("ProcRes - Ended, process """ . PID_or_Name . """ not found")
- Return -1
- }
- Log("ProcRes - Resuming Process: " . PID_or_Name)
- DllCall("ntdll.dll\NtResumeProcess", "Int", h), DllCall("CloseHandle", "Int", h)
- Log("ProcRes - Ended",4)
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;--------------------------------------- Validate IP Functions ---------------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- ValidIP(a) {
- Loop, Parse, a, .
- {
- If A_LoopField is digit
- If A_LoopField between 0 and 255
- e++
- c++
- }
- Return, e = 4 AND c = 4
- }
- ValidPort(a) {
- If a is digit
- If a between 0 and 65535
- e++
- Return e
- }
- GetPublicIP() {
- UrlDownloadToFile, http://www.rlauncher.com/ipcheck/myip.php, %A_Temp%\myip.txt
- FileRead, extIP, %A_Temp%\myip.txt
- Return extIP
- }
- GetLocalIP() {
- array := []
- objWMIService := ComObjGet("winmgmts:{impersonationLevel = impersonate}!\\.\root\cimv2")
- colItems := objWMIService.ExecQuery("Select * from Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")._NewEnum
- while colItems[objItem]
- {
- array[A_Index,1] := objItem.Description[0]
- array[A_Index,2] := objItem.IPAddress[0]
- array[A_Index,3] := objItem.IPSubnet[0]
- array[A_Index,4] := objItem.DefaultIPGateway[0]
- array[A_Index,5] := objItem.DNSServerSearchOrder[0]
- array[A_Index,6] := objItem.MACAddress[0]
- array[A_Index,7] := objItem.DHCPEnabled[0]
- }
- Return array
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;------------------------------------------- Rotate Screen Functions -------------------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- ; Options:
- ; method = irotate, display, or shortcut
- ; degrees = 0, 90, 180, 270
- Rotate(method="irotate", degrees=0) {
- Log("Rotate - Started")
- Global moduleExtensionsPath
- arrowKeys := { 0: "Up", 1: "Right", 2: "Down", 3: "Left" }
- If !RegExMatch(method,"i)irotate|display|shortcut")
- ScriptError("""" . method . """ is not a valid rotate method, Please choose either ""irotate"" or ""display""")
- If !RegExMatch(degrees,"0|90|180|270")
- ScriptError("""" . degrees . """ is not a valid degree to rotate to, Please choose either 0, 90, 180, or 270")
- rotateExe := CheckFile(moduleExtensionsPath . "\" . method . ".exe") ; check If the exe to our RotateMethod method exists
- If (method = "irotate") {
- Log("Rotate - Rotating display using irotate.exe to " . degrees . " degrees",4)
- Run(rotateExe . " /rotate=" degrees " /exit", moduleExtensionsPath)
- } Else If (method = "display") {
- Log("Rotate - Rotating display using display.exe to " . degrees . " degrees",4)
- Run(rotateExe . " /rotate:" degrees, moduleExtensionsPath)
- } Else If (method = "shortcut") {
- Log("Rotate - Rotating display using shortcut keys to " . degrees . " degrees",4)
- Send, % "{LControl Down}{LAlt Down}{" . arrowKeys[degrees // 90] . " Down}{LControl Up}{LAlt Up}{" . arrowKeys[degrees // 90] . " Up}"
- }
- Log("Rotate - Ended")
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;-------------------------------------------- Database Asset Building ------------------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- ; Builds an object filled with the FE's assets
- BuildAssetsTable(list,label,AssetType,extensions="",obj=""){
- Log("BuildAssetsTable - Started - Building Table for: " . label,4)
- Global logLevel
- StringReplace, extensionsReplaced, extensions, |, `,,All
- If !(obj)
- obj := {}
- StringSplit, labelArray, label, |,
- StringSplit, AssetTypeArray, AssetType, |,
- Loop, Parse, list,|
- { If !(labelArray%A_Index% = "#disabled#")
- {
- Log("BuildAssetsTable - Searching for a " . labelArray%A_Index% . ": " . A_LoopField,4)
- currentLabel := labelArray%A_Index%
- currentAssetType := AssetTypeArray%A_index%
- RASHNDOCT := FileExist(A_LoopField)
- If InStr(RASHNDOCT, "D") { ; it is a folder
- folderName := A_LoopFileName
- Loop, % A_LoopField . "\*.*"
- { If RegExMatch(extensions,"i)" . A_LoopFileExt)
- { currentobj := {}
- If (currentLabel="keepFileName")
- currentobj["Label"] := folderName
- Else
- currentobj["Label"] := currentLabel
- If obj[currentLabel].Label
- { currentobj := obj[currentLabel]
- currentobj.TotalItems := currentobj.TotalItems+1
- } Else {
- currentobj.TotalItems := 1
- obj.TotalLabels := if obj.TotalLabels ? obj.TotalLabels + 1 : 1
- obj[obj.TotalLabels] := currentobj.Label
- }
- currentobj["Path" . currentobj.TotalItems] := A_LoopFileLongPath
- currentobj["Ext" . currentobj.TotalItems] := A_LoopFileExt
- currentobj["AssetType"] := currentAssetType
- currentobj["Type"] := "ImageGroup"
- obj.Insert(currentobj["Label"], currentobj)
- }
- }
- } Else If InStr(RASHNDOCT, "A") { ; it is a file
- SplitPath, A_LoopField, , currentDir,, FileNameWithoutExtension
- Loop, Parse, extensionsReplaced,`,
- {
- If FileExist(currentDir . "\" . FileNameWithoutExtension . "." . A_LoopField)
- { currentobj := {}
- If (currentLabel="keepFileName")
- currentobj["Label"] := FileNameWithoutExtension
- Else
- currentobj["Label"] := currentLabel
- If obj[FileNameWithoutExtension].Label
- { currentobj := obj[FileNameWithoutExtension]
- currentobj.TotalItems := currentobj.TotalItems+1
- } Else {
- currentobj.TotalItems := 1
- obj.TotalLabels := if obj.TotalLabels ? obj.TotalLabels + 1 : 1
- obj[obj.TotalLabels] := currentobj.Label
- }
- currentobj["Path" . currentobj.TotalItems] := currentDir . "\" . FileNameWithoutExtension . "." . A_LoopField
- currentobj["Ext" . currentobj.TotalItems] := A_LoopField
- currentobj["AssetType"] := currentAssetType
- obj.Insert(currentobj["Label"], currentobj)
- }
- }
- }
- } Else
- Log("BuildAssetsTable - This asset has been disabled: " . labelArray%A_Index%,4)
- }
- If (logLevel>=5){
- for index, element in obj
- { Loop, % obj[element.Label].TotalItems
- mediaAssetsLog := % mediaAssetsLog . "`r`n`t`t`t`t`tAsset Label: " . element.Label . " | Asset Path" . a_index . ": " . element["Path" . a_index] . " | Asset Extension" . a_index . ": " . element["Ext" . a_index] . " | Asset Type" . a_index . ": " . element["AssetType"]
- }
- If mediaAssetsLog
- Log("BuildAssetsTable - Media assets found: " . mediaAssetsLog,5)
- }
- Log("BuildAssetsTable - Ended",4)
- Return obj
- }
- BuildAssetsTableOld(list,label,AssetType,extensions=""){
- Log("BuildAssetsTable - Started - Building Table for: " . label,4)
- Global logLevel
- StringReplace, extensionsReplaced, extensions, |, `,,All
- obj:={}
- StringSplit, labelArray, label, |,
- StringSplit, AssetTypeArray, AssetType, |,
- Loop, Parse, list,|
- { labelIndex++
- If !(labelArray%labelIndex% = "#disabled#")
- {
- Log("BuildAssetsTable - Searching for a " . labelArray%labelIndex% . ": " . A_LoopField,4)
- currentLabel := labelArray%labelIndex%
- currentAssetType := AssetTypeArray%A_index%
- RASHNDOCT := FileExist(A_LoopField)
- If InStr(RASHNDOCT, "D") { ; it is a folder
- folderName := A_LoopFileName
- Loop, % A_LoopField . "\*.*"
- { If RegExMatch(extensions,"i)" . A_LoopFileExt)
- { currentobj := {}
- If (currentLabel="keepFileName")
- currentobj["Label"] := folderName
- Else
- currentobj["Label"] := currentLabel
- If obj[currentLabel].Label
- { currentobj := obj[currentLabel]
- currentobj.TotalItems := currentobj.TotalItems+1
- } Else {
- currentobj.TotalItems := 1
- obj.TotalLabels := if obj.TotalLabels ? obj.TotalLabels + 1 : 1
- obj[obj.TotalLabels] := currentobj.Label
- }
- currentobj["Path" . currentobj.TotalItems] := A_LoopFileLongPath
- currentobj["Ext" . currentobj.TotalItems] := A_LoopFileExt
- currentobj["AssetType"] := currentAssetType
- currentobj["Type"] := "ImageGroup"
- obj.Insert(currentobj["Label"], currentobj)
- }
- }
- } Else If InStr(RASHNDOCT, "A") { ; it is a file
- SplitPath, A_LoopField, , currentDir,, FileNameWithoutExtension
- Loop, Parse, extensionsReplaced,`,
- {
- If (InStr(extensionsReplaced , ",") && A_Index >= 2) {
- labelIndex++ ; need to advance the label by one each time a new extension is used
- currentLabel := labelArray%labelIndex%
- }
- If FileExist(currentDir . "\" . FileNameWithoutExtension . "." . A_LoopField)
- { currentobj := {}
- If (currentLabel="keepFileName")
- currentobj["Label"] := FileNameWithoutExtension
- Else
- currentobj["Label"] := currentLabel
- If obj[FileNameWithoutExtension].Label
- { currentobj := obj[FileNameWithoutExtension]
- currentobj.TotalItems := currentobj.TotalItems+1
- } Else {
- currentobj.TotalItems := 1
- obj.TotalLabels := if obj.TotalLabels ? obj.TotalLabels + 1 : 1
- obj[obj.TotalLabels] := currentobj.Label
- }
- currentobj["Path" . currentobj.TotalItems] := currentDir . "\" . FileNameWithoutExtension . "." . A_LoopField
- currentobj["Ext" . currentobj.TotalItems] := A_LoopField
- currentobj["AssetType"] := currentAssetType
- obj.Insert(currentobj["Label"], currentobj)
- }
- }
- }
- } Else
- Log("BuildAssetsTable - This asset has been disabled: " . labelArray%labelIndex%,4)
- }
- If (logLevel>=5){
- for index, element in obj
- { Loop, % obj[element.Label].TotalItems
- mediaAssetsLog := % mediaAssetsLog . "`r`n`t`t`t`t`tAsset Label: " . element.Label . " | Asset Path" . a_index . ": " . element["Path" . a_index] . " | Asset Extension" . a_index . ": " . element["Ext" . a_index] . " | Asset Type" . a_index . ": " . element["AssetType"]
- }
- If mediaAssetsLog
- Log("BuildAssetsTable - Media assets found: " . mediaAssetsLog,5)
- }
- Log("BuildAssetsTable - Ended",4)
- Return obj
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;-------------------------------------- Broadcast and Message Receiving --------------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- ReceiveMessage(wParam, lParam) ; receive messages from other programs
- { Global Pause_Active, Pause_Running, systemName, gameInfo
- ;Global ; it is necessary to use global if the var definition part is uncommented
- StringAddress := NumGet(lParam + 8)
- StringLength := DllCall("lstrlen", UInt, StringAddress)
- If (StringLength <= 0)
- Log("A blank string message was received by RocketLauncher or there was an error.")
- Else
- { VarSetCapacity(CopyOfData, StringLength)
- DllCall("lstrcpy", "str", CopyOfData, "uint", StringAddress)
- StringSplit, Data, CopyOfData, |
- If (Data1)
- {
- If (Data1="command") { ; predefined commands
- If (Data2="RLPause") {
- If (Pause_Active){
- Gosub, TogglePauseMenuStatus
- Log("RocketLauncher received the windows message to unpause the game: " . Data2)
- } Else If !(Pause_Running) {
- Gosub, TogglePauseMenuStatus
- Log("RocketLauncher received the windows message to pause the game: " . Data2)
- }
- } Else If (Data2="RLSelect") {
- If (Pause_Active){
- Gosub, ToggleItemSelectStatus
- }
- } Else If (Data2="RLUp") {
- If (Pause_Active){
- Gosub, MoveUp
- }
- } Else If (Data2="RLDown") {
- If (Pause_Active){
- Gosub, MoveDown
- }
- } Else If (Data2="RLLeft") {
- If (Pause_Active){
- Gosub, MoveLeft
- }
- } Else If (Data2="RLRight") {
- If (Pause_Active){
- Gosub, MoveRight
- }
- } Else If (Data2="RLExit") {
- Gosub, CloseProcess
- } Else {
- Log("RocketLauncher received the windows message to run a inexistent command: " . Data2)
- }
- } Else If (Data1="ping") {
- BroadcastMessage("RocketLauncher Message System is Available.")
- } Else If (Data1="Which system?") {
- BroadcastMessage("RocketLauncher Message. Current System: " . systemName)
- } Else If (Data1="Which game?") {
- BroadcastMessage("RocketLauncher Message. Current Game: " . gameInfo["Name"].Value)
- }
- /*} if (Data1="runlabel") {
- if IsLabel(Data2) {
- Log("RocketLauncher received the windows message to run the label: " . Data2)
- gosub, %Data2%
- } Else {
- Log("RocketLauncher received the windows message to run a inexistent label: " . Data2)
- }
- } Else If (Data1="setvar") {
- Log("RocketLauncher received the windows message to set the variable named " . Data2 . " to the value = " . Data3)
- %Data2% := Data3
- */
- } Else
- Log("RocketLauncher does not recognize the pure string message sent as a valid command: " . CopyOfData)
- }
- Return true
- }
- BroadcastMessage(StringToSend) {
- Global broadcastWindowTitle
- If broadcastWindowTitle {
- VarSetCapacity(CopyDataStruct, 12, 0)
- NumPut(StrLen(StringToSend) + 1, CopyDataStruct, 4)
- NumPut(&StringToSend, CopyDataStruct, 8)
- Prev_DetectHiddenWindows := A_DetectHiddenWindows
- Prev_TitleMatchMode := A_TitleMatchMode
- DetectHiddenWindows On
- SetTitleMatchMode 2
- ; If (BroadcastWindowTitle="All"){
- ; Log("BroadcastMessage - Sending message """ . StringToSend . """ to all windows.")
- ; SendMessage, 0x4a, 0, &CopyDataStruct,, ahk_id 0xFFFF
- If InStr(BroadcastWindowTitle, "|") {
- Loop, Parse, BroadcastWindowTitle, |, %A_Space%
- { Log("BroadcastMessage - Sending message """ . StringToSend . """ to " . A_LoopField . " window.")
- SendMessage, 0x4a, 0, &CopyDataStruct,, % BroadcastWindowTitle
- }
- } Else If (BroadcastWindowTitle){
- If (WinExist(BroadcastWindowTitle) != "0x0") {
- Log("BroadcastMessage - Sending message """ . StringToSend . """ to " . BroadcastWindowTitle . " window.")
- SendMessage, 0x4a, 0, &CopyDataStruct,, % BroadcastWindowTitle
- } Else
- Log("BroadcastMessage - Could not broadcast message """ . StringToSend . """ to " . BroadcastWindowTitle . " because the window could not be found.",2)
- } Else
- Log("Message was not broadcasted because the lack of a valid window target.",4)
- DetectHiddenWindows %Prev_DetectHiddenWindows%
- SetTitleMatchMode %Prev_TitleMatchMode%
- Return ErrorLevel ; Return SendMessage's reply back to our caller.
- }
- }
- ;-------------------------------------------------------------------------------------------------------------
- ;----------------------------------------- Split Screen Module Support ------------------------------------------
- ;-------------------------------------------------------------------------------------------------------------
- ; SplitScreenPos function
- ; Returns an object with the screen coordinates (posArray[screen number].x, posArray[screen number].y, posArray[screen number].w and posArray[screen number].h) for placing split screen emulator screens.
- ; Supports up to 8 screens
- ; splitScreen2PlayersMode can be Vertical or Horizontal
- ; splitScreen3PlayersMode can be P1top, P1left, P1right, P1bottom
- ; maxPlayersPerMonitor defines the maximun amount of player screens to be placed at each monitor. For example, "1|2|3" means that screen 1 will only have the player 1, screen 2 will have the player 2 and 3 and screen 3 will have the players 4, 5 and 6 screens. If the current available monitors is not able to show the selected number of players, the code will automatically increase the screen 1 amount of screens untill all players are displayed
- SplitScreenPos(numberofPlayers,splitScreen2PlayersMode="Horizontal",splitScreen3PlayersMode="P1top",maxPlayersPerMonitor="4|4|4"){
- Global monitorTable
- Log("SplitScreenPos - Started")
- ;Making sure to distribute screens only on current available monitors and find out how many monitors are needed to show the selected number of players
- monitor := []
- StringSplit,playerPerMonitor,maxPlayersPerMonitor,|
- Loop, % monitorTable.MaxIndex()
- { monitor[a_index] := {}
- currentNumberOfPlayers := playerPerMonitor%a_index%
- accumulatedPlayers += currentNumberOfPlayers
- If (accumulatedPlayers>numberofPlayers)
- currentNumberOfPlayers := numberofPlayers - (accumulatedPlayers-currentNumberOfPlayers)
- monitor[a_index].numberOfPlayers := currentNumberOfPlayers
- }
- If (accumulatedPlayers<numberofPlayers){
- Loop, % (numberofPlayers-accumulatedPlayers)
- { count1++
- If ( count1 > monitorTable.MaxIndex() )
- count1 := 1
- monitor[count1].numberOfPlayers += 1
- }
- }
- ;Defining splitscreen positions
- posArray := []
- Loop, % numberofPlayers
- posArray[a_index] := {}
- count := 0
- Loop, % monitor.MaxIndex()
- { currentMonitor := a_index
- If (monitor[currentMonitor].numberOfPlayers = 1){
- posArray[count+1].X := monitorTable[currentMonitor].Left , posArray[count+1].Y := monitorTable[currentMonitor].Top , posArray[count+1].W := monitorTable[currentMonitor].Width , posArray[count+1].H := monitorTable[currentMonitor].Height
- } Else If (monitor[currentMonitor].numberOfPlayers = 2){
- If (splitScreen2PlayersMode = "Vertical"){
- posArray[count+1].X := monitorTable[currentMonitor].Left , posArray[count+1].Y := monitorTable[currentMonitor].Top , posArray[count+1].W := monitorTable[currentMonitor].Width//2 , posArray[count+1].H := monitorTable[currentMonitor].Height
- posArray[count+2].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//2 , posArray[count+2].Y := monitorTable[currentMonitor].Top , posArray[count+2].W := monitorTable[currentMonitor].Width//2 , posArray[count+2].H := monitorTable[currentMonitor].Height
- } Else {
- posArray[count+1].X := monitorTable[currentMonitor].Left , posArray[count+1].Y := monitorTable[currentMonitor].Top , posArray[count+1].W := monitorTable[currentMonitor].Width , posArray[count+1].H := monitorTable[currentMonitor].Height//2
- posArray[count+2].X := monitorTable[currentMonitor].Left , posArray[count+2].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+2].W := monitorTable[currentMonitor].Width , posArray[count+2].H := monitorTable[currentMonitor].Height//2
- }
- } Else If (monitor[currentMonitor].numberOfPlayers = 3){
- If (splitScreen3PlayersMode = "P1left"){
- posArray[count+1].X := monitorTable[currentMonitor].Left , posArray[count+1].Y := monitorTable[currentMonitor].Top , posArray[count+1].W := monitorTable[currentMonitor].Width//2 , posArray[count+1].H := monitorTable[currentMonitor].Height
- posArray[count+2].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//2 , posArray[count+2].Y := monitorTable[currentMonitor].Top , posArray[count+2].W := monitorTable[currentMonitor].Width//2 , posArray[count+2].H := monitorTable[currentMonitor].Height//2
- posArray[count+3].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//2 , posArray[count+3].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+3].W := monitorTable[currentMonitor].Width//2 , posArray[count+3].H := monitorTable[currentMonitor].Height//2
- } Else If (splitScreen3PlayersMode = "P1bottom") {
- posArray[count+1].X := monitorTable[currentMonitor].Left , posArray[count+1].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+1].W := monitorTable[currentMonitor].Width , posArray[count+1].H := monitorTable[currentMonitor].Height//2
- posArray[count+2].X := monitorTable[currentMonitor].Left , posArray[count+2].Y := monitorTable[currentMonitor].Top , posArray[count+2].W := monitorTable[currentMonitor].Width//2 , posArray[count+2].H := monitorTable[currentMonitor].Height//2
- posArray[count+3].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//2 , posArray[count+3].Y := monitorTable[currentMonitor].Top , posArray[count+3].W := monitorTable[currentMonitor].Width//2 , posArray[count+3].H := monitorTable[currentMonitor].Height//2
- } Else If (splitScreen3PlayersMode = "P1right") {
- posArray[count+1].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//2 , posArray[count+1].Y := monitorTable[currentMonitor].Top , posArray[count+1].W := monitorTable[currentMonitor].Width//2 , posArray[count+1].H := monitorTable[currentMonitor].Height
- posArray[count+2].X := monitorTable[currentMonitor].Left , posArray[count+2].Y := monitorTable[currentMonitor].Top , posArray[count+2].W := monitorTable[currentMonitor].Width//2 , posArray[count+2].H := monitorTable[currentMonitor].Height//2
- posArray[count+3].X := monitorTable[currentMonitor].Left , posArray[count+3].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+3].W := monitorTable[currentMonitor].Width//2 , posArray[count+3].H := monitorTable[currentMonitor].Height//2
- } Else { ;top
- posArray[count+1].X := monitorTable[currentMonitor].Left , posArray[count+1].Y := monitorTable[currentMonitor].Top , posArray[count+1].W := monitorTable[currentMonitor].Width , posArray[count+1].H := monitorTable[currentMonitor].Height//2
- posArray[count+2].X := monitorTable[currentMonitor].Left , posArray[count+2].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+2].W := monitorTable[currentMonitor].Width//2 , posArray[count+2].H := monitorTable[currentMonitor].Height//2
- posArray[count+3].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//2 , posArray[count+3].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+3].W := monitorTable[currentMonitor].Width//2 , posArray[count+3].H := monitorTable[currentMonitor].Height//2
- }
- } Else If (monitor[currentMonitor].numberOfPlayers = 4){
- posArray[count+1].X := monitorTable[currentMonitor].Left , posArray[count+1].Y := monitorTable[currentMonitor].Top , posArray[count+1].W := monitorTable[currentMonitor].Width//2 , posArray[count+1].H := monitorTable[currentMonitor].Height//2
- posArray[count+2].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//2 , posArray[count+2].Y := monitorTable[currentMonitor].Top , posArray[count+2].W := monitorTable[currentMonitor].Width//2 , posArray[count+2].H := monitorTable[currentMonitor].Height//2
- posArray[count+3].X := monitorTable[currentMonitor].Left , posArray[count+3].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+3].W := monitorTable[currentMonitor].Width//2 , posArray[count+3].H := monitorTable[currentMonitor].Height//2
- posArray[count+4].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//2 , posArray[count+4].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+4].W := monitorTable[currentMonitor].Width//2 , posArray[count+4].H := monitorTable[currentMonitor].Height//2
- } Else If (monitor[currentMonitor].numberOfPlayers = 5){
- posArray[count+1].X := monitorTable[currentMonitor].Left , posArray[count+1].Y := monitorTable[currentMonitor].Top , posArray[count+1].W := monitorTable[currentMonitor].Width//2 , posArray[count+1].H := monitorTable[currentMonitor].Height//2
- posArray[count+2].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//2 , posArray[count+2].Y := monitorTable[currentMonitor].Top , posArray[count+2].W := monitorTable[currentMonitor].Width//2 , posArray[count+2].H := monitorTable[currentMonitor].Height//2
- posArray[count+3].X := monitorTable[currentMonitor].Left , posArray[count+3].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+3].W := monitorTable[currentMonitor].Width//3 , posArray[count+3].H := monitorTable[currentMonitor].Height//2
- posArray[count+4].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//3 , posArray[count+4].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+4].W := monitorTable[currentMonitor].Width//3 , posArray[count+4].H := monitorTable[currentMonitor].Height//2
- posArray[count+5].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width*2//3 , posArray[count+5].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+5].W := monitorTable[currentMonitor].Width//3 , posArray[count+5].H := monitorTable[currentMonitor].Height//2
- } Else If (monitor[currentMonitor].numberOfPlayers = 6){
- posArray[count+1].X := monitorTable[currentMonitor].Left , posArray[count+1].Y := monitorTable[currentMonitor].Top , posArray[count+1].W := monitorTable[currentMonitor].Width//3 , posArray[count+1].H := monitorTable[currentMonitor].Height//2
- posArray[count+2].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//3 , posArray[count+2].Y := monitorTable[currentMonitor].Top , posArray[count+2].W := monitorTable[currentMonitor].Width//3 , posArray[count+2].H := monitorTable[currentMonitor].Height//2
- posArray[count+3].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width*2//3 , posArray[count+3].Y := monitorTable[currentMonitor].Top , posArray[count+3].W := monitorTable[currentMonitor].Width//3 , posArray[count+3].H := monitorTable[currentMonitor].Height//2
- posArray[count+4].X := monitorTable[currentMonitor].Left , posArray[count+4].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+4].W := monitorTable[currentMonitor].Width//3 , posArray[count+4].H := monitorTable[currentMonitor].Height//2
- posArray[count+5].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//3 , posArray[count+5].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+5].W := monitorTable[currentMonitor].Width//3 , posArray[count+5].H := monitorTable[currentMonitor].Height//2
- posArray[count+6].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width*2//3 , posArray[count+6].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+6].W := monitorTable[currentMonitor].Width//3 , posArray[count+6].H := monitorTable[currentMonitor].Height//2
- } Else If (monitor[currentMonitor].numberOfPlayers = 7){
- posArray[count+1].X := monitorTable[currentMonitor].Left , posArray[count+1].Y := monitorTable[currentMonitor].Top , posArray[count+1].W := monitorTable[currentMonitor].Width//3 , posArray[count+1].H := monitorTable[currentMonitor].Height//2
- posArray[count+2].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//3 , posArray[count+2].Y := monitorTable[currentMonitor].Top , posArray[count+2].W := monitorTable[currentMonitor].Width//3 , posArray[count+2].H := monitorTable[currentMonitor].Height//2
- posArray[count+3].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width*2//3 , posArray[count+3].Y := monitorTable[currentMonitor].Top , posArray[count+3].W := monitorTable[currentMonitor].Width//3 , posArray[count+3].H := monitorTable[currentMonitor].Height//2
- posArray[count+4].X := monitorTable[currentMonitor].Left , posArray[count+4].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+4].W := monitorTable[currentMonitor].Width//4 , posArray[count+4].H := monitorTable[currentMonitor].Height//2
- posArray[count+5].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//4 , posArray[count+5].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+5].W := monitorTable[currentMonitor].Width//4 , posArray[count+5].H := monitorTable[currentMonitor].Height//2
- posArray[count+6].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width*2//4 , posArray[count+6].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+6].W := monitorTable[currentMonitor].Width//4 , posArray[count+6].H := monitorTable[currentMonitor].Height//2
- posArray[count+7].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width*3//4 , posArray[count+7].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+7].W := monitorTable[currentMonitor].Width//4 , posArray[count+7].H := monitorTable[currentMonitor].Height//2
- } Else If (monitor[currentMonitor].numberOfPlayers = 8){
- posArray[count+1].X := monitorTable[currentMonitor].Left , posArray[count+1].Y := monitorTable[currentMonitor].Top , posArray[count+1].W := monitorTable[currentMonitor].Width//4 , posArray[count+1].H := monitorTable[currentMonitor].Height//2
- posArray[count+2].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//4 , posArray[count+2].Y := monitorTable[currentMonitor].Top , posArray[count+2].W := monitorTable[currentMonitor].Width//4 , posArray[count+2].H := monitorTable[currentMonitor].Height//2
- posArray[count+3].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width*2//4 , posArray[count+3].Y := monitorTable[currentMonitor].Top , posArray[count+3].W := monitorTable[currentMonitor].Width//4 , posArray[count+3].H := monitorTable[currentMonitor].Height//2
- posArray[count+4].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width*3//4 , posArray[count+4].Y := monitorTable[currentMonitor].Top , posArray[count+4].W := monitorTable[currentMonitor].Width//4 , posArray[count+4].H := monitorTable[currentMonitor].Height//2
- posArray[count+5].X := monitorTable[currentMonitor].Left , posArray[count+5].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+5].W := monitorTable[currentMonitor].Width//4 , posArray[count+5].H := monitorTable[currentMonitor].Height//2
- posArray[count+6].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width//4 , posArray[count+6].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+6].W := monitorTable[currentMonitor].Width//4 , posArray[count+6].H := monitorTable[currentMonitor].Height//2
- posArray[count+7].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width*2//4 , posArray[count+7].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+7].W := monitorTable[currentMonitor].Width//4 , posArray[count+7].H := monitorTable[currentMonitor].Height//2
- posArray[count+8].X := monitorTable[currentMonitor].Left+monitorTable[currentMonitor].Width*3//4 , posArray[count+8].Y := monitorTable[currentMonitor].Top+monitorTable[currentMonitor].Height//2 , posArray[count+8].W := monitorTable[currentMonitor].Width//4 , posArray[count+8].H := monitorTable[currentMonitor].Height//2
- } Else {
- Log("SplitScreenPos - " . monitor[currentMonitor].numberOfPlayers . " is a nonsupported number of players for the split screen position calculation function.",2)
- }
- Loop, % monitor[currentMonitor].numberOfPlayers
- Log("SplitScreenPos - Player " . count+a_index . " window position: X=" . posArray[count+a_index].X . ", Y=" . posArray[count+a_index].Y . ", W=" . posArray[count+a_index].W . ", H=" . posArray[count+a_index].H,5)
- count += monitor[currentMonitor].numberOfPlayers
- If (count >= numberofPlayers)
- Break
- }
- Log("SplitScreenPos - Ended")
- Return posArray
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement