Banana Pi / Arch Linux / SNES emulation using RetroArch

Introduction

This post is about getting RetroArch working on the Banana Pi running Arch Linux. I’m going to tell you, how to achieve a satisfying SNES emulation experience.

The first attempt installing the retroarch package and trying to emulate the good old Super Mario World was disappointing. It was completely messed up as I had less than one frame per second caused by the lack of hardware acceleration.

So I needed to build RetroArch for myself with OpenGLES hardware acceleration enabled. This way, the BPi is able to run most SNES roms quite well. Unfortunately the header files provided by the sunxi-mali Git Repository lack of GLchar definitions required when building RetroArch (see also this issue on Github). But its possible to use current header files from another machine to build successful (see below).

Building and installing

Clone the original RetroArch repository and run configure with appropriate arguments:

cd $HOME
git clone https://github.com/libretro/RetroArch.git
cd $HOME/RetroArch
./configure --enable-gles --disable-oss --disable-sdl --disable-netplay

If we would build right now, we’d get following errors soon:

CC frontend/frontend.c
In file included from frontend/menu/../../gfx/glsym/glsym.h:8:0,
nbsp;                from frontend/menu/../../gfx/gl_common.h:38,
                 from frontend/menu/../../gfx/shader_common.h:26,
                 from frontend/menu/menu_common.h:34,
                 from frontend/frontend.c:27:
frontend/menu/../../gfx/glsym/glsym_es2.h:7:1: error: unknown type name 'GLchar'

… and so forth…
This is because of the outdated gl2.h and gl2ext.h header files provided by sunxi-mali. We just going to use those from another machine. Just backup the existing files and copy the new ones from your desktop PC from/to the location /usr/include/GLES2.
I put them on Pastebin in case, some of you don’t have these header files: gl2.h and gl2ext.h.
So when you have the correct header files in /usr/include/GLES2 then we can continue building and installing:

make
sudo make install

Furthermore, you need a libretro implementation. There are plenty of implementations available at the AUR. To get a satisfying SNES experience, I suggest installing libretro-pocketsnes from AUR (keep in mind to add “armv7h” to the arch list in the PKGBUILD):

yaourt -S libretro-pocketsnes-git

When it’s done, you can test your RetroArch setup:

retroarch -L /usr/lib/libretro/libretro-pocketsnes.so [ROM_FILE]

Congratulations, you just gained nicely SNES emulation with RetroArch on your Banana Pi!


MegaMan X3

Zelda – A Link To The Past

Super Mario Kart

Super Mario World

Terranigma

As you see in the Mario Kart screenshot, glitches caused by libretro-pocketsnes are to be expected (the transparent placement is missing and the lifes are somehow messed). But all these games were definitely playable with appropriate frame rates.

