snes9x-1.39-rpi -- full speed SNES emulation with sound


176 posts   Page 1 of 8   1, 2, 3, 4, 5 ... 8
by palerider » Mon Nov 19, 2012 6:45 pm
Hi all,

I have ported an old SDL version of snes9x to the Raspberry Pi. The PocketSNES core from libretro refused to work well on my machine and snes9x-1.53 is too slow, so I did this thing. It may be of use to some of you!

Get it here!

Here's a YouTube video of this build in action (with some pretty annoying audio pops that I couldn't figure out how to get rid of, but they are not from the Pi):

http://www.youtube.com/watch?v=Jo5wRLz2_R0

At the end of the video, you can see Master System and Game Gear games being run on OsmOse, another emulator I am currently porting to the rPi. It works fine at 100% speed with sound, but has issues with sound synchronization that I need to sort out before releasing it.

I'm posting the text of the included file readme.rpi below:

Code: Select all
snes9x-sdl-1.39-rpi20121119
~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is a quick and dirty Raspberry Pi port of snes9x 1.39. It is based on
an SDL port to the Dingoo game console, with the Dingoo specific stuff
removed and some Raspberry Pi specific stuff added. It should work at very
nearly full speed with sound, without overclocking your Pi. It requires
very little video memory; a 16 MiB split is fine.

1.39 is an ancient build of snes9x that has little in common with the great
new versions. Hence, the sound emulation is not great. snes9x 1.39 has the
old snes9x sound core which is not very accurate, but is MUCH speedier than
the new, accurate snes_spc core. With the Raspberry Pi I have been unable
to achieve playable speeds with snes9x 1.53, so until someone does some
pretty heavy optimization work on that code, 1.39 is a reasonable stop-gap
measure, I think.

Besides some light porting work to make it work well on the Raspberry Pi,
I've also added basic SDL joystick support, which was previously not in
this build. You may assign all the SNES buttons to your joypad, as well as
"exit" and "turbo" buttons.

SUPER FX GAMES DO NOT WORK. Sorry. This means no Yoshi's Island or Star Fox
until further notice. Support for the SNES mouse, Super Scope and Justifier
lightguns may or may not work -- probably not. Untested.


KEYS:
~~~~~
These are the default keys. You can't reassign them without a recompile
at the moment, sorry about that.

   SNES A:      D
   SNES B:      C
   SNES X:      S
   SNES Y:      X
   SNES L:      A
   SNES R:      F
   SNES Start:   Return
   SNES Select:   Tab
   SNES D-pad:   Arrow keys
   Turbo:      Backspace
   Quit:      Escape


If you want to change the keys you need to edit unix/keys.h and then re-
compile. Please see http://www.libsdl.org/cgi/docwiki.cgi/SDLKey for a
list of key symbols you may use.


JOYSTICK BUTTONS:
~~~~~~~~~~~~~~~~~
Same deal here, at the moment you need to edit a header file and recompile
to redefine the joystick buttons. The defaults are not likely to make
sense for you unless you have a digital Thrustmaster Firestorm 12-button
controller. :)

To find out which joystick buttons and axes are which, do:

    $ sudo apt-get install joystick

Then:

    $ jstest /dev/input/js0

Test and write down. Edit unix/joydef.h and then recompile. Future versions
will make this stuff not require a recompile.


COMPILING:
~~~~~~~~~~
If you are willing to live with the default key and joystick mappings, you
should just be able to run the snes9x binary that comes in the distribution
-- as long as you have all the required libs. If you want to compile, do:

    $ sudo apt-get update && sudo apt-get install libsdl-dev
    $ make

That should be it, at least as long as you're running Raspbian 2012-10-28,
which is the version I've been testing on. This will produce a "snes9x"
binary in the source directory. Copy it to wherever you want.


PLEASE NOTE:
~~~~~~~~~~~~
* Do not run from X. This is an SDL port built with the Raspberry Pi
  framebuffer in mind.


