RetroArch 1.9.8 released!


RetroArch 1.9.8 has just been released.

Grab it here.

If you’d like to learn more about upcoming releases, please consult our roadmap here. The next version of Lakka (with an updated RetroArch 1.9.8 version) is scheduled to be released a week from today.

Remember that this project exists for the benefit of our users, and that we wouldn’t keep doing this were it not for spreading the love to our users. This project exists because of your support and belief in us to keep going doing great things. If you’d like to show your support, consider donating to us. Check here in order to learn more. In addition to being able to support us on Patreon, there is now also the option to sponsor us on Github Sponsors! You can also help us out by buying some of our merch on our Teespring store!

Highlights

New RetroFW port

We added support for OpenDingux before for JZ4770-based handhelds. After this, we added support for RetroMini RS-90 devices.

And now thanks to Poligraf, we have a working build for all the JZ4760-based handheld devices running RetroFW. RetroFW is a Dingoo based firmware runnin on the MIPS 4760 which is around 50% the speed compared to other devices running Opendingux.

Which devices does this cover?

  • RS-97
  • LDK
  • RG-300
  • Powkiddy Q80

A full listing can be found here.

  • 29 cores available at launch: Atari800, BlueMSX, Cap32, FCEUmm, fMSX, FreeCHAF, FreeIntv, FUSE, Gambatte, Genesis Plus GX, gpSP, GW, Handy, LRMAME2003, LRMAME2003 Plus, Mednafen PCE Fast, NXEngine, O2EM, Picodrive, Pokemini, Potator, Prboom, Prosystem, QuickNES, RACE, Retro8, SMS Plus, Stella 2014, Vecx

We have been told these cores all run well on the hardware.

All of these low powered handheld devices help us tremendously in optimizing our cores for the low end spectrum of hardware devices. gpSP, PCSX ReARMed and Picodrive are already starting to reap the benefits of it.

Core option categories

We are going to be making a persistent effort now to enhance RetroArch’s UX and lower the acessibility curve. To that end, we now have also implemented core option categories support.

Up to this point, every core option in a core (Quick Menu -> Options) has all been shown in a a flat alphabetical list. Users can quickly get confused if they have to scroll down a massive list of options.

So, 1.9.8 finally adds core option categories. Options assigned to a category will be displayed in a submenu of the main core options menu on supported frontends. For example – here we assign Gambatte’s mulitplayer options to a Game Boy Link category:

If you do not like this new behavior, there are always options to turn it off. Go to Settings > Core > Core Option Categories setting (enabled by default). When disabled, core option categories are ignored, and core options will effectively be displayed using the old v1 format.

Cores that already support core option categories

