Getting Started with RetroArch

In the past month I have seen a few guides about configuring RetroArch, while good some fail to explain some concepts, so I thought why not, I’ll make a series of blog posts about configuring RetroArch, starting from the basics.

Terms

  • Core — a core is a program that runs in RetroArch (or another libretro frontend)
  • Frontend — a frontend in this context is a program that can run libretro cores (RetroArch, Minir, Kodi’s Retroplayer are examples of this)
  • Content — content is a game/program that is run by a core, some cores also require no content
  • Retropad — retropad is RetroArch’s input abstraction controller, it’s the interface between the physical controller and the core inputs
  • Save Files — save files are saves that are made from within a game, usually cross platform and should work across emulators in most cases
  • Save States — save states are snapshots of the content menory at a particular moment, these are not always cross platform and most certainly won’t work on a different emulator that the one used to create them
  • System Files — additional files that might or not be part of the romset that might be needed to get some content to work (usually referred to by the BIOS term)
  • Autoconf Profile — a configuration file that has button definitions for a particular gamepad

Continue reading “Getting Started with RetroArch”

A quick rant about web performance

t was surprisingly easy finishing up my RetroArch port to the web, thanks to Emscripten and all the hard work in that. And making it easier for programs to get on the web is a good thing. However, during my journey, I ran into more than a couple issues and learned more than a couple discouraging facts that make me think twice about the great future of full-blown programs on the web.

A lot of the tech is still very very young

Most of the big tech in web apps are new. Stuff like WebGL, Web Audio, and even Emscripten itself are still in their growing stages, and it shows. You would never expect to run into a bug with a platform’s standard C library, but that was exactly an issue I had to debug and fix. (Note to future C library developers: while isprint and isgraph sound similar, they are not the same.) Even when they do work, they don’t always work “right” according to the other browsers. Right now my port has to resort to a hack to get Firefox working, because currentTime only updates when the Javascript event loop is idle. Mozilla claims this is the correct behavior, yet Chrome goes ahead and updates continuously. Who is right? Mozilla claim they are, but Chrome says otherwise. The spec doesn’t say with certainty which way is correct, so until this is expanded upon, you will run into these issues. (BTW, If anyone from Mozilla happens to read this, I would really like you guys to adapt the Chrome behavior.)

Doing things the “not-Web” way is bad, but it works better

One thing I learned very quickly: blocking the event loop is bad. Very very very VERY bad. It’s so bad. Never do it. No reason to ever do it. But it’s the only way to do some things.

RetroArch, being an emulator, has very different audio/video sync requirements than something like a game or a video. The audio and video the emulator spit out must get played immediately, or you get horrible stuff like input lag or audio/video desync. One way to combat this is to “block” on audio: make a buffer for audio and fill it up. If it’s full, wait until the audio API empties it a bit and fill it up and go on your way. If you’re on native Linux and using something like ALSA, that functionality is built into the API and works just fine, and for something like OpenAL that doesn’t, you can simulate it with busy loops. However, every time I brought that up in a bug report I was immediately shot down. “Busy-waiting in Javascript is a big no-no.” And it is when you let it get in an infinite loop. However, to do blocking audio with any sort of good performance, it is required with the Web Audio API. Web Audio has no blocking features, so you have to use busy-loops. I tried using some of the other interfaces I had to avoid this, like some callback-based ones, but this leads to…

You are at the mercy of the event loop

The event loop is 100% unpredictable. It also must be hit to do anything involving input/output. Video needs it to display, input needs it to capture events, and audio needs it to play. I tried to implement an audio callback method to avoid blocking on audio, but the callback fired at intervals that were in no way predictable, from one time up to five times every 20 milliseconds. That and trying to put calls to “requestAnimationFrames” is spotty at best. Hoping to get a stable 60FPS off of it is an exercise in futility. Most of these issues are not issues for something like a video or a normal game: Audio can be queued and you can play individual samples instead of streaming. For emulators, there is no alternative, and the tools the web platform has right now do not help. They have to be worked around to get a program that performs well.

What can be done?

The first thing that can be done is to make the browsers behave similarly. Right now Firefox doesn’t have the constantly updating currentTime for Web Audio, and the precision on performance timers on Chrome is really odd. These can be fixed (or a consensus agreed upon).

For more performance-heavy things, there needs to be a way to either get around the event loop or control it better. The yield keyword in ES6 is a nice first step, but there needs to be a way to guarantee (or at least make a better attempt) a callback or timer to happen when it should. Even better would be a way to start a thread separate from the main loop. Can Web Workers be used for this? Not sure, but probably not with any audio/video output which makes it a no-go for us. Maybe some new tech can allow this in browsers. A pipe dream perhaps, but hey, it’ll probably be better than NaCl in the long run.

RetroArch v0.9.9 Released – where to get it on each platform

RetroArch v0.9.9 has officially been rolled out on all platform targets.

The new platforms that are supported with this release of RetroArch are as follows:

  • iOS (both jailbroken and non-jailbroken – non-jailbroken requires that you are a registered developer and can compile your own copy of RetroArch + cores)
  • Blackberry 10
  • Blackberry Playbook Tablet OS

The other platforms which are already supported by the RetroArch/libretro projects have all received updates (with some pretty extensive changes – more on that in an upcoming blog post).

WHERE TO GET IT

Windows: New users can download 32- and 64-bit flavors of RetroArch and RetroArch-Phoenix from Themaister’s site:

http://themaister.net/retroarch.html

Existing users can/should download the new version through RetroArch-Phoenix’s built-in ‘RetroArch Updater’ utility. (this is the preferred update method for existing users to save massive bandwidth!)

Mac OS X users can download hunterk’s builds from this post on the libretro forum:

http://forum.themaister.net/viewtopic.php?pid=459#p459

Debian/Ubuntu/Mint users can add hunterk’s Launchpad PPA repository to their Synaptic/apt sources:

https://launchpad.net/~hunter-kaller/+archive/ppa

iOS users can find RetroArch iOS in one of Cydia’s default repositories – ZodTTD & MacCiti.

You can also add our own Cydia repository in order to get it, located at:

http://themaister.net/cydia

Most cores will work with both tethered and untethered jailbreaks, but cores that require the use of a dynamic recompiler (dynarec; DeSmuME and PCSX-ReARMed) will require a full, untethered jailbreak to function.

Android users can get the latest version from the Google Play Store. Xperia play controls seem to be wonky, but we hope to have that fixed very soon.

Wii users should use this package:

https://anonfiles.com/file/4536ac12f0071a397b2f1d70672814cf

Blackberry Playbook users should use this package:

http://themaister.net/retroarch-dl/blackberry/playbook/RetroArch-1_0_0_1.bar

Blackberry 10 users should use this package:

http://themaister.net/retroarch-dl/blackberry/bb10/RetroArch-Cascades-1_0_0_1.bar

PS3 users can get the DEX and CEX versions from the usual sources.

Xbox1 and Xbox360 users can get their respective versions from the usual sources.

OpenPandora users can get builds from lifning’s repo:

http://repo.openpandora.org/?page=detail&app=retroarch.lifning.001