Mac Source Ports Progress Report: June 21, 2022

I just added a build of GemRB to the site, a source port recreation of the Infinity Engine, so I’ve been able to add three new games to the site, Baldur’s GateBaldur’s Gate II, and Icewind Dale. Reportedly, Planescape: Torment is also playable but I couldn’t get it to run personally, and Icewind Dale II can reportedly run but not be completed so I just stuck with listing the three that GemRB seems to be confident about.

I was really trying to get OpenMW to work but I ran into some snags and I’ve not been successful at finding many/any folks who have had it working on Apple Silicon. The OpenMW guys were nice and helpful but they leveled with me: none of them have Apple Silicon Macs so none of them could really help.

So to switch gears to something that seemed more feasible I looked at GemRB which had the advantage in that it made its own app bundle from CMake files so I figured it would be a straighforward deal – build two versions, make a copy that has the resouces and lipo the executables and libraries together, bundle it up and call it wonderful.

And if you’ve looked at how long this post is you’ve probably guessed correctly it wasn’t that straightforward.

It almost was – I had it building two versions for the two architectures and it ran great. Cool, so let’s assemble this guy and get him out the door. This is where I ran into the first snag.

GemRB uses a plugin architecture. It’s actually pretty neat and pretty well done and I’m sure it’s instrumental in getting the project to support numerous games. However, while the project does use a .dylib for certain things, the plugins are all .so files. A .so file is akin to a .dylib on Mac or a .dll on Windows. So my first instinct was to lipo them together to make Universal 2 .so files. Which lipo happily did, and otool even showed them as having the architectures I expected. All was well.

Except they wouldn’t load. This is when I realized: it’s because .so files have no concept of a Universal 2 anything. If they were using .dylib files we’d probably be in business but they’re not, they went with .so files on macOS because they have the common denominator of being useful in Linux/UNIX platforms. What I’ve learned over the years (and I should have thought of this before I messed with the .so files) is that the Mac is pretty much the only platform with this concept of multiple architectures in a dynamic/shared library. This is mostly due to how Apple can dictate the platform, including how it switches architectures. So they invented this concept of a Universal 2 library that can hold both architectures and contains a header to point to where they start and stop.

So that means to do this I’d either need to figure out what was involved with switching the project to using dylibs on macOS (eventually I discovered it’s using dll files on Windows), or deliver two different apps, or copy over the two different versions of the plugins to parallel directories and load from there. I decided on that last option.

I try to change as little as possible but I wound up having to modify the CMake files to copy the items to the right directories, and modifying the code to sniff out where it’s running and load the files from there. It was a touch on the tedious side, and it violated to some extent my impetus to try and modify as few files as possible, but eventually it worked.

And then days later I had the more or less literal Shower Thought: maybe if it just uses .dll files on Windows, it could have used .dylib files after all. I don’t know how much of the process to load in a Universal 2 dylib is truly intrinsic to the operating system and how much it relies on code support. Lots to learn, but if I revisit this in the future I might see if I can get .dylib support working and/or how hard it would be.

Interestingly when I posted the build I noticed it wasn’t getting many downloads. Which is fine, I’m doing this as a hobby, plus GemRB actually does offer a Mac bundle on their site, just unsigned and for Intel only. When I posted to Reddit though, the first question was: I don’t understand, Baldur’s Gate already runs on the Mac, right?

Well, yeah it does. But, it’s kinda complicated.

All these games ran on the Infinity Engine from BioWare. They came out over a period of a few years from 1998 to 2002. Then BioWare moved on to other things – namely, the Aurora Engine for Neverwinter Nights which migrated from the 2D sprites of Infinity to 3D polygons. At some point when it became feasible to sell old games digitally, especially via vendors like GOG who specialized in older games, these games started appearing on places like GOG.

Then in 2012, Beamdog approached BioWare (now owned by EA) with the idea to license the Infinity Engine to enhance it and then sell enhanced editions of the games, which they did. The results were games like Baldur’s Gate: Enhanced Edition and Icewind Dale: Enhanced Edition. Places like GOG originally sold both versions but eventually they dropped direct sales of the original in favor of just bundling it as an extra with the Enhanced Editions.

GemRB requires files from the original version, not the Enhanced Edition. Which means if you don’t own it already you need to buy the Enhanced Editions, which includes the originals, but also means you now own a version that already runs natively on the Mac (albeit for Intel).

So what’s the point of GemRB? Well some people prefer the originals to the Enhanced Editions (I’m not really versed on all the differences personally). But also: to some extent the whole goal of this project is to make versions of source ports to run on modern and future Macs. A secondary goal is to make apps which can play games that might not be otherwise available but that’s not always the case.

Or to put it in Cave Johnson terms: “Science isn’t about why, it’s about why not!”

One area where GemRB might eventually shine: the one Infinity Engine game that does not have an Enhanced Edition is Icewind Dale II. The reason? The source code has been lost. You run into this in the game industry from time to time and often it’s the case that eventually someone stumbles on an old CD-R or an old hard drive someone thought was dead, or even the occasional floppy disk, and finds it. But as of right now Icewind Dale II‘s code is MIA, so there’s only two ways that game is going to run on modern machines: either they find the old code, or the game’s code and the differences to make it happen get reverse engineered. Beamdog seems disinclined to do the work themselves (not that I blame them, the amount of QA work for a commercial product is probably daunting) so if the support in GemRB matures it might be the only way to play that game.

In any event if anyone keeps up with my blog I started this entry weeks ago and didn’t finish until a week into July. Life’s been busy, I’ll blog again soon.