Core option categories have to be specifically added per core. Some of the cores that already support core option categories are as follows:

  • Final Burn Neo
  • Mupen64Plus Next
  • Beetle Saturn
  • Beetle PSX
  • Beetle PCE
  • Beetle PCE Fast
  • Genesis Plus GX
  • Snes9x 2010/2005/2002
  • DOSbox Pure
  • DOSbox Core
  • UAE (Amiga)
  • VICE (Commodore 64)
  • Have you ever noticed RetroArch starting a game in windowed mode and then blowing up the window to ridiculous sizes that exceeds the boundaries of your desktop? Well, we now have a solution for that!

    At present, when RetroArch is in windowed mode with Remember Window Position and size disabled, the window size will be equal to the core provided base_width/base_height multiplied by the Windowed Scale. This is potentially ‘catastrophic’: if a core has a very large base_width/base_height (e.g. PPSSPP with a x7 internal scale factor) and Windowed Scale is set to the default x3, then the window size can be enormous – potentially exceeding the capacity of the host GPU and causing RetroArch to crash.

    1.9.8 adds two new options:

    • Settings > Video > Windowed Mode > Maximum Window Width (default: 1920)
    • Settings > Video > Windowed Mode > Maximum Window Height (default: 1080)
      …which can be used to cap the maximum window size to a ‘sane’ value.

    The PR also cleans up the Settings > Video > Windowed Mode menu, auto-hiding options where required, and re-initing drivers when toggling Remember Window Position and size. Also, since the ‘remember’ part of Remember Window Position and size is only enabled for Windows, an alternate Use Custom Window Size is provided on other platforms.

    Auto-updating core option menu visibility updates without toggling Quick Menu

    Cores are able to show or hide their options via the RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY callback on supported fontends. A significant shortcoming here is that if a change to one core option (via the frontend) affects the visibility of another option, the frontend cannot update the menu state until the core has run for at least one frame. So with the core options menu open, visibility updates cannot happen in real-time – instead, the user must toggle the quick menu off then on before the menu will change. This is ugly and confusing.

    1.9.8 adds a new RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK environment callback which allows the core to register a function that enables the frontend to (a) force a core-side option visibility update and (b) allows the frontend to check whether option visibility has changed. This means all show/hide operations can now generate real-time menu updates.

    Windows

    Plenty of important fixes for Windows users.

    If you experienced lockups in the past when disconnecting an audio device while using the WASAPI audio driver, well, rejoice, this will no longer happen.

    Simultaneous shift sticky fixes were made to the DirectInput input driver. Dinput would not send WM_KEYUP for both Shifts if they were pressed together and released, resulting in sticky Shifts
    = Pinball games ruined in DOSBox.

    The following fix was made to the Windows RawInput driver – the Left Alt key could get stuck when Alt-Tabbing. No more. The keyboard can now also be mapped to analog input axes, meaning you can bind the left and right analog stick on the RetroPad to your keyboard keys.

    PlayStation2 version

    1.9.8 solves the flickering issues that appear in the cores that use the FRAME_SKIP as Snes9x2002 does.

    Also, 1.9.8 basically mounts HDD partition if RetroArch actually started from the HDD unit.
    In this way, we skip the mount partition if the user just wants to use USB.

    macOS/OSX version

    Plenty of important fixes for macOS users this time!

    There were several serious memory leaks with the Metal video driver. These have now been fixed.

    Serious bugs related to the input autodetection subsystem have finally been fixed. Now when you connect a gamepad, it will no longer try to attach the same pad to two controller ports simultaneously. This has been a longstanding bug that we’re glad has finally been consigned to the dustbin of history thanks to the help of a generous contributor who did quite some work to delve deep into this issue. We also made sure everything still works across a wide variety of macOS machines (from a PowerPC Mac running OSX 10.5 to an Intel and ARM Mac running more recent macOS versions).

    WiiU version

    Lots of improvements have been made once again to the WiiU port.

    All the libretro RPX cores are now compressed. Not only do they load faster (leading to faster startup times), but it means you have a lot more space left on your SD card.

    L3 and R3 buttons have been fixed on several gamepads, they were previously completely nonfunctional.

    Furthermore, promising work is underway for a PlayStation1 emulator core running on RetroArch WiiU. More on that later once more news is forthcoming.

    UWP/Xbox versions

    We have been fixing several bugs with the UWP port, many of these affecting in particular RetroArch users on Xbox One/Series.

    Microsoft recently released a new Dashboard update that caused some breakage for existing RetroArch installs.

    We have managed to fix the startup problem that occurred on the latest dashboard. We also fixed the onscreen keyboard display which was previously completely glitched out.

    Note that on the latest Dashboard, some compatibility problems still persist. For instance, it has been reported that several games on PCSX2 no longer work as of the recent update. This will require investigation and it is our guess if anything can be done about this, we will have to determine this after more investigation has occurred. For now, you might experience scaling issues with some of the ANGLE/GL powered cores like Mupen64Plus Next and Flycast because of the Dashboard update. We hope that we will be able to transition from ANGLE to something like GLon12 soon. What this would buy us is full desktop OpenGL support instead of just OpenGLES. This would mean a more complete superset of OpenGL (up to 3.3 from what we can hear), more cores that would work out of the box instead of custom cores made to work with ANGLE, etc. We will see if we succeed in this, but that’s something for a later version.

    In the meantime, we have also enabled Translation features. Note that we haven’t been able to implement the Text-to-Speech accessibility feature yet, but all other features should be there now for experimentation.

    We have also re-enabled the “Explore” tab on the Main Menu. We haven’t found any issues with this anymore after the recent bugfixes/improvements we made to the underlying database code, but let us know if there are any more issues on that front.

    Several cores that used the libretro VFS subsystem and/or CHD loading previously no longer worked. Examples include the Beetle cores. This has been fixed.

    Screen resolution settings improvements

    Currently the “Screen Resolution” list wrongly alters also video_refresh_rate to the rounded value, as in 59.940 Hz becomes 59.000.

    This change makes sure all the 59.94 multiples (59/119 etc) result in the proper float value instead of integer.

    Also, previously notifications when setting the refresh rate would repeat itself twice. This has been fixed.

    Changelog

    1.9.8

    • AUDIO/WINDOWS/WASAPI: Stop deactivating audio on fast forward
    • CHEEVOS: Hide challenge indicators when resetting
    • CHEEVOS: Support for more than 64 memory regions
    • CHEEVOS: Automatically retry ‘http error code -1’
    • CONTENT INFORMATION: Show content info label+path rows always
    • CORE OPTIONS: Core option categories implemented
    • CORE OPTIONS: Add option to disable core option categories
    • D3D10/11/12: Fix gfx_display_draw_texture – fixes OSK (On-Screen Keyboard) issues
    • DATABASE: Fix heap-buffer-overflow when fetching CRC values
    • DATABASE/EXPLORE: Fix CRC32 reading in explore menu
    • DATABASE/LIBRETRODB: Fix writing of numerical values
    • DATABASE/LIBRETRODB: Fix libretro-db loading on big endian platforms
    • DUMMY CORE: Skip state_manager_event_{deinit/init} when core type is dummy, should skip warning spam ‘Implementation uses threaded audio. Cannot use rewind..’ when using rewind
    • INPUT/UDEV: Limit udev device scan to subsystem ‘input’
    • INPUT/SDL2/WINDOWS: Fix keyboard event keycodes
    • INPUT/WAYLAND: Fixes a bug where the first player’s mouse, pointer, and lightgun are echoed to the other ports. Now, those other ports correctly report zero. In the future support for multiple mouselike devices will need to be added, which is a bigger project
    • INPUT/WAYLAND: The driver now respects keyboard_mapping_blocked
    • INPUT/WAYLAND: When possible, deprecated lightgun defines are replaced with the new ones. The coordinates are still using the old relative callbacks
    • INPUT/WINRAW: Trigger joypad driver reinit on DEVICECHANGE – avoids fullscreen toggle
    • INPUT/WINRAW: Alt sticky fix
    • INPUT/WINRAW: Prevent Alt getting stuck when Alt-Tabbing
    • INPUT/WINRAW: Add pointer status
    • INPUT/WINRAW: Add missing analog keybinds
    • LIBNX/SWITCH: Fix poll missing for controller 2-8
    • LIBNX/SWITCH: Fix layout not applied correctly and hangs when splitting joycons
    • LIBRETRO: Core options category API implemented
    • LIBRETRO: Fix RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE callback when runahead is enabled
    • LIBRETRO: Add environment callback for enabling core option menu visibility updates without toggling Quick Menu
    • LOGGING: Starting logging and verbose mode before first config load
    • LINUX: In some Linux Desktop Environments, like Budgie, task bar feature is unable to pin applications. With StartupWMClass= present in .desktop file, it is possible to pin the application
    • LOCALIZATION: Fetch translations from Crowdin
    • MENU: Relocate ‘Manage Playlists’ to top
    • MENU: Fullscreen resolution width/height settings no longer require ‘advanced settings’
    • MENU/REFRESH RATE: Fix double notifications with refresh rate settings
    • MENU/OZONE: Ensure the existence of values used in selection calculation
    • MENU/OZONE/VULKAN: Casting to unsigned caused an integer overflow and after float promotion would lead to ‘x’ being a garbage value, leading to problems when this value was passed to vkCmdSetViewport. This stops Vulkan validation layers from complaining about it
    • METAL: Fixed font driver memory leaks
    • MOUSE: Change default mouse index to port index
    • MOUSE: Friendly names for mice where available
    • OSX: Fix some memory leaks
    • OSX: Fix controller duplication bug
    • PS2: Implement alpha for the video driver
    • PS2: Aspect ratio handling
    • RETROFW: Initial port
    • UWP/XBOX: Enable Explore tab by default – seems to work fine
    • UWP/XBOX: Fix startup issues with latest Xbox Dashboard updates – ANGLE cores still show up wrong
    • UWP/XBOX: fix issue where files where opened as OPENALWAYS instead of OPENEXISTING this fixes beetle cores
    • UWP/XBOX: fix issue where filesizes where not returned properly, this fixes loading arcade dat files
    • UWP/TRANSLATION: Enabled translation services for both UWP MSVC2017 and 2019. No TTS speech yet.
    • VIDEO: Fix refresh rate 59Hz rounding
    • WINDOWS: Remember original refresh rate
    • WINDOWS/VULKAN: Refresh rate fixes + cleanups
    • WIIU: Fix L3/R3 buttons
    • WIIU: Compress RPX libretro cores
    • WIIU: Add ICInvalidateRange (necessary for JITs)
    • WIIU: Slight filesystem optimisation
    • WIIU: Add option for running without core info (emscripten-style)

    What’s next

    It has been often requested during our project’s history, but yes, we finally want to do something on the UI/UX front. We have been considering introducing an ‘Easy Mode’ that should aim at making things much less of a maze to navigate for non savvy users.

    Stay tuned for more info!

