Wolfenstein 3D and DOOM on iOS 11

OK, so for a few months now I’ve been working on getting the old id Software ports of Wolfenstein 3D and DOOM working on iOS 11. Or really, just any modern version of iOS. And I’ve now finished them.

For those who just want to cut to the chase here’s the repos where you can grab the updates.

Wolfenstein 3-D for iOS 11:
https://github.com/tomkidd/Wolf3D-iOS

DOOM for iOS 11:
https://github.com/tomkidd/DOOM-iOS

Note that I’m saying “for iOS 11” to denote that these will run on the latest versions of iOS and have 64-bit versions but really they should run on any iOS later than iOS 9 which, according to Apple, is 93% or more of devices in use today.

The short backstory is: back in 2009, id Software ported Wolfenstein 3D and later DOOM to iOS. Over the next few years they saw some updates and improvements but neither of them have been updated since 2014 and, since they were 32-bit apps, they no longer work on iOS 11 at all since iOS 11 cut off support for 32-bit apps. However, since the source code for both of them has always been available, I went and did the work to update them and get them working in the latest versions of iOS. This wound up being both harder and easier than I expected.

 

So, there’s a few things going on here.

  • The iPhone and iPad as devices evolved from devices with 32-bit processors to devices with 64-bit processors.
  • iOS as an operating system existed in a 32-bit version for 32-bit devices and in a 64-bit version for 64-bit devices, until iOS 11 which did not feature a 32-bit version.
  • The 64-bit version of iOS prior to iOS 11 could run 32-bit apps but the 32-bit versions of iOS could not run 64-bit apps, and iOS 11 cut off 32-bit app support entirely. It’s confusing, but technically iOS 11 could have both existed only in a 64-bit form for iOS devices with a 64-bit processor and also still allowed those devices to run 32-bit apps, but Apple decided to make a clean break.
  • The App Store allowed and then later required apps to be submitted in both 32-bit and 64-bit binaries. It still does this to this day because despite the latest version of iOS cutting off 32-bit devices, there are still plenty of 32-bit only devices running iOS 10 that are still supported. Xcode comes up with and submits both 32-bit and 64-bit apps for you, and most if not all iOS developers are using Xcode.
  • Parallel to all of that, the iOS devices on the market started to come out in different screen sizes, ratios and densities. First the iPhone 5 had a longer/taller screen, then the iPhone 6 and 6+ had larger screens, then various iPad screen sizes got released, and code had to be modified to properly handle all of these resolution changes.

The original iPhone shipped in 2007 with a 32-bit ARM processor. The ability to make apps for the iPhone didn’t come along until 2008 with the iPhone SDK, and the App Store was launched in summer 2008 alongside the iPhone 3G (as a side note it’s kind of insane to picture the iPhone before it could run apps). The timeframe of Wolfenstein 3D‘s launch on the iPhone meant that it was in the very first year of app availability.

As a side note, I keep saying it launched on the iPhone because this predated the iPad and also because the name “iOS” wasn’t used yet either. Up until the launch of the iPhone, Apple and Steve Jobs kept saying it “ran on Mac OS X“, but on launch they just called it “iPhone OS”. They continued to call it iPhone OS even after the iPod Touch launched but once the iPad launched they renamed it iOS. But the timeline of Wolfenstein 3D means it was initially created with the SDK for iPhone OS 2 (so, iOS 2 if they had used that name back then). With this in mind, some of the seemingly odd decisions I encountered in working with it can be explained since the correct way to do things may have been wrong or nonexistent in 2009.

In 2013, the iPhone 5S was released, which was the first iPhone to include a 64-bit ARM processor. iOS 7 was released alongside it and the iOS SDK and Xcode 7 were released which featured the ability to compile 64-bit apps. It could create a “universal” app that had both 32-bit and 64-bit binaries and so when the app would load on a 32-bit phone it would run the 32-bit version and on a 64-bit phone it would run the 64-bit version.

