26 December 2022

Off-Topic: Mupen64plus on Mac Silicon - finally here

Update Christmas 2022: I created a script for a fully fledged compile of mupen64plus. 

Please download the zip file under this link:

https://drive.google.com/file/d/1EG6fMN-NmQl5cPZ20SNFGdych-wGmxNa/view?usp=sharing

After extraction, please check whether it is executable; if not:

chmod 755 mupen64plusSilicon.sh

With this script, you get all built automatically as described below. Be sure to have all the dependencies installed as explained below.

Only one warning: Although the Rice plugin builds successfully, it fails in my testing with several errors. For the time being, it does not work.

And if you want a frontend: That one works well, even if only an Intel binary (take the latest development build):

https://github.com/dh4/mupen64plus-qt#development-builds

Original post from 3 October 2022:

This is major (at least for me), thus I post these non-MAME news as a change: It runs on Apple Silicon, and quite well!

 


As we all know, Nintendo 64 emulation is a challenge, and modern Macs have long time been virtually excluded from proper emulation. Though OpenEmu has a N64 core based on mupen64plus, the current limitations are too big (for me), and on Apple Silicon, there is no OpenEmu binary available. But finally, you can at least compile your own mupen64plus binary, and thanks to a user, even the crucial GlideN64 plugin can be compiled now!

What you get from this adventurous compile:
  • a (nearly) fully functional mupen64plus core with GildeN64 GFX, SDL joypad support and two optional RSPs (HLE and CXD4)
  • very decent performance at 1280x1024 (I did not yet test higher resolutions)
  • fully functional hires texture packs (crucial for me)
  • everything is still considered 'experimental', but very good for me to go so far
  • run it out of a directory, so I do not mess around with an app image
Requirements: Besides XCode, you need a bunch of packages to be installed (via Homebrew or via Macports). These instructions for MacOSX seem outdated. With Homebrew, an installation of the requirements is rather straight-forward:
  • Homebrew (initial install)
  • sdl2 (with all associated dependencies)
  • libpng
  • freetype2
  • zlib
  • cmake
  • nasm
If you have already Homebrew up and running, it's very likely that you already meet these requirements.

I keep it short for the time being, but will expand if necessary. Basic Terminal knowledge and MacPorts/Homebrew will be required.

(To-do: I acknowledge that a script is overdue here, that's next. But at least you figure out what's happening here ;-)

Step 1: Download all components into an empty directory, e.g. from within "mupen64plus compile"

git clone --recursive https://github.com/mupen64plus/mupen64plus-core
git clone --recursive https://github.com/mupen64plus/mupen64plus-ui-console
git clone --recursive https://github.com/mupen64plus/mupen64plus-input-sdl
git clone --recursive https://github.com/mupen64plus/mupen64plus-audio-sdl
git clone --recursive https://github.com/mupen64plus/mupen64plus-rsp-cxd4
git clone --recursive https://github.com/mupen64plus/mupen64plus-rsp-hle
git clone --recursive https://github.com/gonetz/GLideN64

Note: You need all downloads in this structure, so that the components find each other during compilation.

Step 2: Compile the components separately

mupen64plus-core: from within the subdirectory /projects/unix
make all
library libmupen64plus.dylib is created

mupen64plus-ui-console: from within the subdirectory /projects/unix
make all
executable binary mupen64plus is created

From now on, it is entirely repetitive:

mupen64plus-input-sdl: from within the subdirectory /projects/unix
make all
library mupen64plus-input-sdl.dylib is created

mupen64plus-audio-sdl: from within the subdirectory /projects/unix
make all
library mupen64plus-audio-sdl.dylib is created

mupen64plus-rsp-cxd4: from within the subdirectory /projects/unix
make all
library mupen64plus-rsp-cxd4.dylib is created

mupen64plus-rsp-hle: from within the subdirectory /projects/unix
make all
library mupen64plus-rsp-hle.dylib is created

Finally the glideN64 gfx plugin: from the the subdirectory projects/cmake 

cmake -DMUPENPLUSAPI=On -DCMAKE_CXX_FLAGS=-std=c++11 ../../src/

and then

cmake --build . -j6

library mupen64plus-video-GLideN64.dylib is created in /plugin/Release

Step 3: Create a Program Directory Structure

Create a separate directory for the actual program for launching, e.g. Games/mupen64plus-bundle-Silicon; get the test ROM from here: https://github.com/mupen64plus/mupen64plus-rom and put it into the same folder as the mupen64plus binary; content should be as follows:

So in the root folder, only the ui console gets in


The Frameworks directory contains all the libraries.

Content of the Frameworks directory

Now Resources: That's a bit cumbersome, but also not so difficult:

From your mupen64core download: copy Data content (font.ttf, upen64plus.ini, mupencheat.txt) 
From your mupen64plus-input-sdl download: copy Data content (InputAudioCfg.ini)
From your GlideN64 download: copy ini content (GLideN64.custom.ini, GlideN64.ini)

Resources folder content

Step 4: Launch mupen64plus for the first time

Get the test ROM from here: https://github.com/mupen64plus/mupen64plus-rom and put it into the same folder as the mupen64plus binary

From within your program directory, shoot from the Terminal:
./mupen64plus --gfx mupen64plus-video-GLideN64 m64p_test_rom.v64
You should get something like this animated in a window:

This creates a new directory: /Users/--username--/Library/Application Support/Mupen64Plus with the following content:


Congratulations - you made it through the basic mupen64plus configuration! Now comes the fine tweaking.

