Wednesday, May 20, 2015 Eric Richards

Setting up Chocolate Wolfenstein 3D in Visual Studio 2013

For the past few weeks, I've been once again noodling on the idea of starting a .NET port of a classic Id FPS. As a kid on my first computer, an off-brand 486 with DOS, I just hit the tail end of the good old days of shareware. And amongst all the floppy disks of kiddy and educational software and sliming Gruzzles couldn't really hold a candle to exploring Indiana Jones and the Last Crusade-esque Gothic castles and knifing Nazis.

While the original source-code for Wolfenstein 3D has been available for some time, it is a bit of a slog trying to wade through C code that was written 20 years ago, with near and far pointers, blitting directly to VGA memory, and hand-rolled assembly routines, let alone build the project successfully. Consequently, converting over to C# is a bit of a struggle, particularly for some of the low-level pointer manipulation and when loading in binary assets - it is very helpful to be able to step through both codebases side by side in the debugger to figure out any discrepancies.

Because of these difficulties, I have started looking at the Chocolate Wolfenstein 3D project, by Fabien Sanglard. Mr. Sanglard is a great student of the Id Software engine source code, and has done several very nice writeups of the different engines open-sourced by Id. He was even planning on writing a book-length analysis of Wolfenstein 3D, which hopefully is still underway. Chocolate Wolfenstein 3D is a more modernized C++ conversion of the original Id code, with some of the more gnarly bits smoothed out, and using SDL for cross-platform window-management, graphics, input, and sound. Even better, it can be built and run using current versions of Visual Studio.

The only problem I had with the Chocolate Wolfenstein 3D GitHub repository is that it is missing some dependencies and requires a small amount of tweaking in order to get it to build and run on Visual Studio 2013. These steps are not particularly difficult, but if you simply clone the repo and hit F5, it doesn't work right out of the box. If you are working on a Mac, there is a very nice guide on setting up the project in XCode, but I have not found a similar guide for Windows, so I decided to document the steps that I went through and share those here.

Chocolate Wolfenstein 3D title screen

Setting up Chocolate Wolfenstein 3D in Visual Studio 2013

First Steps

The first step is to either clone the Chocolate-Wolfenstein-3D project using git, or download the project zip file from GitHub at https://github.com/fabiensanglard/Chocolate-Wolfenstein-3D.

If you open the Visual Studio solution in /win32/vs2008, you will be prompted to do the normal project upgrade dance, since the solution was originally authored for VS2008. After this, if you attempt to build the project, you will see a big pile of errors reporting that SDL.h could not be found. If you open up the properties for the project, and go to C/C++->General, you will see that there are some additional include directories setup for the SDL header files, which are not present in the downloaded project.

Additional SDL include directories

Getting SDL-1.2.15

SDL is currently at version 2.0.3, after an extensive, long awaited rewrite. However, the 1.2.15 version which this project is built against is still available from their website. What we want here are the 1.2.15 development libraries. Download this archive, and copy the SDL-1.2.15 folder contained into the same directory as the choco_wold3s.vcxproj file (should be /win32/vs2008/choco_wold3s). Build again.

Once again, the build should fail, with a couple of errors complaining that SDL_mixer.h could not be found.

Getting SDL_mixer 1.2.12

The SDL_mixer development libraries can be downloaded from https://www.libsdl.org/projects/SDL_mixer/release/SDL_mixer-devel-1.2.12-VC.zip . Once again, extract the downloaded zip file, and copy the SDL_mixer-1.2.12 folder into the /win32/vs2008/choco_wold3s directory. Build once more. The project should now build successfully. If you attempt to run the program, however, you will see the following error message:

SDL_mixer.dll missing

Copying over SDL_mixer.dll and SDL.dll

Initially, I was stumped for some time at this point. Typically, working with C# .NET projects, I would expect that any linked DLLs ought to be copied to the project's bin/Debug (or bin/Release) directory. For this project, there is no ./bin/ directory, but there is a ./Debug/ directory, so I tried to copy the SDL DLLs into that directory, but I still received the same error message. Eventually, I realized that this project was setup to copy the generated executable into $(SolutionDir)$(Configuration)\, which is the Debug folder one directory up from the project directory (i.e. /win32/vs2008/Debug, not /win32/vs2008/choco_wold3s/Debug), so the SDL DLLS need to go there.

  1. From the SDL_mixer-1.2.12 folder, copy lib/x86/SDL_mixer.dll into the solution Debug folder.
  2. If you run at this point, you will see a different error message, complaining that SDL.dll is missing
    SDL.dll missing
  3. From the SDL-1.2.15 folder, copy over lib/x86/SDL.dll into the solution Debug folder

After copying the DLLs over, when you run the project, it will stop crashing, but you will then see this error message:

No data files...

Obtaining the Wolfenstein 3D Data Files

Obviously, to run the game, we are going to need the art, sound, and data assets. These are not packaged with the GitHub repository for copyright reasons, so you will need to get them from somewhere else.

I happen to have the Steam version of Wolfenstein, which includes all the episodes and the full set of assets. On my machine, these were located in C:\Program Files (x86)\Steam\SteamApps\common\Wolfenstein 3D\base. In this directory (or wherever your Steam library is), you'll find a number of .WL6 files, which contain these data assets. Copy all of these over into the /win32/vs2008/Debug directory.

If you don't have a purchased copy of Wolfenstein 3D, you can also use the set of assets from the shareware version. These are available at various more or less legitimate places on the Internet, pretty easily found with a quick search for "Wolfenstein 3D shareware data files". These should have the file extension .WL1.

With the data files copied over, we should be ready to go, right? Not so fast. If you try to run the project from within Visual Studio, you will probably still see the "NO WOLFENSTEIN 3D DATA FILES to be found!" error message. Why?

Setting the Debugging Working Directory

If you once again open the project properties, and open the Debugging page, you'll see that the project is setup for the debugger working directory to be $(ProjectDir), which is /win32/vs2008/choco_wold3s/Debug. Except that we're actually copying our executable and all the data files to /win32/vs2008/Debug. So you will need to change this value to $(SolutionDir)$(Configuration)\, to match the output directory.

With that change made, build and run the project again. If you are using the shareware WL1 data files, the game should start up and run at this point. If you are using the full version data assets (WL6) from Steam or elsewhere, there is one more step that we need to perform.

Tweaking version.h

The Wolfenstein 3D code uses conditional compilation extensively to define constants that map the art and level assets for each different version, based on a set of #defines which are declared in version.h for Chocolate Wolfenstein. Out of the box, the project is setup to use the shareware assets. To use the full-version assets, you will need to edit version.h, and comment out the line #define UPLOAD. This should leave #define GOODTIMES and #define CARMACIZED. There are comments in this file describing which set of defines work with which set of assets.

Success?

At this point, you should be able to build and run the project, and play Wolfenstein 3D. Even better, you can insert logging statements to document any tricky bits, or step through in the debugger (at least when it doesn't want to bring my entire machine to a stutter, but that's another topic...).

First level start