However, if you didn’t upgrade your version of the SDK, you could continue to target 32-bit only for a while. Apple had a grace period but starting in June 2015, anything submitted to the App Store had to include a 64-bit executable. Since neither Wolfenstein 3D or DOOM has had an update past 2014, this is why they remained as 32-bit apps.

The other reason that the games haven’t been updated in a while is because id Software basically pulled out of the mobile market. Besides these two games they also had a RAGE game for iOS that actually launched before the actual RAGE game on PC and consoles (the iOS game was an on-rails arcade shooter), a game called DOOM Resurrection (same deal as RAGE, on-rails shooter, using DOOM 3-era visuals), and ports of DOOM II RPG (originally on feature phones and J2ME devices) and Wolf RPG (I think that one was original to the iPhone). But the main game RAGE was dragging on and so it took precedence and id focused their energies on that, as well as the game which would end up being the 2016 DOOM reboot.

Maintaining any sort of game or application on any platform requires constant maintenance in order to keep up with the changes to the platform, the SDK and the API. There’s factors that can affect how pronounced this is, such as the maturity level of the platform and how willing the platform vendor is to make major breaking changes. Microsoft, for example, has DirectX which is mature enough now that games written for, say, DirectX 8 will still work fine in DirectX 12 but really old games from 1995 that used DirectX 2 might need some work or hacks before they’ll work on a 64-bit Windows 10 machine. But Microsoft also has a pretty strong backwards compatibility religion. They’re in the business of selling operating system upgrades and if you buy an upgrade and your favorite thing isn’t working, you’ll roll back the upgrade and demand a refund, is the logic.

The iPhone, comparatively, is barely a decade old and Apple as a company has shown very little issue in breaking compatibility. For constantly maintained applications this isn’t really much of a problem – the changes from version to version aren’t huge and since a lot of developers are running into them at the same time there’s info out there on how to overcome them. But if you’re talking about a game that’s been years without updates then there’s some work ahead of you. Method names change, entire systems get deprecated, and some of the fundamentals get changed completely.

So all of this is to say that the first thing I thought was that someone just needs to open up the project and hit recompile, maybe work through the small number of issues that come up, and then you’d be done. And the second thought I had was that if it was this easy someone would have done it by now.

For some history, Wolfenstein 3-D‘s commercial release was in 1991 and the source code release was in 1995. It was released under what was termed an “Educational Use” license, which basically meant that you couldn’t use it for any commercial purposes. You may not even have been allowed to distribute your changes. Look, touch, but go no further. I’m not sure why they didn’t go with something like the GPL out of the gate but the timing of things (GPLv2 had only come out in 1991) and the sheer infancy of game engine source code releases likely played a role.

It didn’t really matter much though since my memory of what happened next was basically not much, a combination of the fact that online communities weren’t big enough or coordinated enough to even be using the word communities yet, the fact that the released source code required Borland C++ for DOS (and maybe some Assembly) to produce a protected mode 16-bit DOS executable, a practice that was on its way out of fashion, and the simple fact that Wolfenstein 3-D just wasn’t nearly as popular as DOOM. People like me who tried to get games running on their 486 as soon as we got one played the heck out of the brightly colored game where you shot Nazis to death, but outside of that not many people had heard of it. This was years before it was a given that there would be a PC in every home.

DOOM was released in 1993 and its source was released in 1997 under a similar “Educational Use” license. Compared to Wolfenstein 3-D‘s source release, however, people went absolutely nuts with DOOM‘s source. For various reasons, DOOM was developed on NeXT computers. NeXT was the company that Steve Jobs formed after being ousted by Apple and it ran on NeXTSTEP, a UNIX-like OS written from scratch by NeXT. I don’t know the exact reasons why it was developed on one other than maybe Carmack just liked them at the time (Quake‘s development was done in part on NeXTSTEP as well, but id switched to Windows development by the time Quake II rolled around) but an anecdotal reason I saw cited in the press at the time (which is probably wrong) was that writing it on a NeXT computer made porting to other platforms easier. I suspect the reality is just that the code was written in such a way that cross platform compatibility was a concern, similar to how these days a game engine will be written considering porting to PCs and consoles at the same time. NEXTSTEP, incidentally, goes on to be the foundation of Mac OS X, the overhaul/replacement of Mac OS, so to some extent anyone using a Mac today is using something ultimately derived from NEXTSTEP.

