Super Mario 64 Emulation on Linux

5 minute read

A friend of mine has been speedrunning The Legend of Zelda: Ocarina of Time (OoT) for a while now. Not too long ago a friend of his began speedrunning OoT as well, but also has been running Super Mario 64 (SM64). OoT didn’t really appeal to me, but SM64 does. I used to play a lot of NES emulators in high school and had some N64 emulators, but that was still when those were relatively new.

I decided that I wanted to try settings up SM64 to run on linux, and stream to twitch.tv, partly to try speedrunning and partly because getting things configured to work on linux is always enjoyable for me.

Emulator

It began with the choice of emulator, a quick search turned up Mupen64Plus, I downloaded the binary 64-bit version, downloaded some dependencies (minizip 1.2.8-1 and libpng15), dug up an old rom file for SM64 and it started up no problem!

Configuring the Controller

A lot of people run on a Wii, and if they do they’re probably using a Gamecube controller. My friends use a Gamecube controller to USB adapter. Not having a Gamecube controller here or the adapter I wanted to use my Xbox 360 controller.

It turns out that the 360 controller is working out of the box on Arch Linux, and Mupen64Plus has a default configuration for it, however, that configuration is really messed up. The configuration can be a little confusing, as there is a controller config in ~/.config/mupen64plus, however this is regenerated every time you start up mupen64plus, so editing this won’t get you much.

When you first download the binary, there is a file, InputAutoCfg.ini, which has the presets for the controllers. This gets installed in /usr/local/share/mupen64plus after running ./install.sh. We must now edit that copy to have changes stay across sessions.

In searching around for the above info on where to change configurations for the 360 controller I found this issue: https://code.google.com/p/mupen64plus/issues/detail?id=576

Detailed here is someone’s fix for the controller settings. A few of things I noticed myself right away was that Z and R were mapped to the 360’s L, so in SM64 you’d always change cameras when trying to long jump, not good.

Fixing the Defaults

For completeness here are the default controls. Several fixes need to be applied, which we’ll walk through step by step.

[Microsoft X-Box 360 pad]
[Win32: Controller (XBOX 360 For Windows)]
[Win32: XBOX 360 For Windows (Controller)]
[Win32: XBOX 360 For Windows]
[Xbox 360 Wireless Receiver]
[OSX: Wireless 360 Controller]
[OSX: Controller]
[Linux: Xbox Gamepad (userspace driver)]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(7)
Z Trig = axis(2+)
B Button = button(2)
A Button = button(0)
C Button R = axis(4+)
C Button L = axis(4-) button(3)
C Button D = axis(3+) button(1)
C Button U = axis(3-)
R Trig = button(5) axis(2-)
L Trig = button(4)
Mempak switch = 
Rumblepak switch = 
X Axis = axis(0-,0+)
Y Axis = axis(1-,1+)

Problems

  • The right trigger is double mapped. button(5) is the right bumper on the 360 controller, and axis(2-) is triggered when you release the left trigger on the 360 controller. We’ll modify this by having just R Trig = button(5).

Before:

R Trig = button(5) axis(2-)

After:

R Trig = button(5)
  • The C-Stick is backwards, in the sense that vertical movement corresponds to horizontal directions. So we want to swap the 3’s and 4’s here. Button’s 3 and 1 are Y and B, respectively. I’m still not sure if I’ll use the button(3) and button(1) mappings, so I’ll leave them as is for now.

Before:

C Button R = axis(4+)
C Button L = axis(4-) button(3)
C Button D = axis(3+) button(1)
C Button U = axis(3-)

After:

C Button R = axis(3+)
C Button L = axis(3-) button(3)
C Button D = axis(4+) button(1)
C Button U = axis(4-)
  • Finally, the D-Pad, I’m not sure what hat(0 Right) is, but it’s not doing anything for the D-Pad. We’ll add that functionality.

Before:

DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)

After:

DPad R = hat(0 Right) button(12)
DPad L = hat(0 Left) button(11)
DPad D = hat(0 Down) button(14)
DPad U = hat(0 Up) button(13)

Now, I’m not actually sure the D-Pad does anything in SM64, it was pretty useless on the N64 controller originally, so I’m not too worried about it. Even with these configurations, it’s not doing anything.

Casting Software

So all I basically looked at here was the Arch Wiki page for streaming, which resulted in me downloading castawesome through the AUR. The AUR dependencies had things taken care of and it ran no problem. Someone on a twitch chat had suggested using ffmpeg directly, which is also detailed on the Arch Wiki.

Timers

The last step was a timer. I tried Llanfair, as it’s written in Java and had a jar file I could run natively. This had some issues though, the first of which I noticed was when moving it around it would glitch out and move where ever it wanted to. Then I started having issues with text clipping, so I jumped ship and moved to trying to get LiveSplit working with WINE.

LiveSplit and WINE

This was probably the most involved step, as I had to install WINE, then figure out dependencies for LiveSplit. I’ll assume you have WINE installed on whatever system you’re running. We’ll then make a 32-bit WINEARCH and a new WINEPREFIX for livesplit.

WINEARCH=win32 WINEPREFIX=~/.livesplit winecfg

Then we need to install .NET 4.0 and some other things like msxml3 and corefonts. The -q option does the install without bothering you.

WINEARCH=win32 WINEPREFIX=~/.livesplit winetricks -q msxml3 dotnet40 corefonts

Now we can download the latest version of LiveSplit here: http://livesplit.org/downloads/

WINEARCH=win32 WINEPREFIX=~/.livesplit wine ~/speedruns/Livesplit_1.4.5/LiveSplit.exe

You should change out the directory I use for the one you’re keeping your .exe of LiveSplit in.

Wrapping Up

That should be it, we have Mupen64Plus emulating a SM64 rom, we fixed some Xbox 360 controller issues that were misconfigured on default, we installed castawesome to stream to twitch.tv, and finally got LiveSplit working under WINE. I’ve added some aliases to my .bashrc file as below, and now just run three simple commands, hit the “on” button in castawesome, and I’m streaming.

alias sm64='/home/USER/speedruns/mupen64plus-bundle-linux64-2.0/mupen64plus --resolution 1024x768 /home/USER/speedruns/roms/sm64.z64'
alias split='WINEARCH=win32 WINEPREFIX=~/.livesplit wine /home/USER/speedruns/Livesplit_1.4.5/LiveSplit.exe'

Happy Speed Running!

Revisit

So I wrote this as I configured my linux streaming setup, but didn’t publish it until now. In the time since I have abandoned the linux setup and moved over to Windows, primarily for the streaming software. castawesome was resulting in some pretty poor stream quality. The lack of configurability there lead me to change. And since I play most of my other games on Windows (and often times the reboot alone stops me from playing games) I’m fine with moving platforms. I hope someone out there finds this helpful, and if you do, let me know in the comments.

Updated: