The road to Uxn started off with getting SDL2 built on OS X Tiger. Not being familiar with SDL at all I went in at the deep end with the latest and greatest release. As the bludgeoning progressed and the patches stacked up, I took a step back and wondered what’s been done already to get SDL2 installed elsewhere.
SDL2 has moved forward with targetting features found in newer OS releases so there’s a world of difference in functionality found lacking in OS X Tiger and SDL2’s expectations, sometimes it’s just been a gratuitous bump imposed by external factors. Consulting MacPorts and Tigerbrew to see how they handled packaging SDL2 I noticed that Tigerbrew had a patched version of SDL2 2.0.3 for Tiger specifically. Great, that’s a start. I knew that Uxn required SDL2, but wasn’t sure if it was a specific version or 2.0.3 would qualify. After some time compiling things (because a PowerPC G4 is mighty and slow) I had a version of SDL2. To be honest, I veered off into having the latest version of deps to compile against. Building latest release of FFTW on Tiger took some time due to a buggy m4 macro for autoconf which broke the configure stage on legacy OS X with GCC. At some point the FFTW’s build process needed to differentiate between compilers on OS X and adjust flags for linker and assembler but the two offending tests didn’t work on Tiger’s mighty compiler, since the test for assembler flag causes compiler to print an error saying flags are not supported but return 0, passing the test, and for the linker flags, compiler would error out but the test passed, resulting in subsequent tests failing due to unsupported flags being used. I initially tried to get autoconf to restrict the tests to newer versions of OS X but failed in getting it to do that. Searching around I discovered the autoconf-archive project which is a community contributed archive of macros to extend autoconf tests. Replacing the macro included in FFTW for the compiler flag checks with copies from the autoconf-archive resolved the build issue. There isn’t yet a script for invoking the compiler with flags for the assembler to test with (
-Wa) but there is a separate script for invoking the compiler with linker flags (
-Wl) and that’s sufficient to move forward, since the issue with assembler flags is specific to GCC 4.0.1 and did not occur on newer versions of OS X with a newer compiler when I tested.
With SDL 2.0.3 built from the patches Tigerbrew used, it was time to try Uxn. Invoking the
build.sh script soon started spitting out errors, again, Tiger’s compiler was too mighty. Uxn relies on type redefinition and so requires a compiler with C11 support so that
-Wno-typedef-redefinition will work. I used GCC 5 but according to the GCC wiki, anything since 4.6 should suffice. With a new compiler, the build progressed and errored out at the linking stage with one missing symbol. It was looking for
SDL_CreateRGBSurfaceWithFormat and SDL 2.0.3 was too old. The function was introduced in SDL 2.0.5, looking into the source of 2.0.5, they raised the OS version requirement. 2.0.4 and prior had a Leopard minimum requirement and 2.0.5 targets Snow Leopard. Wanting to avoid a fight with a new release of SDL I looked into what alternative functionality was there in the version of SDL that I could use.
SDL_CreateRGBSurfaceWithFormat was created to make it easier for the programmer to create surfaces, by specifying a single parameter value for pixel format. A successor to
SDL_CreateRGBSurface which instead of a single parameter require each parameter of the pixel format to be specified individually. Though
SDL_CreateRGBSurfaceWithFormat was introduced in SDL 2.0.5,
SDL_CreateRGBSurface shipped with SDL 2.0, so I switched Uxn to use
SDL_CreateRGBSurface and the build succeeded and then promptly failed to run when the build finished. Turns out Uxn requires joystick support but the SDL patch for 2.0.3 does not cover joystick support nor haptic feedback support due to the reliance in a newer functionality which is lacking in Tiger’s mighty ageing USB stack. This wasn’t so much of an issue since Uxn supports keyboard. Removing joystick support from SDL’s initialisation list and rebuilding Uxn resulting in a successful build and the emulator starting up with the piano rom (build script does this by default unless you tell it to not run the emulator with
--no-run). Cool! lets play keyboard! *cue harsh noises emitting from laptop speakers* (following video link warning: turn sound volume down, don’t use headphones, link).
At this point I wasn’t sure if the issue was with the patched SDL build or Uxn. I chose first to rule out SDL and see if it’s possible to generate sounds ok with a simple test case. I found the Simple SDL2 Audio repo which I used as my test case. The source is just a couple of
.c files and a header, leaving you to assemble things however you choose. This was my first time hand assembling a library then linking to it.
gcc audio.c -I/path/to/sdl2/headers/include -I. -c ar -r audio.a audio.o ranlib audio.a gcc test.c -I/path/to/sdl2/headers/include -Xlinker /path/to/sdl2/lib/libSDL2.dylib audio.a
The test tool executed fine on my PowerBook and the wave files the tool played sounded as they should, so the issue was not with the patched version of SDL. I started to compare how things were done regarding the SDL API in Uxn and the Simple SDL2 Audio example, it seemed that endianness of audio format is a parameter and while the example code explicitly specifies a little endian format, the Uxn codebase uses an alias which defaults to the same little endian format. So SDL has the concept of endianness but the two codebases are trying to play different sound files, Uxn is playing PCM files, where as the example project is playing wav files which are little endian. Switching Uxn to use a big endian audio format resulted in the piano rom sounding correctly on my PowerBook since it’s booted in big endian mode. According to the SDL_Audiospec there are formats which default to the byte order of the system being built on. Using that instead resulted in correct playback regardless of endianness of the host system.
With Uxn working on my PowerBook running OS X Tiger, it was time to upstream the changes. As the project is hosted on sr.ht, I needed to become familiar with git’s email workflow by following the tutorial on git-send-email.io. Given an up to date version of OpenSSL, Perl, and git, I was able to upstream the changes to Uxn using my 12″ PowerBook G4 running OS X Tiger (look ma! no web browser!).
With the exception of skipping joystick support in SDL everything is upstream, but that’s a trivial one word deletion. So as it stands, to run Uxn on OS X Tiger, one needs to install SDL 2.0.3 and GCC 4.6 or newer (I used 5). Edit
uxn/src/uxnemu.c and remove the
SDL_INIT_JOYSTICK flag from
SDL_Init() statement, then run Uxn’s
See the Awesome Uxn list for links to get started once everything is built and ready to go.