In any event DOOM‘s source code as released was stated to be the “Linux version” (my guess would be it was the NeXT code, perhaps just missing whatever toolchain stuff they used to keep it working on DOS) and out of the box it wouldn’t actually compile because id had used a commercial audio software library whose source they couldn’t release. Within days though (or perhaps even hours) eager developers had swapped in OpenAL, an open source audio library, and DOOM became something anyone could compile.

DOOM and Wolfenstein 3-D used software based renderers. There weren’t consumer/gamer focused 3D cards on the market yet so this made perfect sense. With DOOM it didn’t take long for people to try and port the renderer to a hardware-based renderer using something like OpenGL. The first successful effort to do so went under the fitting title DoomGL (I think that was the name, there may have been a space in there). And it was indeed as advertised – it used OpenGL to do the rendering, so you got the smoothed walls, fluid framerates, low CPU usage, etc., associated with that. I think they even did some snazzy things like translucent fireballs or something.

Not too long after that the DoomGL project went silent. At some point the developer (I don’t remember if there was more than one person involved) announced that the project was dead because he lost the source code (as in, the original DOOM source plus the DoomGL modifications) in a hard drive crash. This whole effort predated a number of things, such as GitHub, common usage of source control, cloud storage, or (apparently) near-ubiquity of reliable hard drives. John Carmack noted that if DOOM had been released under the GPL the loss wouldn’t have happened because the source code modifications would legally have had to been released. So id Software re-released the DOOM source code under the GPL license. I don’t know if they ever did the same for Wolfenstein 3-D, but it didn’t really matter much since, like I said, not that many people cared about it as much.

The GPL had another interesting advantage: legally, you can sell products made with the GPL commercially, you just have to make the source code available as well. To this day, the concept of someone doing this is a rarity because of the perception of giving away a competitive advantage (though this seems to be changing very recently). id Software would go on to release all of their engines under the GPL similarly, until RAGE. It’s unclear why they stopped, but the departure of John Carmack was likely a big factor (the other factor would be Zenimax having acquired id Software in mid-2009 but both the release of the DOOM iOS port and source as well as the source of the id Tech 4 engine used in DOOM 3 were done under Zenimax’s watch so that alone isn’t the culprit).

In 2009 John Carmack got involved with helping with the iOS port of Fountainhead Entertainment’s Wolf RPG and he got the bug to fool around with iOS development some more. To some extent his previous experience using Objective-C and NEXTSTEP helped in this area. He decided to port Wolfenstein 3-D to the iPhone first for various reasons, not the least of which was its small installation footprint fitting under the then-20MB AT&T 3G file download limit.

He found a project someone had done called WolfGL which was a hybrid grafting of the Wolfenstein 3-D source code and the Quake II source code. I had read ages ago that due to the way Wolfenstein 3-D was written for DOS it would be unrealistic or infeasible to port it to a modern PC, that you could use parts of its code as reference but that you’d need to redo the renderer from scratch. I don’t know how true that is but it seems like the WolfGL author did just that.

Carmack detailed the process he went through in the README file for the source release, including the unsuccessful attempt to contact the WolfGL author, and id Software goes on to release Wolfenstein 3-D on the App Store.

In a particularly generous turn of events, Carmack decided to release the data files for the game along with the source code. When a game engine’s source code is released, it’s usually just that – the source code for the game engine. They usually don’t release the game’s files for free as well. In many instances if you have the game yourself you can supply the missing files and be able to run the resulting compiled engine, but the important thing is that releasing a game’s source code does not mean the game itself is now free. You may think pointing this out is unnecessary but a surprising number of people do not get this.