Miniretro: testing emulators at scale

This is a guest article written by David GF Net republished with his authorization. Original blog article can be viewed here.

Last year I got involved in Libretro/Retroarch development after buying an Odroid Go Advance. During this time I’ve been working mainly on gpsp and porting it to new devices and such.

One of the main issues about working in software is testing, and as you can probably imagine there’s no tests in most emulators. Partly due to bad practices and because it’s hard to write tests for them. That’s why I came up with miniretro. It is a libretro frontend designed for headless operation, so that it can be used for end-to-end/integration testing. The frontend runs a core and a rom with fake inputs and grabs the output.

Cross platform testing

Some of the emulators (like gpsp) feature a dynamic recompiler (aka dynarec), which have platform specific (CPU, OS and/or device specific) backends targeted at them. These can translate original console instructions into your device’s instruction set (for speed). Since this is device specific, it’s hard to write, debug and test. One needs a toolchain for the platform and a physical device to test it. Or at least that’s the theory!

With miniretro it gets easier to test other platforms like for instance ARM and MIPS devices. Since it is simple (almost no dependencies) and just a Linux binary, we can use Qemu userspace emulation to run our tests! This way there’s not need for a physical device, nor manual testing.

The following diagram shows how it works: miniretro and the libretro core are built for the specific device/architecture and they run under qemu. Qemu takes care of translating syscalls into host syscalls, so there’s no need for a whole OS to run the program. Miniretro can open pipes and other IPC communication channels to input/output any data.

