Doom (linuxdoom-1.10) patched to compile and run on 64-bit Linux / WSL2 with TrueColor X11 and SDL audio.
Doom source port family tree (modified from Wikipedia)
The original linuxdoom-1.10 source release from id Software assumes 32-bit pointers and 8-bit PseudoColor X11 displays — neither of which exist on modern systems. This repo contains the minimal patches needed to get it running on x86-64 Linux (including WSL2 on Windows).
| File | Change | Why |
|---|---|---|
r_data.c |
*4 → *sizeof(void*) for pointer arrays |
Pointer arrays need 8 bytes per entry, not 4 |
r_data.c |
void **columndirectory → int columndirectory |
WAD format uses 32-bit offsets; void** adds padding on 64-bit |
p_setup.c |
total*4 → total*sizeof(line_t*) |
Pointer array allocation |
d_net.c |
(int)& → (long)& |
Pointer-to-int casts need long on LP64 |
p_saveg.c |
(int) → (long) for pointer/index casts |
Same |
r_draw.c |
(int)translationtables → (long) |
Same |
m_misc.c |
(int) "string" → (long) "string" |
Same |
i_sound.c |
extern int errno → #include <errno.h> |
glibc defines errno as a macro |
i_system.c |
mb_used = 6 → mb_used = 32 |
64-bit pointer arrays + sound precaching need more zone memory |
m_misc.c |
defaultvalue field int → long, *(long*) writes for string entries |
default_t stores string pointers in defaultvalue; 4-byte int truncates 64-bit pointers |
info.c/info.h |
sprnames[NUMSPRITES] → sprnames[NUMSPRITES+1] with 0 terminator |
R_InitSpriteDefs iterates until NULL; original relies on zero-filled memory after array |
d_main.c |
Removed #ifndef SNDSERV / #ifndef SNDINTR guards |
These conditionals are unnecessary without the external sound server; removing them allows the in-process mixing and SDL output to run |
m_misc.c |
Removed SNDSERV defaults block (sndserver_filename, mb_used=2) |
Not used with SDL audio |
Modern X servers don't support 8-bit PseudoColor. i_video_truecolor.c replaces i_video.c with:
- 24-bit TrueColor visual instead of 8-bit PseudoColor
rgb_palette[256]lookup table for 8-bit → 32-bit ARGB conversion- Separate
screens[0]buffer (8-bit indexed, not aliased to 32-bit XImage) - Works with MITSHM extension on WSL2
The original linuxdoom-1.10 output sound via OSS (/dev/dsp), a Linux audio API deprecated in 2002 and unavailable on modern systems. The game also supported an external sndserver process, but this was a separate proprietary binary not included in the source release. As a result, the open-source Linux Doom had no working audio out of the box.
i_sound_sdl.c replaces i_sound.c with SDL2 audio output:
- All original mixing code (channel management, volume lookup, stereo separation) is preserved unchanged
- OSS
open("/dev/dsp")+write()replaced withSDL_OpenAudioDevice+SDL_QueueAudio - Audio queue capped at ~100ms to prevent sound delay accumulation
- Removed OSS includes,
ioctlhelpers, and timer interrupt code (SNDINTR) - Fixed linked sound length calculation:
(ptr - array)/sizeof(T)→ptr - array(C pointer subtraction already returns element count, extra divide was wrong in original) sndserver_filenameretained as a stub for compatibility with the defaults system
SDL2 was chosen over PulseAudio or ALSA because it automatically selects the best available backend (PulseAudio, PipeWire, ALSA, etc.) — no user configuration needed. It's also the standard audio library used by every modern Doom source port.
No music support yet — Doom's MUS format requires a MIDI synthesizer, which is a larger addition.
sudo apt install gcc libx11-dev libxext-dev libsdl2-dev# Compile (skip original i_video.c and i_sound.c — replaced by patched versions)
for f in *.c; do
[ "$f" = "i_video.c" ] && continue # use i_video_truecolor.c instead
[ "$f" = "i_sound.c" ] && continue # use i_sound_sdl.c instead
gcc -c -DNORMALUNIX -DLINUX -w "$f" -o "$(basename "$f" .c).o" $(sdl2-config --cflags)
done
# Link
gcc *.o -o linuxxdoom -lXext -lX11 -lm $(sdl2-config --libs)You need a WAD file. The shareware doom1.wad works:
./linuxxdoom -iwad doom1.wadTo jump straight to a level:
./linuxxdoom -iwad doom1.wad -warp 1 1You need an X server running on Windows. Options:
Set DISPLAY in your .bashrc:
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0| Key | Action |
|---|---|
| Arrow keys | Move / turn |
| Ctrl | Shoot |
| Space | Open doors / use |
| Shift | Run |
| Escape | Menu |
| Tab | Automap |
| 1-7 | Select weapon |
Original source code released by id Software under the Doom Source Code License.