I didn’t initially understand why Carmack felt it was necessary do this, instead of just having people supply their own files from copies of the DOS game. I thought maybe it had to do with the spotty availability of old games but I think I understand a little better why (more on that later). In any event, the practical upshot of all of this was that anyone who had an Apple Developer license and wanted to play around with the thing could just hit compile and go, more or less. I didn’t have a Mac or license back then so I can’t attest to it but that’s what I understood it to be.

Later in the year, id ported DOOM to the iPhone, based on a source port called PrBoom, which was a merger of a source port called Boom and some others. By this point, the Wolfenstein 3-D port had been a success and id had a number of other mobile projects in the works. The source release was a similar affair but without the game files (namely the doom.wad file that contained all the game’s data in the DOS version).

If I recall correctly, Wolfenstein 3-D came out at $4.99 and DOOM came out at $7.99. Wolfenstein 3-D had a few different releases, including a “Lite” version that only had the first episode (similar to what Shareware did back in the day) and a “Platinum” update that featured the ability to purchase the Spear of Destiny content (the retail standalone sequel) and also run user-created levels (you were on your own to figure out how to make them though). DOOM did none of this, it was just the one release. Both were updated when the iPad came out to feature an interface appropriate to the new screen size.

They saw a few more updates but then id got out of the mobile market. They never did come out with Android versions, seemingly because the timeframe of all of this preceded the era when Android was going to be the clear other competitor in a duopoly. It seems odd now but there was still a feeling that competitors like Microsoft or RIM (BlackBerry) could usurp the market and become the #2 player but that didn’t happen and today the market is 99% iOS and Android. The other players may as well not exist.

The release of iOS 10 included a new feature – when you launched a 32-bit-only app it would prompt you that the author of the app needed to update it for future versions of iOS. Presumably the purpose of this was to have end users pester the authors of their apps to update them. I suppose if you were an app author and no one asked you to update the app then maybe you’d think it was safe to abandon it, and if a ton of people bothered you then you might find the motivation to update it. The media called it an impending “32-bit Appocalypse” amongst other things. Indeed, in the months immediately preceding iOS 11, which was announced to be 64-bit only, many apps (especially games) did get updated for the first time in years.

About here is where I came in, kicking around the idea of updating the ports of Wolfenstein 3-D and DOOM, since it wasn’t clear they were going to see updates.

I fired up Wolfenstein 3-D first. I really wanted to get that one going because although DOOM is clearly the better game, Wolfenstein 3-D has always sort of been my favorite for nostalgia reasons. It had many errors in Xcode 9 preventing compilation. The xib files (screen layouts, some people call them by “nibs” which was their old extension) for the UI were actually crashing the Interface Builder in Xcode. And it had hundreds and hundreds of warnings. I plowed through through the show-stopping issues and got it to build with the numerous warnings, only to be stopped by a “duplicate symbol” error that was telling me hundreds of locations had a x86 and an x86_64. I figured this had to do with the new 64-bit architecture but I wasn’t sure why.

And at this point I basically bailed because I had other projects of the actually-making-money variety that needed attention and on the chance that someone at id was already digging in and fixing the issues, I didn’t want to get far in the project only to have my effort basically be redundant. So I figured if id didn’t update the apps by iOS 11, I’d have another look.

iOS 11 came and many apps were consumed by the 64-bit cutoff. And Wolfenstein 3-D and DOOM did not get spared. I can’t blame id, since 2016’s DOOM reboot is basically a case study on how to make an amazing game and support it after release so they were clearly busy.

So I cracked open Wolfenstein 3-D on iOS again. id Software has a GitHub account like pretty much literally every other software company on the planet but these iOS ports preceded it by years. It looks like in 2012 someone at id added the Wolfenstein 3-D iOS code to it, in three commits: the source for the 1.0 iOS release, then the 2.0 release, and then the 2.1 release.

The crux of the duplicate symbol issue turned out to be in how the project chose to handle intermediary files. When you create a new iOS app in Xcode, you’re given a basic project with some files based off a template. At this point you can hit Run and it will build it and fire up an iOS Simulator based off of whichever device you have picked, and then it runs it. Under the covers it’s building the intermediary files in a location called Derived Data, which Xcode maintains, and then it’s copied to another folder which is essentially acting as the file structure of an iOS device, which Xcode also maintains, and the Simulator is using it as its base. Absent any intervention, at no point are the object files or binaries in the project folder you’re working from.

