Launch emulator script

Hi !

Using emulationstation on my Gameshell, I wanted to add a new system for diffrents rom hacks. So my system needs to be able to load roms for different consoles.

Retropie do it very well, but I made a little script wish allow to associate default retroarch core per game.

This is pretty simple. Instead of launch the core by the command

retroarch -L ~/apps/emulators/core_name.so yourgame

You can launch my script :

~/apps/emulators/launch.sh yourgame.ext

Note that zip roms are supported ! The script can check the extension of the file inside.

For now the script only manage gb, nes, snes and gba systems but it’s very easy to add anothers !

Just add a statement :

elif [ "$EXTENSION" == "ngpc" ]; then
  SELECTED_CORE="mednafen_ngp_libretro.so" 

for example for Neogeo Pocket Color. Of course you can select the core you want.

A file assoc.txt will be created by the script a looks like this as you laucnh your games :

/home/cpi/games/roms/hacks/Pokemon - Brown version.gb;gambatte_libretro.so
/home/cpi/games/roms/hacks/Super Mario Land - 2012.gb;gambatte_libretro.so
/home/cpi/games/roms/hacks/Pokemon 151 (Red Hack).gb;gambatte_libretro.so
/home/cpi/games/roms/hacks/Metroid/Metroid - MDbtroid.nes;nestopia_libretro.so
/home/cpi/games/roms/msu-1/The Legend of Zelda - A Link to the Past (MSU-1 Video)/alttp_msu.sfc;snes9x_libretro.so
/home/cpi/games/roms/msu-1/Zelda ALTTP Zelda3 Parallel Worlds v1-2-3 Euclid, SePH, Qwertymodo Audio Fix/zpw.sfc;snes9x_libretro.so
/home/cpi/games/roms/hacks/NES/The Legend of Zelda/Another Evil.nes;nestopia_libretro.so
/home/cpi/games/roms/hacks/NES/The Legend of Zelda/Ganon's Curse.nes;nestopia_libretro.so
/home/cpi/games/roms/hacks/NES/The Legend of Zelda/Ganon's Deception.nes;nestopia_libretro.so
/home/cpi/games/roms/hacks/NES/The Legend of Zelda/Ganon's Revenge.nes;nestopia_libretro.so
/home/cpi/games/roms/hacks/NES/The Legend of Zelda/Hyrule's Doom.nes;nestopia_libretro.so
/home/cpi/games/roms/hacks/GBC/Pokemon Prism (v0.94-b0226).gbc;gambatte_libretro.so
/home/cpi/games/roms/msu-1/The Legend of Zelda - A Link To The Past DX (MSU-1)/loz3-dx.sfc;snes9x_libretro.so
/home/cpi/games/roms/gba/Castlevania - Circle of the Moon (Europe).zip;gpsp_libretro.so
/home/cpi/games/roms/gba/Metroid - Fusion (Europe).zip;gpsp_libretro.so
/home/cpi/games/roms/gba/Street Fighter Alpha 3 (Europe).zip;gpsp_libretro.so
/home/cpi/games/roms/gba/Super Mario Advance 2 - Super Mario World (Europe).zip;gpsp_libretro.so
/home/cpi/games/roms/gba/Sword of Mana (Europe).zip;gpsp_libretro.so
/home/cpi/games/roms/gba/Tales of Phantasia (Europe).zip;gpsp_libretro.so
/home/cpi/games/roms/gba/Wario Land 4 (USA-Europe).zip;gpsp_libretro.so

You noticed that each game will be associated with the default core you mentionned in the statement. If you need to, you can change the core name for a specific game as you like.

When you start a game, the script looks in the assoc.txt file if a corresponding line exists. If yes it runs retroarch with the core whose name is mentioned after the semicolon

Of course the script is not perfect but I will update it for sure. So don’t be shy and feel free to give comments and suggestions :wink:

There you are :

 #!/bin/bash
FILE="/home/cpi/apps/emulators/assoc.txt"
ASSOC=0
SELECTED_CORE="null"
GAMETORUN=$1
SYSTEM=$2

# Check if there already an association of game/core in file assoc.txt
while IFS=';' read game core
do
	if [ "$game" == "$1" ]; then
		ASSOC=1
		SELECTED_CORE="$core"
	fi
done < $FILE