* This version of snes9x does not have the capability to scale the output
  image right now, and it is hardcoded to try to set a 320x240x16 mode.
  Therefore, if you want full-screen video, it is important that you have
  a corresponding mode in /etc/fb.modes. I use composite output and this
  works for me:

    mode "320x240"
        geometry 320 240 656 512 16
        timings 0 0 0 0 0 0 0
        rgba 5/11,6/5,5/0,0/16
    endmode

  Yes, 320x240 means 16 vertical pixels will be cut off. This is not
  unlike playing SNES on a real TV however, so it shouldn't really matter.
  Future versions may use a different and/or user selectable screen mode.


* snes9x-rpi is not ALSA aware, but requires OSS emulation. Using the
  kernel module does not seem to be a good idea, so use aoss.

    $ sudo apt-get install alsa-oss

  Then...


* Run with these switches for best results:

    $ sudo ./aoss snes9x-rpi -sy filename.smc

  You will need to futz around with the permissions for the sound devices
  or run the emulator as root, otherwise you will get no sound. For some
  reason this applies even if your user is in the audio group.

  -sy will attempt to sync audio to video. This means better sound, so I
  recommend to always launch the emulator with -sy.


* Currently, there just straight up ain't no configuration file. You'll
  have to pass command line arguments every time you start the emulator.
  Them's the breaks. Going to probably fix this in a coming release.


Enjoy, and if you have questions about how to use this, post here. It's really rough currently, I intend to make it better and release a more usable version shortly.
Posts: 8
Joined: Fri Nov 16, 2012 1:05 pm
by toxibunny » Mon Nov 19, 2012 8:14 pm
Seems to be the best yet, but you can see by the fps counter that there's still quite a few dropped frames there...
note: I may or may not know what I'm talking about...
Posts: 998
Joined: Thu Aug 18, 2011 9:21 pm
by palerider » Mon Nov 19, 2012 8:41 pm
Yes, depending on the game, it will not sustain 60 fps so I should probably not have written "full speed", but to me it certainly feels close enough while playing. Super Mario World sticks to 60 pretty much all the time. With further optimization it should be possible to squeeze out better performance. An overclocked Pi would help too, but personally I've had some bad experiences with file system corruption so I'm sticking to 700. Hearing about others' experiences would be helpful! :)
Posts: 8
Joined: Fri Nov 16, 2012 1:05 pm
by toxibunny » Tue Nov 20, 2012 12:04 am
Oh, that's just at 700mhz? Well I'm even more impressed...
note: I may or may not know what I'm talking about...
Posts: 998
Joined: Thu Aug 18, 2011 9:21 pm
by billb » Tue Nov 20, 2012 12:38 am
Nice monitor! ;)
User avatar
Posts: 173
Joined: Wed Sep 19, 2012 10:27 pm
by CPOKashue » Tue Nov 20, 2012 5:10 am
It's also worth pointing out the ACTUAL SNES didn't always manage an optimal frame rate. Pretty much any game that used the hardware expansion pins was guaranteed to dip a little bit. Remember Megaman X3, with the pretty particle contrail on the charged shots?

Anyhow, this is pretty impressive. It may even compel me to move beyond the 8 bit era!
Posts: 52
Joined: Fri Sep 28, 2012 6:13 pm
by Vanfanel » Tue Nov 20, 2012 9:06 am
Snes9x 1.39 has horrible sound. Even music is out of tempo in many games...
Why not port a more recent version instead?
Posts: 244
Joined: Sat Aug 18, 2012 5:58 pm
by palerider » Tue Nov 20, 2012 10:23 am
Vanfanel wrote:Snes9x 1.39 has horrible sound. Even music is out of tempo in many games...
Why not port a more recent version instead?

Well, as is written in the readme, I did do just that, and snes9x-1.53 reaches 12 fps at best, with stuttering sound. I have that too, if you're interested in trying it. I did some profiling of the binary and by far the largest portion of CPU time is taken by the new SPC700 emulation, snes_spc. It is very accurate and sounds great but unfortunately the Raspberry Pi is just too weak to run it at present.

So: I think snes9x-0.53 may be doable but it requires more knowledge than I possess. If someone ports snes_spc to ARM assembly that might do it ;)

billb wrote:Nice monitor! ;)