Well, the project file for Wolfenstein 3-D did intervene. For a lot of application types, such as .NET programs and video games, you generally do want to know where the object and binary files wind up, if for no other reason than you’re eventually going to need to copy those out to somewhere to redistribute. For iOS, however, you’re never going to be grabbing those actual files and the process of getting an app on the App Store is much different for various reasons not the least of which is the need for the iPhone to run only signed code.

But were I to guess, in this case the intermediary locations of files and executables was changed in the Xcode project probably due to habit more than any other reason. Once I cleared that out and let Xcode handle it, the app finally built and ran. And crashed.

Several troubleshooting steps later I had it up and running. The GitHub project had a handful of forks, the most recent of which said “compiles and kind of runs in iOS 10”. I had fired up that one but I still got the duplicate symbol issue. At least one fork had the menu images needed to actually compile (since the Copy Files build phase failed without them) but I don’t think they’re supposed to be there since they weren’t in the original release. I believe the original 1.0 version of Wolfenstein 3-D on iOS drew its menus and such directly from game code on the OpenGL surface and not from xib files so the menu art wouldn’t have been needed. They were needed later but just never added or included.

Then I ran into an issue where maps wouldn’t load because a checksum failed. The game loads up the header from a .map file (one per level, more or less) and does a checksum on it. My guess is this was because the game could run user defined levels. The problem was that the 64-bit upgrade changed the calculation and now nothing was matching the hardcoded constant it was expecting. I figured it would be as simple as changing the constant, maybe making it architecture dependent, but I couldn’t find a reliable way to do that, so I commented it out and moved on.

So after working though all that I ran the game and actually launched it. The game itself ran in portrait mode…

Actually, it’s kind of awesome this way

This is one of the big stumbling blocks of fixing old game on iOS: in iOS 8, Apple changed how the coordinate plane was handled. Specifically, they fixed it. I can’t find the explanation now but basically the iOS coordinate system and the (x,y) origin was handled different than any other system and platform, including OS X/macOS, and developers had to work around it. Plus I think it didn’t change when you rotated the phone. Now that they fixed it anything that was designed to work around it had to be changed. The problem I had is that I had no idea where to fix this because I basically knew fuckall about OpenGL or even if that was the problem.

The game uses an Objective-C class called EAGLView which looks to be derived from an example Apple gave out. The Objective-C portion of the game handles navigation and then sets up this EAGLView class as a view taking up the entire screen and just shows/hides it appropriately. The parts of the code that are OpenGL paint the game images on the EAGLView. It intercepts touches from the EAGLView which hands it off to the game engine and renderer which takes actions based on whether or not the coordinates of the touches intercept the bounds of the controls drawn on the screen. Really the only way any of this works is because C/C++ code and Objective C can coexist in the same project. This gave the iPhone an unusual advantage in the early days of smartphone game development because it meant that some amount of code from existing games could come along for the ride and since the original iPhone models weren’t speed demons, they lent themselves to older games. Android development is primarily done using Java (since the target hardware of the Android device is not a constant) but there is a way to get C/C++ code running on there that I don’t understand well enough to comment on. And I believe the initial releases of Windows Phone required the code to be .NET which was a big enough hurdle that most didn’t bother.

In any event the code to fix the rotated screen wound up being just a couple of lines. It just took a while for me to figure out what those lines were.

So now I could run the game, but nothing worked right. Long story short the coordinate system for the touches on the screen needed to be rotated too. The fix I came up with for it may not be the best way to do it (it may be the worst way to handle it actually) but it works.