# Find the extension of the rom, even if it's zipped
FILENAME=$(basename "$GAMETORUN")
EXTENSION="${FILENAME##*.}"
if [ "$EXTENSION" == "zip" ]; then
  TEMP=`zipinfo -1 "$GAMETORUN"`
  TEMP2=$(basename "$TEMP")
  EXTENSION="${TEMP2##*.}"
fi

#default cores
if [ "$SELECTED_CORE" == "null" ]; then
	if [ "$SYSTEM" == "gb" ] || [ "$EXTENSION" == "gb" ] || [ "$EXTENSION" == "gbc" ]; then
	  SELECTED_CORE="gambatte_libretro.so"
	elif [ "$EXTENSION" == "nes" ]; then
	  SELECTED_CORE="nestopia_libretro.so"
	elif [ "$EXTENSION" == "smc" ] || [ "$EXTENSION" == "fig" ] || [ "$EXTENSION" == "sfc" ]; then
	  SELECTED_CORE="snes9x2005_plus_libretro.so"
	elif [ "$EXTENSION" == "gba" ]; then
	  SELECTED_CORE="gpsp_libretro.so"
	fi
fi

# if we didn't find a line in the assoc file we create it with the selected core
if [ "$ASSOC" == 0 ] && [ "$SELECTED_CORE" != "null" ]; then
	echo "$GAMETORUN;$SELECTED_CORE" >> $FILE
fi

# launch the game
retroarch -L ~/apps/emulators/"$SELECTED_CORE" "$GAMETORUN"

exit
1 Like

I completly forgotten to give the update I made… There it is :

#!/bin/bash
EMULATORS_ROOT_DIR="/home/cpi/apps/emulators"
FILE="$EMULATORS_ROOT_DIR/assoc.txt"
OUT="$EMULATORS_ROOT_DIR/out.txt"
ERRORS="$EMULATORS_ROOT_DIR/errors.txt"
ASSOC=0
RETROARCH_CORE=0
EMULATOR="null"
DIRECTORY="null"
GAMETORUN=$1
SYSTEM=$2
DEBUG=$3

# Check if there is already an association of game/emulator in file assoc.txt
while IFS=';' read game emulator directory
do
	if [ "$game" == "$1" ]; then
		ASSOC=1
		EMULATOR="$emulator"
		DIRECTORY="$directory"
	fi
done < $FILE

if [ "$DEBUG" == 1 ]; then
	echo "===========" >> $OUT 2>> $ERRORS
	echo "1 $SYSTEM" >> $OUT 2>> $ERRORS
	echo "2 $GAMETORUN" >> $OUT 2>> $ERRORS
	echo "3 $EMULATOR" >> $OUT 2>> $ERRORS
	echo "4 $DIRECTORY" >> $OUT 2>> $ERRORS
fi

# Find the extension of the rom, even if it's zipped
FILENAME=$(basename "$GAMETORUN")
EXTENSION="${FILENAME##*.}"
if [ "$EXTENSION" == "zip" ] && [ "$SYSTEM" != "cps" ] && [ "$SYSTEM" != "neogeo" ]; then
  TEMP=`zipinfo -1 "$GAMETORUN"`
  TEMP2=$(basename "$TEMP")
  EXTENSION="${TEMP2##*.}"
fi

if [ "$DEBUG" == 1 ]; then
	echo "5 $EXTENSION" >> $OUT 2>> $ERRORS
fi

#default emulators
if [ "$EMULATOR" == "null" ] && [ "$DIRECTORY" == "null" ]; then
	if [ "$DEBUG" == 1 ]; then
		echo "6 EMULATOR and DIRECTORY are null" >> $OUT 2>> $ERRORS
	fi
		
	if [ "$EXTENSION" == "gb" ] || [ "$EXTENSION" == "gbc" ]; then
		EMULATOR="ohboy"
		DIRECTORY="ohboy"
	elif [ "$EXTENSION" == "nes" ]; then
		EMULATOR="fceux"
		DIRECTORY="fceux"
	elif [ "$EXTENSION" == "smc" ] || [ "$EXTENSION" == "fig" ] || [ "$EXTENSION" == "sfc" ]; then
		EMULATOR="PocketSNES"
	elif [ "$EXTENSION" == "gba" ]; then
		EMULATOR="gpsp"
		DIRECTORY="gpsp"
	elif [ "$EXTENSION" == "gg" ]; then
		EMULATOR="genesis_plus_gx_libretro.so"
	elif [ "$EXTENSION" == "ngc" ]; then
		EMULATOR="mednafen_ngp_libretro.so"
	elif [ "$EXTENSION" == "cue" ]; then
		EMULATOR="pcsx_rearmed_libretro.so"
	elif [ "$EXTENSION" == "smd" ] || [ "$EXTENSION" == "bin" ] || [ "$EXTENSION" == "md" ]; then
		EMULATOR="PicoDrive"
		DIRECTORY="PicoDrive"
	elif [ "$EXTENSION" == "zip" ]; then
		if [ "$SYSTEM" == "cps" ]; then
			EMULATOR="fbneo_libretro.so"
		elif [ "$SYSTEM" == "neogeo" ]; then
			EMULATOR="fbalpha2012_neogeo_libretro.so"
		fi
	elif [ "$EXTENSION" == "pce" ]; then
		EMULATOR="mednafen_pce_fast_libretro.so"
	fi