Thanks, I knew someone would take notice 8-)
Posts: 8
Joined: Fri Nov 16, 2012 1:05 pm
by Toad King » Tue Nov 20, 2012 4:24 pm
CPOKashue wrote:It's also worth pointing out the ACTUAL SNES didn't always manage an optimal frame rate. Pretty much any game that used the hardware expansion pins was guaranteed to dip a little bit. Remember Megaman X3, with the pretty particle contrail on the charged shots?

Anyhow, this is pretty impressive. It may even compel me to move beyond the 8 bit era!

Most SNES emulators still treat the games as 60 FPS, but pass unchanged frames back to the frontend in those cases.

Also, with the recent accuracy-focused direction Snes9x is heading, any modern version of it will never run fullspeed on the Pi. This I can pretty much guarantee.
User avatar
Posts: 156
Joined: Sun Dec 18, 2011 8:03 pm
by ro6er » Wed Nov 21, 2012 4:59 pm
Cool, had a quick go works really well. I'm guessing it's not possible to save yet?

Roger
User avatar
Posts: 24
Joined: Fri Oct 19, 2012 6:26 pm
by welshy » Wed Nov 21, 2012 6:01 pm
palerider
Good Job! Thanks for posting! I too have been experimenting with getting a decent SNES emulator running on RPi (Excluding the Retroarch approach!). My line of attack was to find a version of snes9x-sdl previous to v1.53 (Which as you stated, is horrendous, but, “acceptable” if you adjust the “framerate against frameskip” plus the advantage of perfect sound (Well, on my build anyway!), fullscreen in Console (Without any settings or config changes) and will play ANY DSP/SuperFX powered game, but subsequent to v 1.39 (Which I also had compiled but working WITHOUT sound!). Reading the changes documentation, snes9x started to use drivers “other” than oss on UNIX/Linux around v 1.42), but, as yet, I haven’t procured an sdl “flavoured” source (Maybe there isn’t one!?)
As Toad King rightly says, when NEW versions of emulators are released its usually for “accuracy”, rather than “performance” optimisation! That’s emulation for you, so often a “compromise”!
Posts: 1229
Joined: Mon Oct 29, 2012 2:07 pm
by palerider » Wed Nov 21, 2012 6:34 pm
ro6er wrote:Cool, had a quick go works really well. I'm guessing it's not possible to save yet?

Saving does work, if you mean save RAM! Savestates should also work, try keyboard number keys 0-9 to load. Hold shift and an number key to save.

welshy wrote:Good Job! Thanks for posting! I too have been experimenting with getting a decent SNES emulator running on RPi (Excluding the Retroarch approach!). My line of attack was to find a version of snes9x-sdl previous to v1.53 (Which as you stated, is horrendous, but, “acceptable” if you adjust the “framerate against frameskip” plus the advantage of perfect sound (Well, on my build anyway!), fullscreen in Console (Without any settings or config changes) and will play ANY DSP/SuperFX powered game, but subsequent to v 1.39 (Which I also had compiled but working WITHOUT sound!). Reading the changes documentation, snes9x started to use drivers “other” than oss on UNIX/Linux around v 1.42), but, as yet, I haven’t procured an sdl “flavoured” source (Maybe there isn’t one!?)
As Toad King rightly says, when NEW versions of emulators are released its usually for “accuracy”, rather than “performance” optimisation! That’s emulation for you, so often a “compromise”!

Thanks for the comments!

What I actually am planning to do is to probably abandon this 1.39 tree and instead go straight to porting 1.51. snes9x-1.51 was the last version that did not use the new sound emulation core, but it should still be heaps better than 1.39 in many ways. There is no existing SDL port that I've found, but it seems straightforward enough to do one. I've also found that there is a port of the old SPC700 core to ARM assembly, which I am going to try to integrate if possible. That should give some pretty blazing performance; as I said, the sound emulation is some of the most expensive processing in the whole affair. The cost for rendering the video screen is pretty negligible in comparison, so there appears to be no use in porting snes9x to OpenGL ES (I saw valiant efforts being made to do just that in another thread here, but to little avail unfortunately.)
Posts: 8
Joined: Fri Nov 16, 2012 1:05 pm
by palerider » Wed Nov 21, 2012 6:38 pm
Toad King wrote:Also, with the recent accuracy-focused direction Snes9x is heading, any modern version of it will never run fullspeed on the Pi. This I can pretty much guarantee.