After that I addressed all the warnings. Most of them were things that worked just fine but newer versions of Xcode get increasingly strict. Most of them were just casting a long to the integer it was getting assigned to, something like that. Then there were some quirks with pausing and going back to the game so I hammered those out as well. After that it was mostly cosmetic stuff, like getting the xib files to use Auto Layout, Apple’s newer system to handle screen layouts and be able to adapt to new screen sizes, and swapping out some UIScrollViews with UITableLayout objects because auto layout and UIScrollView don’t get along. Also the method for using motion controls (there’s an option to control movement like turning a steering wheel – I don’t use it but some people like it) was using a deprecated API so I had to find out what to swap out there.

And then just for fun I put in MFi controller support. This was actually fairly straightforward. You basically intercept button presses and then the code that hands commands to the engine based on screen presses you add the active buttons as commands as well. The analog sticks come up with values between 0.000 and 1.000 and those translate exactly to what the engine is expecting. With a little work I got the two sticks to control movement and turning and when using a SteelSeries Nimbus controller, it’s like playing a modern console-based FPS.

So this was all I was expecting to do, and I thought maybe I’d look at DOOM at some point. But on a hunch I looked into it, thinking perhaps it would also be as simple as the Wolfenstein 3-D fixes. I knew it was a different game, different engine, etc. but maybe if the “throw the OpenGL graphics on the screen” code was similar it might not be too hard. In the respect that the DOOM iOS port also used EAGLView, it was pretty similar. In pretty much every other respect it wasn’t.

For starters, there’s two different GitHub repositories on id Software’s account, DOOM-iOS, described on there as “DOOM Classic for iOS Source Release” and DOOM-iOS2, described as “DOOM Classic for iOS version 2”, but the readme file for DOOM-iOS describes it as version 2.1 and the readme file for DOOM-iOS2 describes it as version 3.0. The last version released on the App Store was listed as version 2.7, which matches neither of them.

DOOM-iOS features no xib files other than MainWindow.xib, and every screen is done in that one file as separate views, which are mostly swapped out using the app delegate (almost like a Storyboard before iOS development had the concept of Storyboards). They have their own classes but they’re not using UIViewController classes. DOOM-iOS2 uses UIViewControllers and multiple xib files, similar to how Wolfenstein 3-D is set up. It also features multiple other embedded sub-projects, including one called “idmobilelib” that had build issues of the variety where Stack Overflow tells you that need to rethink how you’re doing things because that shit is old. It also wasn’t clear what it was doing but things like friends and matchmaking were mentioned in the code which is odd since neither game featured multiplayer. Neither repo would build out of the box on Xcode 9. There were a few forks of DOOM-iOS from people but there were a lot of forks of DOOM-iOS2, probably since logic would dictate it’s the latest code.

After a lot of looking and fiddling and back and forth, I have a theory on what’s going on here. The original repo, DOOM-iOS, is the code of the original game, and it’s the basis of the one that was on the App Store last. The version on the App Store was listed as v2.7 but the only change was “iOS 7 compatibility”. The previous version was v2.1 which matches DOOM-iOS’s stated version. I think since the only fix was iOS 7 stuff, that the number was bumped up to 2.7 as a joke to include the number 7.

So what was DOOM-iOS2 then? I think it was done as an overhaul of DOOM for iOS and was going to include things such as a unified id Software library for handling things on iOS across all their games, but then id decided to leave the mobile market and it never got used in an App Store release. However, since they had done all the work they figured they might as well throw it on GitHub. Looking at the original 1.0 checkin of Wolfenstein 3-D for iOS, it looks like that game did a similar thing with the single xib file and no view controllers. I think they went in and overhauled Wolfenstein 3-D and then did the same thing to DOOM, but Wolfenstein 3-D‘s overhauled version actually saw a release whereas DOOM did not.

To the extent that I had even thought about making a pull request to id Software to update the code, I figured the best bet was to update the code only and check that in for the pull request. But this two DOOM repos thing gave me a dilemma – do I update DOOM-iOS which is probably the last thing on the store, or do I update DOOM-iOS2, which was not? To say nothing of the fact that DOOM-iOS2 had a number of forks from enthusiast individuals who had done a fair amount of work, so what was the point of even messing with it in the first place?

