theMK2k / MetropolisLauncher

A data-heavy Emulation & Gaming front-end for Windows
http://metropolis-launcher.net
Other
40 stars 3 forks source link

AutoIT Support #22

Closed BabaJeanmel closed 5 years ago

BabaJeanmel commented 6 years ago

One of the most interesting features on launchers such as hyperspin is the ability to use metadata (title, filename, extension, 1 or 2 custom fields) from roms and use them within scripts.

For instance, you can :

Plus other general functions not requiring metadata :

I've written a lot of AutoIT3 scripts for ECC, a frontend that enables the use of metadata but is otherwise sluggish and primitive compared to MetropolisLauncher. They really make the difference for launching computer games (Amstrad CPC, NEC PC-8801 and PC-9801, Fujitsu FM-7 and FM-Towns, Sharp X1 and X68000, MSX, Thomson MO5/TO7, Texas Instruments TI-99...)

I'm using this metadata for my scripts :

Could support for AutoIT be possible in MetropolisLauncher in the future ?

If it can be of any help, I can send you some of my scripts, of course.

theMK2k commented 6 years ago

Thanks for your detailled description here.

I have some initial questions:

  1. Does Metropolis Launcher have to provide the metadata as input parameters to the script or is it neccessary that Metropolis Launcher generates the scripts by itself (from a template of some sorts) and provides them to the AutoIt?

  2. Is it sufficient to assign an AutoIt script per emulator or per game?

My TODO:

Could you send over some scripts, so I can have a better picture of the situation? And let me know which emulators you're using with them.

Thanks

BabaJeanmel commented 6 years ago

1) I think it's better to provide metadata only. Scripts are very different from one emu to the other, so a general template would be kinda difficult to set up. Besides, being able for the end user to tweak existing scripts per emu to add their own key shortcuts or additional features could be great ! 2) Yes. I use a script per platform. For special game cases, I use the custom fields and they are processed in the script (if id=... , then ...)

Below, here is a commented script for WinAPE (Amstrad CPC)

BabaJeanmel commented 6 years ago
;eccscriptsystem.au3 is the file containing all variables pulled from the database.

#include "..\eccScriptSystem.au3"

;First, I set two hotkeys for easily pausing games/quitting. Associated functions are at the bottom of the script.

hotkeyset("{esc}", "Terminate")
hotkeyset("{²}", "Pause")

;Removing all media entries in the WinAPE .ini file, as the emu keeps all stored.

IniDelete ( "WinAPE.ini", "Drives", "Drive(0)" )
IniDelete ( "WinAPE.ini", "Drives", "Drive(1)" )
IniDelete ( "WinAPE.ini", "Tape", "File Name" )
IniDelete ( "WinAPE.ini", "ROMS", "Cartridge" )