Diagram of Miniretro running under Qemu

Just as an example, let’s build picodrive, gpsp and pcsx for armv6 and mips32. To do this you will need a toolchain. In my case I’ve been using some Linux-generic toolchains for a variety of platforms, such as ARM, MIPS, x86 and PowerPC, freshly built using Buildroot (you can find them at my Copr if you use Fedora, see this repo). This, coupled with the regular Qemu userspace emulators (available in most Linux distros), enables us to test our emulators on a bunch of platforms effortlessly.

# Build the three emus for arm and mips
git clone –recurse-submodules https://github.com/irixxxx/picodrive.git && cd picodrive
make platform=armv CC=/opt/buildroot-armv6el-eabi-uclibc/bin/arm-linux-gcc -j10 -f Makefile.libretro all && \
mv picodrive_libretro.so picodrive_libretro_arm.so && make -f Makefile.libretro clean
make platform=unix CC=/opt/buildroot-mipsel32-o32-uclibc/bin/mipsel-linux-gcc -j10 -f Makefile.libretro all && \
mv picodrive_libretro.so picodrive_libretro_mipsel.so && make -f Makefile.libretro clean

git clone https://github.com/libretro/gpsp.git && cd gpsp
make platform=armv CC=/opt/buildroot-armv6el-eabi-uclibc/bin/arm-linux-gcc -j10 all && \
mv gpsp_libretro.so gpsp_libretro_arm.so && make platform=armv clean
make platform=mips32 CC=/opt/buildroot-mipsel32-o32-uclibc/bin/mipsel-linux-gcc -j10 all && \
mv gpsp_libretro.so gpsp_libretro_mipsel.so && make platform=mips32 clean