fi

if [ "$DEBUG" == 1 ]; then
	echo "7 $EMULATOR" >> $OUT 2>> $ERRORS
	echo "8 $DIRECTORY" >> $OUT 2>> $ERRORS
fi

# Find the extension of the emulator to determine if it's retroarch or not
FILENAME_EMU=$(basename "$EMULATOR")
EXTENSION_EMU="${FILENAME_EMU##*.}"
if [ "$EXTENSION_EMU" == "so" ]; then
  RETROARCH_CORE=1
fi


# if we didn't find a line in the assoc file we create it with the selected core
if [ "$ASSOC" == 0 ] && [ "$EMULATOR" != "null" ]; then
	if [ "$DIRECTORY" == "null" ]; then
		echo "$GAMETORUN;$EMULATOR" >> $FILE
	else
		echo "$GAMETORUN;$EMULATOR;$DIRECTORY" >> $FILE
	fi
fi

# launch the game
if [ "$RETROARCH_CORE" == 1 ]; then
	retroarch -L ~/apps/emulators/"$EMULATOR" "$GAMETORUN" >> $OUT 2>> $ERRORS
else
	cd ~/apps/emulators/"$DIRECTORY"

	./"$EMULATOR" "$GAMETORUN" >> $OUT 2>> $ERRORS
fi

if [ "$DEBUG" == 1 ]; then
	echo "===========" >> $OUT 2>> $ERRORS
fi

exit
1 Like

It is beautiful and my god so much more eloquent than what I would have done, ie just treated the entire Retroarch + options + core as it’s own “standalone” per emulator, on top of actual standalones.
I can certainly learn a lot from this coding! Thanks for the update! :slight_smile:

1 Like

To be completely honest, i don’t know bash at all. :yum:
I’m sure there is a much more effective way to deal with this.

In fact I thought of a solution in an algorithmic way and then I searched on google how to do it.
For example “how to read the contents of a file line by line”, “how to write to a file”, “how to determine the extension of a file”, etc.
And then I improve gradually … Nothing exceptional in the end. :grin:

The ultimate thing would be to be able to create an entry in the main menu of the Gameshell which would allow you to edit the “assoc.txt” file directly.
A bit like the ROMs lists where you can bookmark a game.
We would have the list of our games, we select one. There then appears the list of emulators / cores and we select one. This action writes or modifies the line of the “assoc.txt” file.
Unfortunately I have absolutely no knowledge in python to do that …

1 Like

this is a nice script,

i personally use xdg-open method to link roms mime types & emulators, in your script you could also set it as a fallback method if the extension is not know

(for more match you may set extension to lower case before comparing it

$ string="A FEW WORDS"
$ echo "${string,}"
a FEW WORDS
$ echo "${string,,}"
a few words
1 Like

Better yet, having a scraped meta data that uses a list of known rom sets zip files, and the contents within each; especially when some are compiled with multiple languages in one compressed archive!

Good point re case sensitivity @r043v!

One thing RetroPie also does is have Retroarch set to have settings on either a per core basis or a per rom basis. This personally frustrates me, having to remember which emulator has what settings etc, and not being able to edit just one to get it working.

In the long run, we could probably come to a consensus of what settings work best for which emulators/games and truly have the console set to a “set and forget” and “pick up and play” format.

That’s when having emulationstation truly as the primary launcher could indeed be a reality. Is that what you’ve got set up, @Dowdheur?