Native Android build of DethRace — the clean-room reimplementation of the 1997 game Carmageddon. This fork takes the upstream opengles branch, wires it into a Gradle/NDK project, replaces the desktop OpenGL bits with OpenGL ES 3, and adds a touch overlay and lifecycle handling so the game is actually playable on a phone.
The desktop builds still work. Every Android-specific change is gated behind
#ifdef __ANDROID__orif(ANDROID)in CMake. Pull fromdethrace-labs/dethraceupstream and you'll see no behavioural differences on Linux / macOS / Windows.
Tested on Galaxy S25 Ultra (Adreno 830, Android 16) — should run on any Android 7+ device with GLES 3.
You don't have to build anything. Each push to android-port produces a debug APK as a CI artifact:
- Open https://github.com/mgrz18/dethrace-android/actions/workflows/android.yml
- Click the most recent green run.
- Scroll to Artifacts and download
dethrace-android-debug-apk. - Unzip — inside is
app-debug.apk. - Install it:
adb install -r app-debug.apk(or sideload from the file manager). - Provide the game data (next section).
If you don't see Artifacts, you need to be signed in to GitHub.
You must own and provide your own Carmageddon files. The APK is empty without them — it'll launch and immediately show a "Couldn't open Key Map file" error until you finish this section.
Easiest source: Carmageddon Max Pack on GoG → https://www.gog.com/game/carmageddon_max_pack.
After installing it on Windows, the install path is typically:
C:\GOG Games\Carmageddon Max Pack\
If you're on macOS/Linux you don't need Windows — extract the offline installer with innoextract (brew install innoextract).
Inside the install you'll find this structure (only the bits in bold matter):
Carmageddon Max Pack/
├── CARMA/
│ └── DATA/ ← *** main game data, ~190 MB ***
├── __support/
│ └── app/
│ └── CARMA/
│ └── DATA/ ← *** GoG support files (KEYMAP_*.TXT, OPTIONS.TXT, PATHS.TXT) ***
└── (a bunch of other folders we don't need: DOSBOX, __redist, etc.)
You need both DATA/ folders. The first is the game. The second ships with GoG and contains the keyboard mapping the engine refuses to start without.
The game expects everything at:
/sdcard/Android/data/com.dethrace.android/files/DATA/
(That's the app's external files dir — Android lets the app read from there without runtime permissions.)
Plug your phone in (USB debugging enabled) and run, from your PC's terminal:
# 1. The main DATA folder
adb push "Carmageddon Max Pack/CARMA/DATA" \
/sdcard/Android/data/com.dethrace.android/files/
# 2. The GoG support files merged INTO the DATA you just pushed
adb push "Carmageddon Max Pack/__support/app/CARMA/DATA/." \
/sdcard/Android/data/com.dethrace.android/files/DATA/The trailing
/.on the secondadb pushmatters — it copies the contents of__support/.../DATA/and merges them into the existingDATA/on the phone, instead of nesting anotherDATAfolder.
-
Compress
CARMA/DATA/and__support/app/CARMA/DATA/into a single zip on your PC, with the layout:carmageddon-data.zip └── DATA/ ├── CARS/ ├── RACES/ ├── ... (everything from CARMA/DATA) └── KEYMAP_0.TXT, KEYMAP_1.TXT, ... (merged in from __support) -
Send the zip to your phone (email, Google Drive, anything).
-
Install a file manager that can write to app-private storage (e.g. Solid Explorer, MiXplorer, Material Files). The stock Samsung "Files" app on Android 11+ won't work — Google blocks
Android/data/from the system file picker. -
Extract the zip into
Android/data/com.dethrace.android/files/. The result must end up asAndroid/data/com.dethrace.android/files/DATA/....
adb shell ls /sdcard/Android/data/com.dethrace.android/files/DATA/ | head
# Expected output includes folders like CARS, RACES, SOUND, ACTORS
# and files like KEYMAP_0.TXT, OPTIONS.TXTIf you see those, you're done — open the app.
- Splat Pack (also part of the GoG Max Pack, in
CARSPLAT/): pushCARSPLAT/DATA/to the same place the same way. The engine auto-detects which game mode is available. - Free demos (
carmdemo,splatdem,Splatpack_christmas_demo) work too — push theirDATA/folder.
The game launches in landscape, fullscreen, immersive (no status bar / no nav bar). Touch overlay only appears when you're actually in a race — menus stay clean and respond to plain taps.
| Region | Action | Equivalent DOS key |
|---|---|---|
| Bottom-left, left disc ◀ | Steer left | Keypad 4 |
| Bottom-left, right disc ▶ | Steer right | Keypad 6 |
| Bottom-right, brake button | Brake / reverse | Keypad 2 |
| Bottom-right, gas button | Accelerate | Keypad 8 |
| Top-right, pause icon | Pause / open menu | Esc |
Touch zones are larger than the rendered icons (you can rest your thumbs in roughly the bottom-left and bottom-right corners — you don't have to aim at the icons). For weapons, lookback, etc., pair a Bluetooth keyboard.
You only need to do this if you want to hack on the port. To just play, see Just want to play? above.
Requirements
- macOS or Linux (Windows untested but should work).
- Android Studio (or the standalone command-line tools) with:
- SDK platform 34
- NDK r26 (
26.1.10909125is what CI uses) - CMake 3.22.1+
- Java 17.
curl,tar,unzip(for the SDL2 download script).
One-time setup
git clone https://github.com/mgrz18/dethrace-android.git
cd dethrace-android
# Pull SDL2 source (~15 MB, extracts into android/app/jni/SDL/)
./android/scripts/setup-sdl.sh
# Tell Gradle where your Android SDK lives
echo "sdk.dir=$ANDROID_HOME" > android/local.propertiesBuild
cd android
./gradlew assembleDebugThe APK lands at android/app/build/outputs/apk/debug/app-debug.apk.
Install + launch
adb install -r android/app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n com.dethrace.android/.DethraceActivityTo stream the game's logs:
adb logcat -s dethrace:V DethRace:V DethRace-native:V SDL:VA short tour of the changes — full diff in the first commit on android-port.
New files
| Path | Purpose |
|---|---|
android/ |
Gradle project, Java code, build scripts, NDK glue |
android/app/src/main/java/com/dethrace/android/DethraceActivity.java |
Custom SDLActivity: forces landscape, sets DETHRACE_ROOT_DIR, immersive fullscreen, mounts the touch overlay, polls race state |
android/app/src/main/java/com/dethrace/android/TouchOverlayView.java |
Steering discs, gas/brake pedals and pause button drawn over the SDL surface |
android/scripts/setup-sdl.sh |
Downloads SDL2 2.30.10 source into app/jni/SDL/ |
src/harness/os/android.c |
Bionic-friendly OS layer (signal handler, case-insensitive OS_fopen) |
src/DETHRACE/android_jni.c |
JNI bridge exposing gProgram_state.racing to Java |
Engine tweaks — all #ifdef __ANDROID__ / if(ANDROID):
harness_trace.c— pipeLOG_*to__android_log_printso panics show up inlogcatinstead of disappearing into stdout.gl_renderer.c— skipglReadPixels(GL_DEPTH_COMPONENT, ...). It'sGL_INVALID_OPERATIONon strict GLES drivers (Adreno) and was crashing on Start Race.sdl_opengl.c— go straight to GLES (no desktop-GL probe), load symbols withgladLoadGLES2Loader, cap to 60 fps via swap-interval 2 on 120 Hz panels, inject Keypad 4/6/8/2 + Esc from touch zones, pauseminiaudioonSDL_APP_*_BACKGROUND.harness.c—start_full_screen = 1by default.main.c— include<SDL.h>so theSDL_mainbridge picks it up.CMakeLists.txtpatches — short-circuitfind_package(SDL2)when SDL2 is already a target, builddethraceaslibmain.so, drop pthread (in bionic), linklog android GLESv3 EGL, swapos/linux.cforos/android.c.
openglesupstream branch is stale — about 700 PRs behindmain. Bug fixes landed there don't carry over yet.- Aspect ratio — the engine renders at the original 320×200 (8:5). On 21:9 phones you'll see black pillars. Removing them while preserving the HUD requires non-trivial engine surgery (see Future work).
- Limited input — only steer/throttle/brake/menu. Weapons, lookback, handbrake etc. need an external keyboard or a future overlay extension.
- Game files must be sideloaded — for legal reasons we can't bundle Carmageddon assets.
- No Splat Pack auto-merge yet — push
CARSPLAT/DATAseparately if you want it.
- Wider-FOV widescreen rendering (requires reallocating the BRender pixmap and HUD-coord remapping).
- Forward-port to upstream
mainto pick up ~700 PRs of fixes. - Configurable touch layout, on-screen weapon buttons.
- Gamepad/keyboard remapping UI on the Android side.
- F-Droid / Play distribution once the port is more polished.
PRs welcome.
The Android port — Gradle/NDK wiring, GLES 3 path, touch overlay, lifecycle handling, widescreen pixmap and the rest of the __ANDROID__-gated changes — was developed in collaboration with Claude Code (Anthropic, Claude Opus 4.7).
Same as upstream DethRace. SDL2 is zlib. Carmageddon assets remain © Stainless Games — bring your own copy.