Mupen64Plus-Next – v2.1

The long-anticipated big update to Mupen64Plus-Next has finally arrived!

Important Information and notes

Beforehand, be warned that the core name changed
As you probably know, up until now, the flavour (if it’s a GLES/GL build) was appended to the Core Name, this caused the frontend to categorize them with the appendix. Now with Vulkan support added, this would break remap/game specific core options/etc anyway, so I decided to just kill it and append it to the version (there was never a good reason why I added it to the name to begin with…).
Now a new folder named `Mupen64Plus-Next` will be created inside your config folder on first start.
You can move and rename your existing core config override, core options and shader presets there, named accordingly (Mupen64Plus-Next.cfg/opt/slangp…).

RetroArch Nintendo Switch Notes

With the development of the threaded renderer support we noticed a few Issues in our platform specific Audio drivers, especially audren_thread, that will cause some cores, most often multithreaded cores, to randomly freeze. We have a fix for this in the pipeline, while also nearly halving our current audio latency.
Due to time concerns tho, I didn’t get to push the fix yet and it needs more testing.
So, for now, I recommend switching to the `switch_thread` audio driver until the issues are fixed.
Another core where it’s likely to happen is PPSSPP, so if you encounter random freezes, give it a try, the only thing you will lose is audio in in-game recordings.

GlideN64

This new version of Mupen64Plus-Next should be up-to-date with the most recent versions of GLideN64.
Here are some highlights, which are now available in the libretro-core as well!

Threaded Renderer

There’s now a ‘threaded rendering’ option for the libretro core. Enabling this can significantly increase performance, at the expense of slightly more input latency.
It has been available upstream for a while, but the implementation doesn’t play well with how a libretro core works.
I started work on it sometime mid last-year and after more than a dozen iterations and months of testing, it’s now ready for production.
An enormous shoutout to fzurita, who originally came up with the implementation!

How to use it


To use it, go to Quick Menu, Options. Make sure you have set ‘RDP Plugin’ to ‘GLideN64’ (the setting will not do anything with Angrylion and/or ParaLLEl RDP). Then turn ‘Threaded Rendering’ either on or off, and then restart the core (Close Content, and loading content again with the core).
Please note, I am aware that switching between fullscreen and windowed currently crashes when a game is running with the threaded renderer (same applies to changing Video Threaded in RetroArch), a fix is on my todo.

Benchmarks

Tests were performed on a Core i7 7700k desktop PC with a Geforce RTX 2080 Ti.

Game Non-Threaded Threaded Resolution
Super Mario 64 719 VI/s ~1000 VI/s 2x Native Resolution
Super Mario 64 701 VI/s ~1000 VI/s 4x Native Resolution
Super Mario 64 742 VI/s 780 VI/s 3840 x 2880

NOTE: These tests were performed with hyper threading enabled and CPU throttling, so take these figures with a grain of salt. The main important thing to take away from this is that VI/s is nearly 300 units of measurement faster at 2x to 4x native resolution compared to non-threaded rendering in this test.

This feature will significantly help platforms like Nintendo Switch and Raspberry Pi.

Dithering

In the past, HLE renderers have not really attempted to implement dithering (of course, with LLE RDP renderers you get it for free). An N64 game is typically rendered using a 16bit color buffer, and dithering is then used to reduce color banding and create the illusion of a higher color depth. GLideN64 in the past has always used 32bit rendering.

There are several new core options available:

  • Dithering Pattern
  • Dithering Quantization
  • RDRAM Image Dithering Mode

If you use native N64 resolution, you also may enable a dithering pattern to get a more authentic look, but even if you like to play in HD, this is something worth trying out!

ParaLLEl RDP

By now you’ve heard all about the revolutionary Vulkan-powered ParaLLEl RDP renderer, which debuted first in ParaLLEl N64. It is now included for the first time in Mupen64Plus-Next.

All the same features are available and more –

  • Compatibility on Android with ParaLLEl RDP should be much higher now as a result of a much more up-to-date mupen64plus-core. Games like Paper Mario, GoldenEye 007 and others would previously just crash on Android with ParaLLEl RDP+RSP.
  • Performance should be roughly ~5-10% faster on average than ParaLLEl N64. Sometimes a bit more.
  • Some compatibility issues that happened even on PC x86/x64 with ParaLLEl N64 are not an issue with Mupen64Plus-Next (such as Perfect Dark crashing at startup, Pokemon Snap graphics glitches, Mario no Photopi not working, Conker’s Bad Fur Day).

Over time we will probably repurpose ParaLLel N64 and let Mupen64Plus-Next take center stage.

Improved Core Options

Sub-labels descriptions got added to the core options. I hope this will make them a bit less confusing.
Please note that it’s currently not possible to hide the options on the fly so depending on the build configuration this might get a bit cluttered.
I am looking for solutions, but this should be a great improvement over the last versions nontheless!

