Thursday, 31 December 2020

Game Emulation Options on Linux

Emulation for old games, particularly on Linux, can be a bit of a difficult area to navigate. Whilst there are nice standalone setups like retropie, it does need a Raspberry Pi and a display. For those looking to run emulation on their normal OS will have the option of programs like Retroarch, mame and FB Neo. But where to start?

Retropie

This is an SD image that can be loaded for a RPi - it is built on top of RPi's raspbian and uses RetroArch for emulation and EmulationStation to manage the UI. This setup is not easily runnable outside of RPi but it works well for RPi.

RetroArch

This is a nicely polished interface that uses cores to provide the supported emaulators. It provides an every growing set of preconfigured controllers that can be automatically download although if your controller is not availble, you can set it up locally. The cores are libretro maintained forked or periodicallyed sync with various upstreams projects.

Compiling this can be a litle messy as its modular and split across a number of source repos. The main repos:
$ git clone https://github.com/libretro/retroarch && cd retroarch && git checkout v1.9.0 $ ./configure --enable-libusb --enable-udev && make install
Once installed, you may want to download assets and change the UI to the rgui interface under Settings since a number of tutorials will show this interface. Also ensure that the input for joystick is set of udev so plugable devices are made available to RetroArch
$ git clone https://github.com/libretro/libretro-super && cd libretro-super $ for i in fbneo snes8x2010 dosbox vice-x64; do ./libretro-fetch.sh $i && ./libretro-build.sh $i done ./libretro-install.sh
Install the foo_libretro.so and corresponding .info to ~/.config/retroarch/cores/. For some emulators, I've seen problems. The DOSbox and vice emulators seem to fail playing some games even though they work in standalone emulators on the same linux host.

Recording walkthroughs

On my machine, I have a NVidia card that is supported by ffmpeg for hardware video encode. This is useful as RetroArch can record video of the games being played via ffmpeg. By default RetroArch uses libx264 to encode the video in software. By adding ~/.config/retroarch/records_config/nv.cfg
vcodec = h264_nvenc pix_fmt = yuv420p #video_ffmpeg option = ... #video_preset = llhq #video_profile = main #video_rc = vbr
To verify what additional options are available ffmpeg -h encoder=nvenc

On the Settings -> Record ensure that Use GPU is set to false - with this enabled it captures the post processed frame but this can slow down the actual game, even though the recorded output plays normally

Controllers

RetroArch has a notion of a virtual controller - this is what the internal keys are mapped to but real controllers need their inputs mapped to the virtual controller. The controller inputs are community contributed and can be automatically downloaded but new items awaiting PR in its repo will not be available.

RetroArch will decide which controllers map to player 1 and 2 etc and depends on plug-in order and also USB name if both are inserted on startup - since you can not map the /dev/input/js* device nodes via udev for persistent names, you have to use the Settings -> Input -> Port 1 Controls -> Device Index to toggle to the joystick required for player 1 each time the process starts. Also note that it appears that even with multiple joysticks connected only Player 1 can control the menu via the controller although keyboard and mouse inputs can also control menu.

Adding ROMs

Once you add your ROMs, say into /export/roms/fba, they need to be discovered by RetroArch - the most repeatable way is documented here and reproduced:
1. Open RetroArch 2. Update Databases in "Main Menu > Online Updater" (not 100% sure this one is required) 3. Go to "Import Content > Manual Scan" 4. Fill it : - Content Directory = /export/rom - System Name = choose "FBNeo - Arcade Games" - Default Core = choose "Arcade (FinalBurn Neo)" - Arcade DAT File = download and use this file 5. The remaining can be left at default, but consider turning on "Overwrite Existing Playlist" if you are updating an existing list 6. Select "Start Scan" 7. Go back, you should have a FB icon with your new playlist inside

FB Neo

This is the upstream for the FBNeo RetroArch core and available as FBNeo. Whilst it's an option to use this as a standalone, I've used the RetroArch version for the easy of use. The linux SDL2 build isn't inutiative so I quickly lost interest given the easier (RetroArc) alternatives.

Pre build binaries are available - for Windows its a standalone zip that can be run standalone but I wasn't able to persist configurations.

mame