I do think 1.53 is doable, but it would take a lot of effort. A job for a skilled assembly programmer, to be sure.
Posts: 8
Joined: Fri Nov 16, 2012 1:05 pm
by Casty » Fri Nov 23, 2012 5:36 am
Just downloaded this and gave it a go... works pretty good! The speed is promising, I look forward to a proper release... just wish it would run Super FX!
Posts: 22
Joined: Fri Nov 23, 2012 3:40 am
by jose1711_ » Mon Nov 26, 2012 6:21 pm
nice work. any chance to see support for 2 joysticks?
Posts: 44
Joined: Sat Jul 21, 2012 10:03 am
by reidw » Tue Dec 04, 2012 7:18 am
I wanted to get this working with a PS3 dualshock 3 controller through usb. I found that I wanted to use the d-pad for directional movement rather than the default analogue stick. Unfortunately the dualshock d-pad gets mapped into the joystick device as 4 buttons instead of two axes, but snes9x (at least this version anyway) expects directional movement to come from axes not buttons.

I modified unix.cpp and joydef.h to allow buttons to map to movement and fix this problem, if anyone wants the code.

cheers,
Reid
Posts: 3
Joined: Thu Nov 29, 2012 8:04 pm
by edwinsage » Thu Dec 06, 2012 2:06 am
What do I need to add to joydef.h to define buttons for the D-pad? The way it is now it uses the joystick axes, but I want to use buttons. I mapped the other buttons correctly, but there aren't any #define lines for directional buttons.
The Art of Unix Programming: http://faqs.org/docs/artu/
User avatar
Posts: 11
Joined: Thu Dec 06, 2012 2:03 am
Location: Kalamazoo
by reidw » Thu Dec 06, 2012 8:04 am
Here's what you need to change to use the D-pad for directional control.

In joydef.h, add the following lines:
Code: Select all
#define JB_UP    <button id for your joystick / controller>
#define JB_DOWN    <button id for your joystick / controller>
#define JB_LEFT    <button id for your joystick / controller>
#define JB_RIGHT    <button id for your joystick / controller>


Use jstest to find out which button id to use.

In unix.cpp you'll see the following lines in the S9xReadJoypad function:
Code: Select all

   if (keyssnes[sfc_key[UP_1]] == SDL_PRESSED || joy_axes[JA_UD] == UP)      val |= SNES_UP_MASK;
   if (keyssnes[sfc_key[DOWN_1]] == SDL_PRESSED || joy_axes[JA_UD] == DOWN)   val |= SNES_DOWN_MASK;
   if (keyssnes[sfc_key[LEFT_1]] == SDL_PRESSED || joy_axes[JA_LR] == LEFT)   val |= SNES_LEFT_MASK;
   if (keyssnes[sfc_key[RIGHT_1]] == SDL_PRESSED || joy_axes[JA_LR] == RIGHT)   val |= SNES_RIGHT_MASK;


Change them to the following:

Code: Select all
   if (keyssnes[sfc_key[UP_1]] == SDL_PRESSED || joy_axes[JA_UD] == UP || joy_buttons[JB_UP])      val |= SNES_UP_MASK;
   if (keyssnes[sfc_key[DOWN_1]] == SDL_PRESSED || joy_axes[JA_UD] == DOWN || joy_buttons[JB_DOWN])   val |= SNES_DOWN_MASK;
   if (keyssnes[sfc_key[LEFT_1]] == SDL_PRESSED || joy_axes[JA_LR] == LEFT || joy_buttons[JB_LEFT])   val |= SNES_LEFT_MASK;
   if (keyssnes[sfc_key[RIGHT_1]] == SDL_PRESSED || joy_axes[JA_LR] == RIGHT) || joy_buttons[JB_Right])   val |= SNES_RIGHT_MASK;


Reid
Posts: 3
Joined: Thu Nov 29, 2012 8:04 pm
by edwinsage » Fri Dec 07, 2012 3:28 am
reidw wrote:Here's what you need to change to use the D-pad for directional control.

Ah, excellent. I guessed correctly on the labels to use in joydef.h, but unknowledgeable bumbling proved insufficient for the unix.cpp file.

Also, there are a couple of typos in the last line of the code you posted, but with some easy fixes I got it to work.