Step 5: Configuration within mupen64plus.cfg

For a fully functional emulation, several steps are still required, so don't stop reading! So let's configure the newly generated configuration file properly.

In line 67:
SharedDataPath = ""
must point to the Resources directory of your applications folder, e.g. /Users/--username--/Games/mupen64plus-bundle-Silicon/Resources/

In line 389 (optionally):
RspPlugin = "mupen64plus-rsp-hle.dylib"
You can switch to "mupen64plus-rsp-cxd4.dylib" if you want to experiment with the other RSP.

From line 386 onwards:
ScreenWidth = 640
ScreenHeight = 480
VerticalSync = False
I use 1280, 1024 and True.

From line 168 onwards: Controller Setup
This is a potentially difficult topic, as in MacOS, an automatic controller configuration seems difficult. Here I post as an example my manual controller configuration of a PS4 Controller via USB cable:

Most important changes: mode = 0 (Fully Manual), then all mappings of DPad, Analogue Joypads and keys.

[Input-SDL-Control1]

# Mupen64Plus SDL Input Plugin config parameter version number. Please don't change this version number.
version = 2.000000
# Controller configuration mode: 0=Fully Manual, 1=Auto with named SDL Device, 2=Fully automatic
mode = 0
# Specifies which joystick is bound to this controller: -1=No joystick, 0 or more= SDL Joystick number
device = 0
# SDL joystick name (or Keyboard)
name = "Wireless Controller"
# Specifies whether this controller is 'plugged in' to the simulated N64
plugged = True
# Specifies which type of expansion pak is in the controller: 1=None, 2=Mem pak, 4=Transfer pak, 5=Rumble pak
plugin = 2
# If True, then mouse buttons may be used with this controller
mouse = False
# Scaling factor for mouse movements. For X, Y axes.
MouseSensitivity = "2.00,2.00"
# The minimum absolute value of the SDL analog joystick axis to move the N64 controller axis value from 0. For X, Y axes.
AnalogDeadzone = "4096,4096"
# An absolute value of the SDL joystick axis >= AnalogPeak will saturate the N64 controller axis value (at 80). For X, Y axes. For each axis, this must be greater than the corresponding AnalogDeadzone value
AnalogPeak = "32768,32768"
# Digital button configuration mappings
DPad R = "button(14)"
DPad L = "button(13)"
DPad D = "button(12)"
DPad U = "button(11)"
Start = "button(6)"
Z Trig = "button(9)"
B Button = "button(2)"
A Button = "button(0)"
C Button R = "axis(2+)"
C Button L = "axis(2-)"
C Button D = "axis(3+)"
C Button U = "axis(3-)"
R Trig = "button(5)"
L Trig = "button(4)"
Mempak switch = ""
Rumblepak switch = ""
# Analog axis configuration mappings
X Axis = "axis(0-,0+)"
Y Axis = "axis(1-,1+)"


A really helpful online tool for your button configuration:
The results from this page exactly fit with this mapping here.

Further recommended tweaking of mupen64plus.cfg:

Display FPS and rendering resolution during gameplay:
In line 549:
ShowFPS = True
In line 557:
ShowRenderingResolution = True

Step 6: Hires Textures
With the GlideN64 plugin, activation of hires textures is easy.

In /Users/--username--/Library/Application Support/Mupen64Plus create a cache directory:


Place hires textures in the .htc format in there.

In line 511 of the cfg:
txHiresEnable = True

If done properly, that should activate Hires Textures.


Step 7: Launch games from Attract Mode
(quite good, however in windowed mode with some quirks, to be completed)
(I still like running mupen64plus in Windowed mode just in case that something freaks out)









Known limitations on Apple Silicon (my personal experience during testing and playing):
  • After a larger number of starts/stops, mupen64plus tends to run slowly. A restart of your Mac brings everything back to speed.
  • Line 410: MSAA does not work.




5 comments:

  1. Hello, I'm DJ.HAN
    I have good news and bad news.
    Good news is attractplus was updated. Now it can build normally on intel Mac. But original code have a issue on m1 mac, so I synched my source to newest original source code. You can get new source code from my github, and build new one.
    Bad news is retroarch and mame has biggest problem on MacOS Ventura(until beta 10). retroarch can't run on fullscreen mode, also even can't play sound! I reported this issue to retorarch developers.
    mame has a issue with bgfx/metal video driver. If you set video to bgfx, mame sound is shuttering slightly even don't use shader. Especially you can suffer this sound issue on after 90's games.
    I thinks these are all of compatibility issue that caused by newest metal 3 API and sound API. It's very disappointed for user and developers. Because these problems are not resolve until emulator developers learn new api and fix to their code. Yes, very annoying.

    ReplyDelete
  2. mame have only one solution; set video to opengl, then sound shuttering is gone.
    retroarch? There are not fix yet.

    ReplyDelete
  3. I found another solution on mame. Lease video option to bgfx, but change bgfx backend from metal to opengl. It can fix sound shuttering issue, too.

    ReplyDelete
    Replies
    1. Many thanks DJ.HAN, just about to post a new Blog Entry on Shaders - you may want to comment there. Your testing is quite in line with my own experience with MAME Metal: It works, but seems to be quite buggy, e.g. a nothrottle test does not work at all. OpenGL in BGFX is indeed always a very safe and fast option. Will also look into Attract Mode, many thanks for this!

      Delete
    2. This comment has been removed by the author.

      Delete

Any comments are welcome!