After a lot of debate I decided to take a hybrid Frankenstein approach. I would update DOOM-iOS, the original one, using a lot of the code and methods from DOOM-iOS2, and incorporating the work of some community forks, in particular a fork by GitHub user JadingTsunami renamed “FinalJudgement” for some reason. I ditched the concept of embedded projects in favor of just using the code from the other projects in separate directories, and only taking the parts of “idmobilelib” that were actually being used, which luckily avoided the messy complicated deprecated bits. There was still a fair amount of work to do, such as getting the xib files to use Auto Layout, replacing the UIScrollViews on the mission select and credits screens with UITableViews, and restoring the Credits screen on the iPhone version, which had been replaced in the FinalJudgement port with a screen allowing you to choose different WAD files (I left it in under “SecretScreenViewController” but it’s not accessible by default). Once I went down this path it went much quicker and smoother than I had anticipated. Finally, like the Wolfenstein 3-D code, I went in and added MFi controller support but this time I grafted in code from another commit by GitHub user TheRohans.

So then the final issue, I thought, was the resources for the menus. Since the original version of Wolfenstein 3-D appears to have drawn all the menus using the engine (makes sense, since this is how it would work on every other platform) it didn’t include the menu art needed for the later multiple-xib version. I acquired the artwork from… somewhere… but it’s not something I can include in the repos because it’s copyrighted material, but I also want these repos to be buildable which they can’t be without the menu art. So I created placeholder art for the menus and buttons. I went with a simple school book/Field Notes vibe, both for style reasons and also because it was the quickest and easiest to do (and I’m not an artist).

In the home stretch of all of this, I upgraded to an iPhone X. Also around that same time a game called Fortnite came to iOS and a couple of things that were noted is how this is the exact same version as the PC/console versions (or at least as much as the phone can run, which is surprisingly close) and can play on the same servers, and how it fills to fit the iPhone X screen. The ports of DOOM and Wolfenstein 3-D were not filling the iPhone X screen. Apple’s iOS SDK does this every time there’s a screen size change – if your app has not been updated to handle the latest screen sizes and devices it restricts it to the size of the screen it was designed for. This way it doesn’t break anything if you were relying on the screen size not changing. I made the changes necessary to have it fill the iPhone X screen (the only real change needed was to add a launch screen Storyboard) and it worked – except for the fact that a number of my Auto Layout decisions for the menus were based on bad assumptions. The apps as they stand now use a background image and rely on the text for buttons being in a very specific place in order to look right. As a result the best way to handle the menus is to have them basically be at the same 320×480 as the original iPhone screen (stretched to @2x or @3x as needed, so it’s not some tiny menu in the middle of the HD-or-higher resolution of recent phones). If these were redesigned today you’d break up the graphics differently but doing that was outside of the scope of what I was trying to do. The one thing I wasn’t able to address was the bar thing at the bottom of the iPhone X screen (which near as I can tell does not have an official name other than “bar thing at the bottom of the iPhone X screen”). It collides with the HUD at the bottom but any efforts I made to shrink the screen by a few pixels ran into issues with regards to where touches land and I just didn’t think it was a big enough deal to keep fooling with for now. Maybe later.

So the result is an update to DOOM-iOS which brings its design and practices in line with the Wolfenstein 3-D iOS port and updates it for modern devices.

This is pretty cool.

This is also pretty cool.

The Wolfenstein 3-D update is such that anyone can download it and run and compile it without needing anything else. The original code included the levels so this update includes them too. The app can also run the Spear of Destiny levels but since those weren’t included they’re not included here either.

The DOOM update is such that it can’t run completely right out of the box because it needs the data from the original game, which I figured would be no big deal. Just drop in a “doom.wad” file from an installation of the DOS version of DOOM (available on Steam and GOG) and you’re off, right?

feels good man

Well, not quite.