This is one of the best old school emulators, striking for component accuracy - its interface is minimal and functional although as of version 0.177 became a little more picky for the ROMs, with many needing to be redumped which may have some implications for your old game cartridges.

Compiling subset of arcade support

The mame is a monolithic binary with compiled in support for different arcade boards and games. Compiling this cna take some time and be relatively large when you don't need all functionality.
$ git clone https://github.com/mamedev/mame && cd mame \ make REGENIE=1 SOURCES=src/mame/drivers/cps2.cpp,src/mame/drivers/cps3.cpp,src/mame/drivers/cps1.cpp,src/mame/drivers/capcom.cpp,src/mame/drivers/snes.cpp && \ make install

Setting up multiple controllers

mame can handle multiply configured controllers that may not be always plugged in via its controller configuration. Firstly, you will need to identify the controller's identifier as seen by its GUID or device id
$ mame -v ... Joystick: Start initialization Input: Adding joystick #0: MY-POWERCO.,LTD.USBJoystick (device id: 030000008f0e00000300000010010000) Joystick: MY-POWER CO.,LTD. USB Joystick [GUID 030000008f0e00000300000010010000] Joystick: ... 5 axes, 12 buttons 1 hats 0 balls Joystick: ... Physical id 0 mapped to logical id 1 Joystick: ... Has haptic capability Joystick: End initialization ..
Use normal means to set the controls for each controller and create a consolidated controller file that is referenced by ~/.mame/mame.ini sections:
ctrlrpath /usr/share/mame/ctrlr ctrlr default
and finally the /usr/share/mame/ctrlr/default.cfg. The following will always map certain controllers to certain ports - ie the Hori stick is always mapped to player 1.
<mameconfig version="10"> <system name="default"> <input> <!-- PS2 type generic controller --> <mapdevice device="030000008f0e00000300000010010000" controller="JOYCODE_2"> </mapdevice> <!-- HORICO.,LTD.RealArcadeProS --> <mapdevice device="030000000d0f0000aa00000011010000" controller="JOYCODE_1"> </mapdevice> <!-- Hori NSwitch fighting stick mini 2 aka GenericX-Boxpad --> <mapdevice device="030000000d0f00003701000013010000" controller="JOYCODE_3"> </mapdevice> <port type="P1_JOYSTICK_UP"> <newseq type="standard"> JOYCODE_1_HAT1UP </newseq> </port> <port type="P1_JOYSTICK_DOWN"> <newseq type="standard"> JOYCODE_1_HAT1DOWN </newseq> </port> <port type="P1_JOYSTICK_LEFT"> <newseq type="standard"> JOYCODE_1_HAT1LEFT </newseq> </port> <port type="P1_JOYSTICK_RIGHT"> <newseq type="standard"> JOYCODE_1_HAT1RIGHT </newseq> </port> <port type="P1_BUTTON1"> <newseq type="standard"> JOYCODE_1_BUTTON1 </newseq> </port> <port type="P1_BUTTON2"> <newseq type="standard"> JOYCODE_1_BUTTON4 </newseq> </port> <port type="P1_BUTTON3"> <newseq type="standard"> JOYCODE_1_BUTTON6 </newseq> </port> <port type="P1_BUTTON4"> <newseq type="standard"> JOYCODE_1_BUTTON2 </newseq> </port> <port type="P1_BUTTON5"> <newseq type="standard"> JOYCODE_1_BUTTON3 </newseq> </port> <port type="P1_BUTTON6"> <newseq type="standard"> JOYCODE_1_BUTTON8 </newseq> </port> <port type="P1_START"> <newseq type="standard"> JOYCODE_1_BUTTON10 </newseq> </port> <port type="P2_JOYSTICK_UP"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_JOYSTICK_DOWN"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_JOYSTICK_LEFT"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_JOYSTICK_RIGHT"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_BUTTON1"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_BUTTON2"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_BUTTON3"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_BUTTON4"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_BUTTON5"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_BUTTON6"> <newseq type="standard"> NONE </newseq> </port> <port type="START1"> <newseq type="standard"> JOYCODE_1_BUTTON10 </newseq> </port> </input> </system> </mameconfig>
To use the controller connfig run as mame -ctrlr default which will search for the default configuration in the specified controller directories.

No comments:

Post a Comment