14 comments:

  1. First of all big kudos to you for all the effort you put into this blog.

    It helped me a lot to get banana pi up and running, playing with the mali GPU acceleration etc., as it is my first experience with this kind of devices.

    I really appreciate the build-in SATA port and WiFi of banana pi so i don’t have to have hook it up to router or notebook (and share internet connectivity by bridging it).

    One of the first thing I wanted to tried was exactly this. Use Banana Pi for PS1, SNES, MAME emulation.

    I have some tips for people who might be struggling with being able to build and run RetroArch properly. In the current builds there are several feature which are broken and therefore preventing RetroArch from being compiled. Namely it’s networking and the cheevos (anticheat system). Therefore you need to add “–disable-networking” and “–disable-cheevos” to make it to the end of compilation.

    second is the libretro-pocketsnes core. The current version of the aur package (as is your suggestion) is broken and AFAIK the package has been abandoned, so the only way to make it work it is to build it manually from git (https://github.com/libretro/pocketsnes-libretro).

    I have tried some other SNES libretro-cores (i.e. snes9x-next, snes9x-sdl etc.) and also stand-alone version of snes9x and I must say all of them run pretty good but I would suggest to use snes9x-next over pocketsnes. Although pocketsnes is declared to be heavily optimized to run on ARMs i didn’t see any performance boost or better handling over snes9x-next, it even had many more graphic glitches (e.g. in Super Mario on both sides there were rectangle of the background being loaded when moving through the levels) it might to do only with proper settings of the RetroArch but I have not being able to examine this so close yet.

  2. I’m having issue compiling using Arch Linux on my Banana Pi. I’m 95% positive I have everything extra and all dependencies installed. I think this is a linking issue, but have no clue how to correct it. I have mostly been following your tutorials so I figured I would ask you first. I get these errors after compile. I have also posted the config line I am using. It is the same one you use above.
    ./configure --enable-gles --disable-oss --disable-sdl --disable-netplay
    obj-unix/input/drivers/udev_input.o: In function `udev_input_hotplug_available':
    /root/retroarch/RetroArch/input/drivers/udev_input.c:267: undefined reference to `udev_monitor_get_fd'
    obj-unix/input/drivers/udev_input.o: In function `udev_input_handle_hotplug':
    /root/retroarch/RetroArch/input/drivers/udev_input.c:352: undefined reference to `udev_monitor_receive_device'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:364: undefined reference to `udev_device_get_property_value'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:365: undefined reference to `udev_device_get_property_value'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:366: undefined reference to `udev_device_get_property_value'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:367: undefined reference to `udev_device_get_action'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:368: undefined reference to `udev_device_get_devnode'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:405: undefined reference to `udev_device_unref'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:405: undefined reference to `udev_device_unref'
    obj-unix/input/drivers/udev_input.o: In function `open_devices':
    /root/retroarch/RetroArch/input/drivers/udev_input.c:615: undefined reference to `udev_enumerate_new'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:620: undefined reference to `udev_enumerate_add_match_property'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:621: undefined reference to `udev_enumerate_scan_devices'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:622: undefined reference to `udev_enumerate_get_list_entry'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:641: undefined reference to `udev_device_unref'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:624: undefined reference to `udev_list_entry_get_next'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:626: undefined reference to `udev_list_entry_get_name'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:630: undefined reference to `udev_device_new_from_syspath'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:631: undefined reference to `udev_device_get_devnode'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:644: undefined reference to `udev_enumerate_unref'
    obj-unix/input/drivers/udev_input.o: In function `udev_input_init':
    /root/retroarch/RetroArch/input/drivers/udev_input.c:718: undefined reference to `udev_new'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:725: undefined reference to `udev_monitor_new_from_netlink'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:728: undefined reference to `udev_monitor_filter_add_match_subsystem_devtype'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:729: undefined reference to `udev_monitor_enable_receiving'
    obj-unix/input/drivers/udev_input.o: In function `udev_input_free':
    /root/retroarch/RetroArch/input/drivers/udev_input.c:591: undefined reference to `udev_monitor_unref'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:593: undefined reference to `udev_unref'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:591: undefined reference to `udev_monitor_unref'
    /root/retroarch/RetroArch/input/drivers/udev_input.c:593: undefined reference to `udev_unref'
    obj-unix/input/drivers_joypad/udev_joypad.o: In function `udev_add_pad':
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:230: undefined reference to `udev_device_get_parent_with_subsystem_devtype'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:234: undefined reference to `udev_device_get_sysattr_value'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:237: undefined reference to `udev_device_get_sysattr_value'
    obj-unix/input/drivers_joypad/udev_joypad.o: In function `udev_hotplug_available':
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:162: undefined reference to `udev_monitor_get_fd'
    obj-unix/input/drivers_joypad/udev_joypad.o: In function `udev_joypad_handle_hotplug':
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:412: undefined reference to `udev_monitor_receive_device'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:419: undefined reference to `udev_device_get_property_value'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:420: undefined reference to `udev_device_get_action'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:421: undefined reference to `udev_device_get_devnode'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:438: undefined reference to `udev_device_unref'
    obj-unix/input/drivers_joypad/udev_joypad.o: In function `udev_joypad_destroy':
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:403: undefined reference to `udev_monitor_unref'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:406: undefined reference to `udev_unref'
    obj-unix/input/drivers_joypad/udev_joypad.o: In function `udev_joypad_init':
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:533: undefined reference to `udev_new'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:537: undefined reference to `udev_monitor_new_from_netlink'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:540: undefined reference to `udev_monitor_filter_add_match_subsystem_devtype'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:541: undefined reference to `udev_monitor_enable_receiving'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:544: undefined reference to `udev_enumerate_new'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:548: undefined reference to `udev_enumerate_add_match_property'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:549: undefined reference to `udev_enumerate_scan_devices'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:550: undefined reference to `udev_enumerate_get_list_entry'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:554: undefined reference to `udev_list_entry_get_name'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:555: undefined reference to `udev_device_new_from_syspath'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:556: undefined reference to `udev_device_get_devnode'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:560: undefined reference to `udev_device_unref'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:552: undefined reference to `udev_list_entry_get_next'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:563: undefined reference to `udev_enumerate_unref'
    obj-unix/input/drivers_joypad/udev_joypad.o: In function `udev_joypad_destroy':
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:403: undefined reference to `udev_monitor_unref'
    /root/retroarch/RetroArch/input/drivers_joypad/udev_joypad.c:406: undefined reference to `udev_unref'
    collect2: error: ld returned 1 exit status
    Makefile:103: recipe for target 'retroarch' failed
    make: *** [retroarch] Error 1

  3. Hi there would you mind letting me know which hosting company you’re working
    with? I’ve loaded your blog in 3 different web browsers
    and I must say this blog loads a lot faster then most.
    Can you recommend a good internet hosting provider at a honest price?
    Thanks, I appreciate it!

    1. Hello gevolgen,
      I host my blog on a virtual root server by a German provider called 1&1. Most of the time it works nice, but I still cannot recommend it, as there are very limited resources. Only a few server processes simultaneously are working stable for a long time.

  4. Hi Ryad!
    This is very great!
    Can you help me a little with the controls?
    I was able to start a game and with F1 the setup(RGUI) shows and done the binding in setup-input options – User1, but I can’t move inside the game, only in the menu…
    I used this configuration:
    Autodetect Enable off (with on, it’s the same)
    Bind Mode RetroKeyboard
    User 1 Device Type Retropad (I cannot get keyboard, but at the “bind all” option I was able to re-set the bindings)

    I tried to edit the
    /home/bananapi/.config/retroarch/retroarch.cfg
    and /etc/retroarch.cfg also, but it didn’t help…
    for input_libretro_device_p1 = “3”
    it shows:
    init_controllers :: Input device ID 3 is unknown to this libretro implementation. Using RETRO_DEVICE_JOYPAD
    although in the config file it says the keyboard should be 3. (with 0,1,2 it’s also not working…)

    I’m using an USB keyboard.

  5. Hi,

    do you have an idea about getting decent und playable fullscreen fps with sound?
    When I put Arch into Fullscreen, the sound stutters and the fps drops down

    thanks

    1. Hello Carsten,

      To get a nice fullscreen experience with emulation, you might be interested in using the sunxi-mali driver in framebuffer mode. This means you will loose X11 compatibility. If you’re interested in using the framebuffer mode, I can recommend the forum thread of my friend Simon in which he explains step by step how to get everything up and running.

      If I find the time, I’m going to include some more details about the framebuffer more into this guide.

      Hope that helps,
      Ryad

    1. Hello Vushu,
      When I did this article, the latest sources from the master repository did just work. Possibly there are some issues with the latest sources. I’m glad, you could do it, with an older repository tag. If I find the time, I’ll try to investigate that issue and update this blog post.

      Thanks,
      Ryad

  6. Hello when i try to make i get this :
    obj-unix/command.o: In function `cmd_init_stdin’:
    /home/bananapi/RetroArch/command.c:112: undefined reference to `socket_nonblock’
    collect2: error: ld returned 1 exit status
    Makefile:88: recipe for target ‘retroarch’ failed

  7. This is great. I’m glad someone figured out how to get it working on the Banana Pi. The question I have, though, is does this version of RetroArch support more platforms than SNES? I’m really hoping to get one that does NES, SNES, Genesis, and possibly N64 and PS1. Also, does this support using the controller to navigate the menu, or is there something else I need to do in order to make that work?

    1. Hi Fornaxx,

      yes, this is the idea of RetroArch. RetroArch basically is just is a frontend, which aims to unite several emulators (the so called RetroArch cores) into one user interface. In this article, I present how to build the user interface and a SNES core. You are free to build all the cores that exist, including all you mentionend. In my blog post about PSX emulation I also showed how to build a PSX core, but I couldn’t get a satisfying result. As far as I know, it’s not possible to build a N64 (i.e. mupen64plus) core at the moment, as in contrast to the Raspberry there’s no hardware accelerated port for the BPi at the moment.

      I really can recommend the forum thread of my friend Simon. He presents how to build a dedicated retro emulation station using the BPi and RetroArch.

      RetroArch does support controller navigation out-of-the-box, but has to be configured using the “retroarch-joyconfig” tool.

      Best regards,
      Ryad

Leave a Reply

Your email address will not be published. Required fields are marked *