Something I didn’t realize until the very end of the road was there’s actually two data files you need. The first is “doom.wad” and like I said you can get that from a copy you’ve purchased. The second, however, was “base.iPack” and I had not noticed its importance before. I had made new assets for the menus and buttons for use in xib files but I realized there were no images of the iPhone controls (the cross and buttons on the in-game screens), but those wouldn’t have come from the doom.wad file since they wouldn’t have existed back then. Turns out they’re from the base.iPack file. When I got the images for the menus from… somewhere… it included this file as well. There’s also a “base.parm” file that is a really small text file so I may have had them confused and not realized the significance of base.iPack.

At this point it hits me that there’s a second project in the DOOM-iOS directory called “doomtool” that I had basically ignored to this point. After some digging and experimentation and a few Google searches (to discover there’s scant information about this file online), it looks like base.iPack is essentially a parallel data file that houses images and sound effects, and the doomtool utility can create it. It’s about 6MB, compared to the 12MB of doom.wad. The textures are run through a texturetool utility that comes with Xcode. The sound effects don’t seem to have any processing but they come from WAV files. You can’t run the doomtool utility to create the base.iPack file unless you have these image and sound assets ready to go and can point to the directory where to go. Some amount of looking through the code says that the images in this file may be processed in some way that makes them more amenable to whatever the iPhone needs for displaying, and/or it’s quicker to access them and the sounds this way in order to get them played in menus or the game proper or whatnot. It may or may not be related to the speed of the original iPhone and iPhone 3G, which were the devices on the market when this game came out. Basically I’m not 100% on why this file needs to exist but a bunch of really smart people came up with it so I’m going with it. Also, I think this is the real reason why Carmack included the extra files with the Wolfenstein 3-D port – some of them probably had to go through this texturetool process and he just saved everyone the effort.

That all said, doomtool is nice to have because it comes up with this file for us but the problem is you don’t have easy access for the files it needs to create the base.iPack file in the first place. Some or all of the graphics in it are iPhone-specific, so I will need to create replacements for those, except I can’t get them out of the base.iPack file to know what dimensions and so forth to go with. There’s code in the app to read base.iPack but my C/C++ knowledge is rusty and it’s also designed to read the base.iPack file, not write out data. I mean, it’s possible but I just haven’t dug in to figure it out yet and for fear that it might take a long time I decided it’s not worth holding up the show.

And then you need WAV files of the various sound effects in the doom.wad file, and this is a heck of a rabbit hole to go down. Pretty much ever since the release of the original DOS game there’s been a cottage industry of WAD hacking tools and utilities. But you find some link on some message board from a decade or more ago and the links they have to the tools are all dead. And a number of the tools were written back in the DOS days and “may have problems on Windows XP” so the over/under of them working on a 64-bit Windows 10 machine are probably slim anyway. I found an app that extracts WAD files and they even had the source code available… in Borland Delphi. Oh, and the links are broken anyway. I did find one reasonably recent utility that can list and extract the contents of a WAD file, and it’s in GitHub as source code, but it’s written in C# for .NET on Windows. And it extracts the WAD file to a bunch of discrete files representing its contents, but the sound effects are all in a not-quite-WAV file format that the original DOOM engine used because of that proprietary sound library but that’s not the format we need. It does look like this utility may have a secondary function to turn those into usable WAV files but I haven’t had a chance to investigate it yet. It’s probably possible to have this C# code grafted into a Mono/.NET Core project that could run in Visual Studio for Mac, but that’s one more thing to have to have in order to get this up and running for an end user/developer. Ideally I’d modify or expand doomtool to handle all of this and it’s entirely possible, but I just haven’t had the chance to get to that yet.

So all of this is to say that if you download the DOOM-iOS fork I have with with the latest fixes and substituted assets, you’re going to have to supply your own base.iPack file. And I can’t tell you where to find it. If I’m lucky, perhaps id will let me distribute it. After all, it’s pretty useless without the doom.wad file, but I haven’t asked yet.

So anyway there you have it. I don’t know if id will pay any attention to the pull request and I don’t know if anyone besides me even cares but it was fun to dig into old code by iOS standards and even older code by video game standards. If anyone wants to contact me I can be reached at tomkidd@gmail.com.

Thanks.

Categories: