Skip to content

danielgatis/doomgeneric

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

142 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

doomgeneric

The purpose of doomgeneric is to make porting Doom easier. Doom is already very portable, but with doomgeneric you can port it with just a few functions.

Requirements

WAD File

You need a WAD file (game data) to run Doom. The shareware version (doom1.wad) is included in the iwads/ folder.

Sound (SDL-based platforms)

For MIDI music support, a SoundFont file is included in the sounds/ folder:

  • gzdoom.sf2 - GZDoom Classic SoundFont (3.1MB)

Project Structure

doomgeneric/
├── iwads/
│   └── doom1.wad         # Doom shareware WAD
├── sounds/
│   └── gzdoom.sf2        # GZDoom Classic SoundFont
├── doomgeneric/          # Core Doom source code
└── platforms/            # Platform-specific implementations
    ├── sdl/              # SDL2 (cross-platform)
    ├── terminal/         # Terminal rendering (notcurses + SDL audio)
    ├── wasm/             # Standalone WebAssembly module
    ├── xlib/             # X11 (Linux)
    ├── linuxvt/          # Linux framebuffer
    ├── freebsd/          # FreeBSD with X11
    ├── emscripten/       # WebAssembly (browser)
    ├── djgpp/            # DOS with Allegro
    ├── soso/             # SoSo OS
    └── sosox/            # SoSo OS with Nano-X

Each platform folder contains:

  • Makefile - Build configuration
  • main.c - Platform-specific implementation

Building

From the project root directory:

# Build for a specific platform (using convenience targets)
make sdl
make terminal

# Or using PLATFORM variable
make PLATFORM=sdl

# Run
./platforms/sdl/bin/doomgeneric -iwad ./iwads/doom1.wad

# Run with MIDI music (SDL platforms)
SDL_SOUNDFONTS=$(pwd)/sounds/gzdoom.sf2 ./platforms/sdl/bin/doomgeneric -iwad ./iwads/doom1.wad

# Terminal platform with sound
SDL_SOUNDFONTS=$(pwd)/sounds/gzdoom.sf2 ./platforms/terminal/bin/doomgeneric -iwad ./iwads/doom1.wad

Available Platforms

Platform Description Requirements
sdl SDL2 rendering + sound SDL2, SDL2_mixer
terminal Terminal rendering with notcurses notcurses, SDL2, SDL2_mixer
wasm Standalone WebAssembly module wasi-sdk
xlib X11 rendering X11
linuxvt Linux framebuffer Linux
freebsd FreeBSD with X11 X11
emscripten WebAssembly (browser) Emscripten SDK
djgpp DOS DJGPP, Allegro
soso SoSo OS musl-clang
sosox SoSo OS with Nano-X musl-clang, Nano-X

Porting to a New Platform

  1. Create a new folder under platforms/:

    mkdir platforms/myplatform
  2. Create main.c implementing these functions:

    Required functions:

    Function Description
    DG_Init Initialize your platform (create window, framebuffer, etc.)
    DG_DrawFrame Frame is ready in DG_ScreenBuffer. Copy it to screen.
    DG_SleepMs Sleep for given milliseconds
    DG_GetTicksMs Return ticks since launch in milliseconds
    DG_GetKey Provide keyboard events
    DG_SetWindowTitle (Optional) Set window title
    DG_Log (Optional) Handle log output. Default prints to stdout.

    Sound support (optional):

    For sound effects and music, add -DFEATURE_SOUND to CFLAGS and include the appropriate sound modules in your build:

    Module Files Description
    SDL Sound i_sdlsound.c Sound effects via SDL2_mixer
    SDL Music i_sdlmusic.c MIDI music via SDL2_mixer (requires SoundFont)
    Allegro Sound i_allegrosound.c Sound effects via Allegro
    Allegro Music i_allegromusic.c Music via Allegro

    These modules define DG_sound_module and DG_music_module which are used by the engine.

  3. Basic main loop structure:

    #include "doomgeneric.h"
    
    // Implement DG_* functions here...
    
    int main(int argc, char **argv)
    {
        doomgeneric_Create(argc, argv);
    
        while (1)
        {
            doomgeneric_Tick();
        }
    
        return 0;
    }
  4. Create a Makefile (use an existing one as template):

    # Directories
    SRCDIR=../../doomgeneric
    OBJDIR=./build
    BINDIR=./bin
    
    CC=clang
    CFLAGS+=-I$(SRCDIR)
    # ... add your platform flags
    
    OUTPUT=$(BINDIR)/doomgeneric
    
    SRC_DOOM = dummy.o am_map.o ... # (copy from existing Makefile)
    SRC_ENTRY = main.o
    
    # ... rest of Makefile rules
  5. Build and test:

    cd platforms/myplatform
    make
    ./bin/doomgeneric -iwad ../../iwads/doom1.wad

WebAssembly (WASM) Platform

The wasm platform compiles DOOM to a standalone WebAssembly module that can be embedded in any host language (JavaScript, Rust, Go, Python, etc.).

Building

# Install wasi-sdk from https://github.com/WebAssembly/wasi-sdk/releases
# Extract to /opt/wasi-sdk or set WASI_SDK environment variable

make wasm
# Output: platforms/wasm/bin/doomgeneric.wasm

Host Interface

The WASM module imports these functions from the host (module: env):

Video/Input (required):

Import Signature Description
DG_Init () -> void Initialize the platform
DG_DrawFrame () -> void Render frame from screen buffer
DG_SleepMs (ms: i32) -> void Sleep for milliseconds
DG_GetTicksMs () -> i32 Get ticks since start
DG_GetKey (pressed: *i32, key: *u8) -> i32 Get keyboard input
DG_SetWindowTitle (title: *u8) -> void Set window title
DG_Log (msg: *u8) -> void Handle log output

Sound (optional - return 0/stub if not implementing):

Import Signature Description
DG_InitSound (samplerate: i32) -> i32 Init sound, return 1 on success
DG_ShutdownSound () -> void Shutdown sound
DG_StartSound (id, channel, vol, sep: i32, data: *u8, len: i32) -> i32 Play sound effect
DG_StopSound (channel: i32) -> void Stop sound on channel
DG_SoundIsPlaying (channel: i32) -> i32 Check if channel is playing

Music (optional - return 0/stub if not implementing):

Import Signature Description
DG_InitMusic () -> i32 Init music, return 1 on success
DG_ShutdownMusic () -> void Shutdown music
DG_SetMusicVolume (volume: i32) -> void Set volume (0-127)
DG_PauseMusic () -> void Pause music
DG_ResumeMusic () -> void Resume music
DG_PlayMusic (data: *u8, len: i32, loop: i32) -> void Play MIDI data
DG_StopMusic () -> void Stop music
DG_MusicIsPlaying () -> i32 Check if music is playing

The WASM module exports these functions:

Export Signature Description
doomgeneric_Create (argc: i32, argv: i32) Initialize DOOM
doomgeneric_Tick () -> void Run one game tick
DG_ScreenBuffer () -> i32 Get pointer to pixel buffer
DG_GetScreenWidth () -> i32 Get screen width (320)
DG_GetScreenHeight () -> i32 Get screen height (200)
doom_malloc (size: i32) -> i32 Allocate memory
doom_free (ptr: i32) -> void Free memory

Pixel Format

DG_ScreenBuffer returns a pointer to a 320x200 array of 32-bit ARGB pixels.

License

See LICENSE file.

About

Easily portable doom

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • C 98.2%
  • Makefile 1.2%
  • C++ 0.6%