Code: Select all
if (keyssnes[sfc_key[RIGHT_1]] == SDL_PRESSED || joy_axes[JA_LR] == RIGHT) || joy_buttons[JB_Right])   val |= SNES_RIGHT_MASK;

should be
Code: Select all
if (keyssnes[sfc_key[RIGHT_1]] == SDL_PRESSED || joy_axes[JA_LR] == RIGHT || joy_buttons[JB_RIGHT])   val |= SNES_RIGHT_MASK;


Thanks, that works excellently!
The Art of Unix Programming: http://faqs.org/docs/artu/
User avatar
Posts: 11
Joined: Thu Dec 06, 2012 2:03 am
Location: Kalamazoo
by gregwar » Mon Dec 10, 2012 4:49 pm
Hello there,

First of all, thank you very much!
I have managed to get this working but i'm afraid i don't have any sound.

The game start and play. When i press ESC i can see thoses debug lines:

Code: Select all
/dev/dsp: No such file or directory
Sound device open failed


This append although I can easily play sound files with mplayer or even vlc.

I tried running the emulateur as root but it changed nothing.
Posts: 2
Joined: Mon Dec 10, 2012 4:34 pm
by welshy » Mon Dec 10, 2012 5:59 pm
gregwar
SNES9x-SDL-v1.39 is not ALSA aware, but requires OSS emulation. Check palerider's original post (or the readme.rpi file in his Binary) it gives instructions on how to get sound running!

I wrote a "Guide" for v1.53 Here - viewtopic.php?f=78&t=24318

Its runs ALSA sound (i.e. "Straight out of the box Sound"), however, the performance is inferior (Requires “liberal” use of frameskip to attain 60 FPS performance). Sound emulation is excellent and it will run ANY game enhanced by use of an “On Cart” additional processor (e.g. DSP-1: Super Mario Kart, SuperFX: StarFox/StarWing etc (v1.39 WILL NOT emulate SuperFX!) AND render “Fullscreen” without any config alterations.

I have also just posted a Thread regarding BSNES (Apparently its available from the Repo’s), this MAY be a better solution (I do know the rendering performance of the X86 version is superior to SNES9X!). Keep an eye on it to see if anyone posts a reply with some details!
Posts: 1229
Joined: Mon Oct 29, 2012 2:07 pm
by gregwar » Mon Dec 10, 2012 6:48 pm
thank you welshi
This will teach me to read readme files^^.
I'll give a try to Guide,
Posts: 2
Joined: Mon Dec 10, 2012 4:34 pm
by welshy » Mon Dec 10, 2012 7:15 pm
gregwar
No Probs! If you are into emulation (And are new to the Forum which it looks like you are!) please check out my other "Guides" for -

AdvMAME (Multiple Arcade Machine Emulator) - viewtopic.php?f=78&t=22403
AdvMESS (Multi Emulator Super System) - viewtopic.php?f=78&t=23113
AdvMENU (Emulator Front End) - viewtopic.php?f=78&t=23431
Atari++ (Atari 8Bit Computer Line) - viewtopic.php?f=78&t=24729
FBZX (Sinclair ZX Spectrum) - viewtopic.php?f=78&t=24910
GnGeo (Neo-Geo AES/MVS) - viewtopic.php?f=78&t=22302
Posts: 1229
Joined: Mon Oct 29, 2012 2:07 pm
by eix » Sat Dec 15, 2012 7:45 pm
palerider wrote:I've also found that there is a port of the old SPC700 core to ARM assembly, which I am going to try to integrate if possible. That should give some pretty blazing performance; as I said, the sound emulation is some of the most expensive processing in the whole affair.

palerider, would you mind participating also in this sister thread? I'd like to know if that's the port you were talking about, and also your feedback

Thanks
User avatar
Posts: 82
Joined: Sat Sep 15, 2012 8:09 am
by Raspiberry » Tue Dec 18, 2012 2:03 am
Not to sound too inexperienced, but how exactly do I use this?
I know how to compile, but how should I "get" the package? wget?
Then what?
If only my school used the Raspberry Pi...
User avatar
Posts: 20
Joined: Sun Dec 16, 2012 9:56 pm