KevinGisi.com Whatever is here is here

Poking Around with RetroPie

Good news on the emulator front - it does appear that we can launch immediately directly into a ROM via the command line. Which of course means we could also drive that behavior through interaction with the GPIO pins.

I have a Raspberry Pi 4 on its way, but dug out an old RPi3 and a SNES style USB game controller (non-affiliate link). Installed RetroPie, which is a Raspbian-based OS that includes all the emulation infrastructure we could ever want. The dashboard for the experience is EmulationStation.

At first glance, there’s not an immediate way to programatically control the dashboard (and emulationstation --help doesn’t indicate anything to that effect), so I went ahead and launched a game, then checked the running processes.

ps -ef | grep Mario and there’s our culprit!

/opt/retropie/emulators/retroarch/bin/retroarch -L /opt/retropie/libretrocores/lr-snes9x2010/snes9x2010_libretro.so --config /opt/retropie/configs/snes/retroarch.cfg /home/pi/RetroPie/roms/snes/SuperMarioWorld.sfc --appendconfig /dev/shm/retroarch.cfg

It appears that EmulationStation sits in front of RetroArch, which is a frontend for Libretro, which is an API that assorted emulators can use (such as snes9x, which we’re using out of the box here). Best I can tell, Libretro is responsible for the graphics drivers, input drivers, probably the button-mapping, etc, and then snes9x doesn’t have to worry about all that.

But that’s not particularly important for what we need to work out. All we care about is the fact that if we run that command, we’re able to immediately launch into a game, with the controller already mapped. I played through the yellow switch palace, saved, and killed the process. Launched it again and my save data was preserved. This means we’re able to use RetroPie as our platform.

One tweak to make - we want to avoid launching EmulationStation on boot. If it’s active, it fights with our manual game-launching. We can always build some GPIO-based way of launching emulationstation if we want to configure a controller. Easy enough to do - we go into settings, launch the RetroPie setup script, then Configuration / tools -> autostart -> Boot to text console (require login).

Assorted Thoughts

  • It may be helpful to use (auto login as pi) as our launch behavior down the road - we could simply trigger our Python script via .bashrc, safe in the knowledge that the display and assorted devices are all ready to go at that point. Time will tell!
  • Not sure if this is Raspbian’s fault or RetroPie’s, but vim isn’t there out of the box. Harumph!
  • This may require a little bit of tweaking when the RPi4 gets in, as the RetroPie image is different, but assuming it’ll be pretty similar.

Let’s poke around with Python

To be clear, I don’t have a background in Python, so this is gonna be “it works” type of code, not something to model anything after. That said, it looks like subprocess.Popen is the route we want to go down to spawn the emulator in such a way that we can programmatically kill it. After a little messing around, we have the start to a passable script!

#!/usr/bin/env python

import subprocess

ROM_DICT = {
    1: 'SuperMarioWorld.sfc'
}

def main():
    # On power on, fetch the id from the chip
    game_id = 1
    game = run_game(ROM_DICT[game_id])
    game.wait()
    # On power off, kill the subprocess
    # On reset, restart the subprocess

def run_game(rom):
    return subprocess.Popen([
        '/opt/retropie/emulators/retroarch/bin/retroarch',
        '-L', '/opt/retropie/libretrocores/lr-snes9x2010/snes9x2010_libretro.so',
        '--config', '/opt/retropie/configs/snes/retroarch.cfg',
        '/home/pi/RetroPie/roms/snes/%s'%(rom),
        '--appendconfig', '/dev/shm/retroarch.cfg'])

if __name__ == '__main__':
    main()

With that script done, we’re about as far as we can go on this project without hardware. Within a few days, I should have a breadboard and some EEPROMs for us to mess with, so we’ll be able to dive into the excitement that is I2C!