git clone https://github.com/libretro/pcsx_rearmed.git && cd pcsx_rearmed
make platform=armv CC=/opt/buildroot-armv6el-eabi-uclibc/bin/arm-linux-gcc -j10 -f Makefile.libretro all && \
mv pcsx_rearmed_libretro.so pcsx_rearmed_libretro_arm.so && make -f Makefile.libretro clean
make platform=unix CC=/opt/buildroot-mipsel32-o32-uclibc/bin/mipsel-linux-gcc -j10 -f Makefile.libretro all && \
mv pcsx_rearmed_libretro.so pcsx_rearmed_libretro_mipsel.so && make -f Makefile.libretro clean

# Build miniretro fro arm and mips too
git clone https://github.com/davidgfnet/miniretro && cd miniretro
PREFIX=/opt/buildroot-mipsel32-o32-uclibc/bin/mipsel-linux- make && mv miniretro miniretro.mipsel && make clean
PREFIX=/opt/buildroot-armv6el-eabi-uclibc/bin/arm-linux- make && mv miniretro miniretro.arm && make clean

And finally, let’s run a full matrix of tests, choose your favourite ROMs of course!

export ARCHS=”arm mipsel” EMUS=”pcsx_rearmed picodrive gpsp”
export FRAMES=”10000″ OUTPUT=”output/” SYSTEM=”$HOME/.config/retroarch/system/”
declare -A SYSROOTS=([“arm”]=”/opt/buildroot-armv6el-eabi-uclibc/arm-buildroot-linux-uclibcgnueabi/sysroot/” \
[“mipsel”]=”/opt/buildroot-mipsel32-o32-uclibc/mipsel-buildroot-linux-uclibc/sysroot/”)
declare -A ROMDIR=([“gpsp”]=”gbaroms/path/” [“picodrive”]=”mdroms/path”)

mkdir -p ${OUTPUT}

for emu in $EMUS; do
for arch in $ARCHS; do
echo “Running $emu for $arch”
./regression.py –core ../${emu}/${emu}_libretro_${arch}.so –system ~/.config/retroarch/system/ \
–input ${ROMDIR[${emu}]} –output ${OUTPUT}/${emu}-${arch} –threads=`nproc` –frames=${FRAMES} \
–driver “qemu-${arch} -L ${SYSROOTS[${arch}]} ./miniretro.${arch}”
done

./report.py compare –results ${OUTPUT}/${emu}-* –output ${emu}-report.html
done

This will produce a comparison report for every emulator, where you can see a screenshot (plus some info) for each rom and each platform. It will compare any different screenshot and report it in a red background. This is very useful to compare devices but can be also be used to compare across versions of the emulator (say, on a new commit or PR).

Reports: HTML and video!

It is also possible to produce video output directly using miniretro (if ffmpeg is installed on the system). It will output BMP and RAW PCM frames to ffmpeg which will encode them as video and audio tracks. Unfortunately there’s a bug in ffmpeg which prevents using two pipes to feed data and we are forced to produce separate streams (which can then later be muxed easily without reencoding).

I ran the above example with gpsp and arm, mips and x86 (+interpreter on x64) and got the following video (after a bit of editing with ffmpeg :P)

Likewise I ran a full test for picodrive, running 32x games:

Bonus content: dualretro

Tooling is better than debugging for sure. I’d rather spend 1 hour creating some tool rather than manually debugging something and digging too deep. Perhaps it’s part of becoming an adult 🙂 While doing a small code change I found some weird bug in gpsp that didn’t make any sense. Instead of debugging it, I tried to compare the emulator before and after my changes. Usually this involves finding the smallest change that triggers the bug and then, compare them. Thanks to miniretro I managed to found a couple of games that would trigger the error and a small test case that caused it.

Next step was to create a tool that allows us to compare emulator cores: let me introduce you to dualretro. This simple tool takes two cores and a rom and runs them side by side in lockstep. On each frame it will create a savestate and compare them, letting you know when it found a difference. This allowed me to find the bug in a matter of minutes.

Diagram of Dualretro running under Qemu

This concept can be generalized to compare frames, memory regions, audio, etc. libretro’s API provides a lot of information in a standarized way that can be used.