Bugfixes and changes

– Android: Fixed garbage on the framebuffer with GLES3 (where the overscan would be)
– Android: Switched to “on Vertical Interrupt buffer swap mode” (might take slightly more perf) since the touch overlay was pretty much unusuable without it
– Updated Parallel-RSP
^- – Fix some stability issues in parallel-rsp on 64-bit
– Added Native Resfactor core option (set to disabled / 0 to use custom resolutions as you are used to)
^- Note: With Native Resfactor the resolution option will act as viewport size!
– Added Copy Aux to RDRAM core option
– Added a script to regenerate the INI Headers, updated to the latest variants
^- Note: It seems I still had cheats for OoT subscreen fix and DK64 bone displacement from when I first wrote the core, these caused some issues after it was fixed in the core, so I got rid of them for good, it was a oversight.
– Remove CountPerOp=1 for Quake 2 and Goldfinger
^- Note: After speaking with some upstream folks, nobody knows why it was even forced to 1, it caused crippeling performance on Android and Switch and after hours of testing no gamebreaking Issue was found, in the future I might work on getting rid of Count-Per-Op for good, it’s a nasty approximation.
– Allow higher Count-Per-Op
– Nintendo Switch: Lowered Firmware version requirements
– Added support for linking against system libaries
– Fixed LLE Fallback falsely being treated as supported, fixes F-Zero X Expansion HLE
– Exposed Hybrid filtering

These fixes are incorporated in both ParaLlEl N64 and Mupen64Plus-Next:

  • Vigilante 8’s character portraits are no longer wrongly coloured.
  • Mario Tennis’ intro screen no longer has tons of graphics bugs

Dynarec Issues

Over the last months, testers repeatedly encountered freezes in Ocarina of Time. I and Gillou spent hours on investigating the Issue and tracked it to the dynarec.
Sadly even after syncing core instances and comparing each recompiled block with the working MSVC builds led nowhere yet (tho we found a few other issues in code invalidation, which might’ve been an issue or not as well as borked caller saved regs..)
These fixes are still in the development stage and thus not included here. However I brought back the good ol’ TLB Invalidation hack as core option.
Setting it to the Ignore TLB Exceptions if not using TLB option will allow the game to continue so you can save it and restart (For this Issue you actually need to Close Content and start it again, a soft reset wont be enough). You will notice it happens when you suddenly see Epona carrots. Of course this is not a fix, but a side-effect is also that a bunch of broken romhacks work and it’s also useful for the upcoming GDB Server implementation, so I figured I will add it anyway.
Take note that this is confirmed as a mupen64plus-core upstream issue and that this Issue does not arise with Cached or Pure Interpreter!

Differences between Mupen64Plus-Next and ParaLLEl N64

  • ParaLLEl N64 has the following RDP plugins: Glide64, GLN64, Rice, Angrylion, ParaLLEl RDP. Glide64, GLN64, and Rice are aimed more at the lowend of graphics cards.
  • Mupen64Plus-Next has the following RDP plugins: GlideN64, Angrylion, ParaLLEl RDP.
    GLideN64 should be the best-in class HLE RDP renderer, but might have higher performance and GL requirements than the lower-end Gliden64/GLN64/Rice from ParaLLEl N64.
  • Both ParaLLEl N64 and Mupen64Plus-Next have the same RSP plugins (HLE, cxd4 LLE interpreter, and ParaLLEl RSP)
  • ParaLLEl N64 uses the Hacktarux dynarec for x86 32bit/64bit, and new_dynarec for ARM. Mupen64Plus-Next uses new_dynarecs for both x86 and ARM architectures, and tends to be a bit faster as a result.
  • ParaLLEl N64 has some built-in game specific alternate control schemes that you can switch on/off with the Select button. Mupen64Plus-Next does not have this yet.

Conclusion

Moving forward, we recommend you use Mupen64Plus-Next if you want to use LLE N64 (ParaLLEl RDP/RSP) with the highest compatibility and best performance.
Also, GLideN64 (provided your graphics card meets the OpenGL requirements) will work better than ParaLLEl N64’s equivalents.
Furthermore, Mupen64Plus-Next has a up to date version of mupen64plus-core, so it tends to have less game compatibility issues and the sound is better in games like Body Harvest.

ParaLLEl N64 might get repurposed towards the lower end as a result.

As a final note I want to give my thanks to dmrlawson for giving me a helping hand, fzurita for being very helpful, gonetz and his contributors for doing a awesome job with GLideN64 and Gillou68310 for all the hours he put in helping me investigate the dynarec issues (also thanks to Thom Rainier for never getting tired of OoT testing) as well as themaister for his work on Parallel RSP/RDP and the Vulkan implementation in Mupen64Plus-Next!

– m4xw