;Re-inserting CPC Plus cartridge (inserting another one makes the emu boot in GX4000 mode, and if we've played a GX4000 game before, the emu will stay configured to play it again)

IniWrite ( "WinAPE.ini", "ROMS", "Cartridge", "cpc_plus.cpr")

;Some commands we need for tape games can only be parsed in windowed mode, so we force WinAPE to run windowed at start.

IniDelete ( "WinAPE.ini", "Configuration", "Full Screen" )

;There isn't an entry in ECCscriptsystem.au3 for file address with full path, and we need it. So I create a new variable.

Local $FilePath = $eccFileRomPath & $eccFileRomFile

;Disk game section 

If $eccFileRomExtension = "dsk" Then

;1-disk games are just sent straight to the .ini file.

    If $eccMetaMediaCount < "2" Then
        IniWrite ( "WinAPE.ini", "Drives", "Drive(0)", ""&$FilePath&"")
    Else

;If the game has more than 1 media, the first two will be inserted into the emu's floppy ports. Files must be named "Game Name Disk 1.dsk", "Game Name Disk 2.dsk" etc. for the script to work.

        Local $eccFileRomFile2 = StringReplace($eccFileRomFile, "Disk 1", "Disk 2")
        Local $FilePath2 = $eccFileRomPath & $eccFileRomFile2
        IniWrite ( "WinAPE.ini", "Drives", "Drive(0)", ""&$FilePath&"")
        IniWrite ( "WinAPE.ini", "Drives", "Drive(1)", ""&$FilePath&"")
    Endif

;This command executes the emulator telling it to boot from the floppy.

    ShellExecute ($Emulator, '/A')

;Tape game section  

Elseif $eccFileRomExtension = "cdt" Then

;We need this for the tape to be set at starting position.

    IniDelete ( "WinAPE.ini", "Tape", "Position" )
    IniDelete ( "WinAPE.ini", "Tape", "Size" )

;As with the disk games, we send directly the filename into the .ini file.

    IniWrite ( "WinAPE.ini", "Tape", "File Name", ""&$FilePath&"")

;Starts the emu and waits for it to open.

    ShellExecute ($Emulator)
    WinWaitActive("[CLASS:TfrmEmu]")

;Send tape commands
    Opt("SendKeyDownDelay",20)
    Sleep (500)
    Send ("NUMLOCK on}")
    Send ("{NUMPAD1}")
    Sleep (1000)

;I'm on a french keyboard... on a QWERTY it would be the pipe symbol ("|")
    Send ("{¨}")
;Same thing... on a QWERTY it would be "TAPE"
    Send ("TQPE")

    Send("{ENTER}")

;On a QWERTY, it would be "RUN"""
    Send ("RUN22")

    Send("{ENTER}")
    Send ("{APPSKEY}")
    WinMenuSelectItem("[CLASS:TfrmEmu]", "", "&File", "&Tape", "&Press Play")
Endif

;Now we can put the emu in fullscreen mode !

WinWaitActive("[CLASS:TfrmEmu]")
Send ("{APPSKEY}")
WinMenuSelectItem("[CLASS:TfrmEmu]", "", "&Settings", "&Full Screen")
Send("{ENTER}")

;Keep script open 
ProcessWaitClose ($eccEmuEmulatorFile)

Exit

;This function quits the emu if we press "ESC" (see on top of the script)

Func Terminate()
   ProcessClose ($eccEmuEmulatorFile)
   Exit 0
EndFunc

;This function pauses the emu if we press "²" (see on top of the script). It also hides the debugger that WinAPE automatically opens when we pause.

Func Pause()
    Send ("{F7}")
    WinWaitActive("[CLASS:TfrmDebug]")
    WinSetState ( "[CLASS:TfrmDebug]", "", @SW_HIDE )
EndFunc
BabaJeanmel commented 6 years ago

Another one for OpenMSX :

#include "..\eccScriptSystem.au3"

hotkeyset("{esc}", "Terminate")

Local $FilePath = $eccFileRomPath & $eccFileRomFile

;Sets the MSX machine to an US/Euro variant if the country is set as "Japan" in the metadata. This enables dual-language games to be launched in english. The Japanese config is better so I don't default the US/Euro machine.

If $eccFileRomRegionNr = "9" Then
    Local $Machine = "boosted_msx2_en"
Else
    Local $Machine = "boosted_msx2+_jp"
Endif

;Disk section. Very similar to the one in the WinAPE script, but this time we don't edit an .ini file. Info needed for launching is sent into variables and OpenMSX is launched with command-line parameters parsing theses variables.

If $eccFileRomExtension = "dsk" Then
    Local $Media= "diska"
    If $eccMetaMediaCount > "1" Then
        Local $Media2 = "diskb"
        Local $eccFileRomFile2 = StringReplace($eccFileRomFile, "Disk 1", "Disk 2")
        Local $FilePath2 = $eccFileRomPath & $eccFileRomFile2
    Endif
Elseif $eccFileRomExtension = "rom" Then
    Local $Media= "carta"
Endif

If IsDeclared ("Media2") Then
    ShellExecute ($Emulator,'-machine "'&$Machine&'" -"'&$Media&'" "'&$FilePath&'" -"'&$Media2&'" "'&$FilePath2&'" ')
Else

;For tape games, file names aren't parsed to the command line. See below.

    If $eccFileRomExtension = "cas" Then
        ShellExecute ($Emulator,'-machine "'&$Machine&'" ')
    Else
        ShellExecute ($Emulator,'-machine "'&$Machine&'" -"'&$Media&'" "'&$FilePath&'" ')
    Endif
Endif

;Hide the console (can confuse Steam's in-home streaming)

WinWaitActive ("[CLASS:ConsoleWindowClass]")
WinSetState ( "[CLASS:ConsoleWindowClass]", "", @SW_HIDE )

;To run tape games, we need to enter the OpenMSX command prompt and send a command.

If $eccFileRomExtension = "cas" Then

;File paths in OpenMSX are UNIX-style, with "\" instead of "/". So we must correct that before sending the command.

Local $FilePathCorrected = StringReplace($FilePath, "\", "/")

;Command to run tape is sent into the command prompt, then command prompt is closed

    Opt("SendKeyDownDelay", 5)
    Send("{F10}")
    Send ('cassetteplayer insert "'&$FilePathCorrected&'"')
    Send ("{ENTER}")
    Send("{F10}")   
Endif

;Now we go fullscreen as this setting is not kept after we quit OpenMSX.

Send ("{! ENTER}")

ProcessWaitClose ($eccEmuEmulatorFile)

Exit

Func Terminate()
   ProcessClose ($eccEmuEmulatorFile)
   Exit 0
EndFunc
BabaJeanmel commented 6 years ago

Here are both files without comments and more easily readable. I've renamed them to "txt" but they are, in fact, au3 files (ECC requires them to have the .eccscript extension)

openmsx.txt winape.txt

I've got plenty of other ones (a lot of them aren't as complex) mainly for japanese computers (M88 for NEC PC-8801, Neko Project 2 for NEC PC-9801, Takeda Common Binaries for Fujitsu FM-7 variants, UNZ for FM-Towns, Takeda Common Binaries again for Sharp X1 variants, WinX68K Hi-Speed for Sharp X68000) but also for Demul (Dreamcast + Atomiswave, Naomi), Phoenix Emu Project (Jaguar, ColecoVision, 3DO) and a few more vintage 8-bit computers (Thomson MO5/TO7 computers, Oric, Tandy CoCo and Thomson TI-99).

theMK2k commented 6 years ago

Wow, that's some pretty serious scripting going on there. I wonder if the actual emulator is even neccessary here, as it seems to be just another parameter for the script.

Could you please provide an exported eccScriptSystem.au3 containing the metadata. Ideally one with more than one ROM/Disk file?

BabaJeanmel commented 6 years ago

Well... I can script, but writing serious code is totally out of my reach. So I guess I still need these emus after all ^^

Original file names are eccScriptSystem.au3 (tweaked to make daemon tools work again) and eccScriptRom.dat (contents changes each time you launch a different rom)

eccScriptRom.dat keeps info only on the file you launch. To make ECC process other ROMs/Disks, it's mandatory to use scripts or playlists (for emulators supporting them, such as mednafen or winVICE)

eccScriptSystem.txt eccScriptRom.txt

theMK2k commented 6 years ago

Alright, many thanks. It's a bit overwhelming and I have to get my head around it. I'm still positive that we can get a nice AutoIT integration into Metropolis Launcher.

theMK2k commented 6 years ago

I just read up about AutoIT and saw that there seem to be two large communities:

  1. AutoIT
  2. AutoHotKey

It seems to me, that if we support scripting engines, we have to at least support both of the above.

theMK2k commented 6 years ago

Unfortunately some months went by until I actually start implementing the AutoIt 3 support. Anyways, here's how I would do it:

Metropolis Launcher will provide a sample script file which contains:

The user prepares the scripts and may include actual data between the INJECT START and END tags for testing purposes.

When a game is launched, the provided script will be copied to a temporary directory. Metropolis Launcher will remove all content between INJECT START and END tags and provide the actual data in that section. Then, the AutoIt3 script gets run.

I just added a very simple example file.

So, if you're still around, let me know what you think :) ml_autoit_sample.txt

theMK2k commented 5 years ago

AutoIT and AutoHotKey is supported with v1.2.0