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!

Driving an Emulator with Physical Cartridges

I have real nostalgia for audio cassettes, physical game cartridges, and the like. I see my son flip back and forth between assorted apps on his iPad, and I think the additional friction of having to switch out a physical piece of media added to my experience as a child. In other ways, slogging through menus and settings to get to what my son wants to do is frustrating. When we’ve tried playing the Nintendo Switch, he struggles to make the association between wireless controller inputs and an effect on the screen.

My wife got me an original SNES for my birthday, and my son and I have been really enjoying it. But there are some caveats. First, the lag is pretty brutal. I’m sure it’s rose-colored glasses just blurring this out, but just within the first few levels of Super Mario World, it’s evident that the machine is struggling to keep up. Old hardware, but it wasn’t the fastest device to begin with. On top of that, my son does have a habit of messing with the cartridge a little bit, which can cause things to freeze up. Lastly, and not insignificantly, these old games are rare and expensive! Emulation would be a lot easier on the pocketbook.

I’ve messed around with RetroPie and such in the past. But again, I don’t want my son to be toggling through a menu of assorted options. The experience that I want is one where we get the performance and consistency of an emulator, but maintain the console experience.

Could we hack this?

Let’s overengineer a solution. Could we house a Raspberry Pi inside a SNES console, and use GPIO pins connected to the cartridge reader, power switch, etc, such that they appropriately drive emulator behavior? Perhaps with the cartridges not actually having any data - merely emitting a unique identifier, either through an integrated circuit or even just soldering direct lines to an array of pins that could be read at one’s leisure? Probably!

Here are some areas of ignorance I’ll need to work through, since this isn’t really my area, and I’ve not messed with hardware in a decade…

  • Can I get a cartridge reader of the appropriate side? (presumably so, this project found some hardware)
  • Can I 3d print an SNES cartridge casing? (almost certainly)
  • Can I manufacture PCBs with gold fingers that would fit in the casing (this guy did something along these lines, but there’d definitely be a learning curve)
  • Can I drive an emulator appropriately from whatever script I’m using to interact with the GPIO pins?
  • What exactly does the GPIO communication look like (I’m gonna need to play around with some breadboard prototypes, I suspect)
  • How is the game identifier actually stored?

Who knows? But I’m gonna start by proving out the concept of driving an emulator on a Raspberry Pi, and slowly work my way back from there. Stay tuned as I start to figure this out.