Important
Mali, PowerVR, Xclipse phones (Dimensity, Exynos, Tensor, Unisoc): make the astc texture cache. Since
v0.4.12, setup can prepare a copy of the game's textures in formats these GPUs read directly (folder
DOOM Mobile/astc, about 0.85 GB). Without it the game converts textures on the fly: it needs several times more
graphics memory, stutters more and may be closed by the system while a level loads. If you prepared your files with an
older setup, run setup again (it only adds the new folder) and copy astc to Download/DOOM Mobile/astc on the
phone: INSTALL, step 5. Snapdragon phones don't need it.
Телефоны с Mali, PowerVR, Xclipse (Dimensity, Exynos, Tensor, Unisoc): сделайте кэш текстур astc. Начиная с
v0.4.12 setup умеет готовить копию текстур игры в форматах, которые эти GPU читают напрямую (папка
DOOM Mobile/astc, около 0,85 ГБ). Без неё игра перекодирует текстуры на лету: ей нужно в несколько раз больше
графической памяти, больше подтормаживаний, и система может закрыть игру во время загрузки уровня. Если файлы
готовились старым setup, запустите его ещё раз (он только добавит новую папку) и скопируйте astc на телефон в
Download/DOOM Mobile/astc: INSTALL, шаг 5.
Телефонам со Snapdragon она не нужна.
A native Android port of DOOM (2016) for Nintendo Switch. The game's own AArch64 program runs directly on the phone's CPU; a small host provides the Switch system services, and the NVN graphics API is replayed on Vulkan. You bring the game: this repository contains no game content.
Русский: ниже.
Install: step-by-step guide for players — docs/INSTALL.md (English) ·
docs/INSTALL.ru.md (по-русски). In short: dump your own game + update v262144 and prod.keys,
put them into put-game-files-here/, double-click setup.bat (or bash setup.sh), copy work/DOOM Mobile to the
phone's Download folder and install the APK from the latest release.
Tested so far on Adreno 750 (Snapdragon 8 Gen 3, Xiaomi 14 Ultra) and Adreno 740 (Snapdragon 8 Gen 2). Other GPUs are untested. Adreno 6xx/7xx use the bundled Mesa Turnip Vulkan driver by default; other Adreno generations get their Turnip package, and non-Adreno GPUs (Mali, PowerVR, Xclipse) use the phone's own driver, with engine fallbacks for features those GPUs lack (see Vulkan drivers and Other GPUs).
Captured on the phone (Adreno 750, Qualcomm driver). The counter in the top-left corner is the port's own FPS / frame time / GPU time overlay (it can be turned off in the settings). These shots predate the aspect-ratio fix: they show the 16:9 image stretched to the 20:9 screen; current builds render 1600×720 widescreen (or 16:9 with side bars).
On-screen controls (shown while no gamepad is connected):
![]() |
![]() |
With a gamepad (Bluetooth / USB): the on-screen controls hide themselves and come back when it disconnects.
![]() |
![]() |
![]() |
![]() |
The gear at the top of the screen opens the port's own settings, on top of the game's menus:
| Setting | Default | What it does |
|---|---|---|
| Dynamic resolution | off | lets the game lower the 3D resolution under load; the same switch as Video → Dynamic Resolution in the game menu, applies at once and is saved in the game profile |
| Vulkan driver | by GPU | Adreno 6xx/7xx: bundled Turnip; other Adreno: their Turnip package; others: system driver. Or any package in Download/DOOM Mobile/drivers (next launch); a driver that fails falls back to the system one with a message |
| Frame rate limit | 60 | 30 / 60 / 90 / 120 (only rates your display supports; next launch; above 60 is experimental) |
| Game language | system | text and voice: system language, Russian or English (next launch) |
| Aim assist | 1 | strength of the game's aim assist; "Как на Switch" keeps the Switch behaviour (next launch) |
| Widescreen | on | 1600×720 (screen aspect, wider view) instead of 1280×720 16:9 with side bars (next launch; turn it off on weaker devices) |
| Rumble | off | controller / phone vibration (next launch; off to save battery) |
| FPS and frame time counter | on | the overlay in the top-left corner |
| 3D resolution | 100% (720p) | 85% / 75% / 67%; the HUD stays at 720p |
| Sharpening (FSR RCAS) | off | weak / medium / strong |
| Look sensitivity | 1.0 | swipe look and the look while FIRE is held |
| Move stick dead-zone compensation | none | offsets the game's own move-stick dead zone |
Each option says whether it applies at once or on the next launch. The dialog follows the system language: English, Russian, Ukrainian, German, French, Spanish, Portuguese, Italian, Polish, Turkish, Simplified Chinese, Japanese, Korean.
It is:
- The original game code, executing natively on the phone — no emulated CPU, no JIT. Switch and Android phones share the AArch64 instruction set; an offline rewriter changes only the few instructions that cannot run unchanged on Linux (x18 use, TLS reads, system calls, counter reads) into calls to the host.
- An HLE host for the Horizon OS services DOOM uses (threads, memory, file system, audio renderer, input, sockets…), and an NVN → Vulkan recorder and engine tuned for Adreno GPUs.
- A phone port: on-screen controls with mouse-like touch look, game controllers, gyro aiming, aim assist, rumble, resolution scaling and sharpening, the game's own languages (including Russian) following the phone's locale.
It is not:
- An emulator, cloud gaming or streaming.
- A source of game content. There is no game program, data, shader, text or key in this repository, and the APK contains none. You dump DOOM from a Switch you own and convert it on your PC (docs/doom/GAME_FILES.md). What the repository knows about the game (patch addresses, cvar names, shader identifiers…) is listed in docs/doom/DERIVED.md.
- Online. The MULTIPLAYER entry is removed from the main menu and every network / account service answers like a console without a connection; the campaign runs fully offline.
- Affiliated with id Software, Bethesda, ZeniMax, Panic Button or Nintendo.
Tested on Snapdragon 8 Gen 3 / Adreno 750 (Xiaomi 14 Ultra) and Snapdragon 8 Gen 2 / Adreno 740 (Xiaomi 13 Pro). Other Snapdragon devices may work; other GPUs are untested.
- The campaign is playable from the main menu through gameplay. Output is 1600×720 widescreen by default on a 20:9 screen (same height as the Switch's handheld 720p, with a wider Hor+ view: more on the sides, nothing stretched); the original 1280×720 (16:9) with side bars is optional in the settings and ~25% lighter on the GPU.
- Performance at 1600×720 with Turnip v27: Snapdragon 8 Gen 3 (Adreno 750) — 50–60 fps in most of the campaign (capped at 60), the heaviest areas ~35–50 fps; Snapdragon 8 Gen 2 (Adreno 740) — ~40–50 fps, heavy areas ~33–40 fps (measured on a warm, thermally throttled phone). Turning widescreen off (1280×720) helps on 8 Gen 2 in pixel-heavy scenes. Level loads use a fast NEON zlib. Since v0.4.1 scenes with in-game video screens no longer drop to ~20 fps (an audio renderer wait, fixed); v0.4.2 keeps the GPU busier between frames (a deeper submit queue), about +7–10% fps in the heaviest scenes on 8 Gen 2; v0.4.3 trims GPU work without changing the image (shader and pass clean-ups, skipped dead occlusion boxes), another ~1.4–1.9 ms per frame, about +9–11% fps on 8 Gen 2. v0.4.4 shortens the hitches when a level starts and when you enter a new area (faster texture uploads, shaders read from internal storage instead of the shared Download folder): about −35% in total time spent in frames over 100 ms. The frame rate limit above 60 now really reaches the game (90 / 120 Hz screens). v0.4.5 adds a Light mode (the Switch handheld quality preset, for weaker phones), a working 3D resolution option, and dynamic resolution that targets 30 / 45 / 60 fps using the port's own GPU timing; menus and loading screens now run at 60 so loads are fast with a higher limit. After updating to v0.4.5 run the setup again once: it regenerates the patched game files these options need (with the old ones the new options stay off). v0.4.6 trims the translation thread further (bigger pipeline cache, cached driver constant blocks, fewer image checks, present on its own thread, -O3 engine build) and makes dynamic resolution keep lowering while it still saves GPU time: in the heaviest spots on 8 Gen 2 with dynamic resolution on, about 38 → 48 fps. v0.4.7 records the Vulkan commands on their own thread (about −2.7 ms of translator CPU per frame), fixes the game speed (game time ran 4 % slow in gameplay and 2× fast in menus at 60 fps; both now follow real time) and adds an optional GSR upscale to the screen's native resolution in the gear settings. v0.4.8 makes swipe-look follow the finger exactly, including slow, smooth movements: the swipe now drives the game's own gyro-aim channel like a touchpad, instead of tilting the right stick. Optimisation is ongoing. The game's adaptive tick keeps game speed equal to real time at any frame rate.
- Memory: the game uses about 1.2–2 GB of RAM; its VRAM pools get extra headroom only on phones with 14 GB or more (half on 12 GB phones). On 8–12 GB phones close background apps before playing: when Android has to swap them out, level loads become much slower.
- Input: on-screen pad (left stick, mouse-like look on the right half, FIRE that also looks while held, R3), Bluetooth / USB controllers (the on-screen pad hides while one is connected), gyro aiming, aim assist with adjustable strength, rumble.
- Settings (gear button): widescreen, frame rate limit, light mode (Switch handheld preset), 3D render resolution, dynamic resolution with a target fps (shared with the game's Video menu), RCAS sharpening, Vulkan driver (by GPU, or your own package), game language, aim assist strength, rumble, frame counter, look sensitivity, and the gear button itself (normal, or faded with an opacity slider). The in-game Video menu's Chromatic Aberration entry is repurposed as Dynamic Resolution.
- The game's GPU triangle culling (
r_geometryCulling,r_smallTriangleCulling) is off by default: on our GPU path it dropped visible triangles. Turning it on (DM_DOOM_GEOMCULL=1) is for debugging only. - Dynamic resolution is off by default; enable it in the gear settings or the Video menu and pick its target fps.
- Only update v262144 is supported; the patches and addresses are tied to its build id.
- Turnip is the default driver and matches or beats the stock Qualcomm driver on Adreno 750; on other Adreno generations you may need another Turnip build (see Vulkan drivers); non-Adreno GPUs use the system driver.
- The heaviest scenes are still below 60 fps (see above).
- The gear dialog's 3D render resolution currently has no effect (the game ignores the forced scale while dynamic resolution is off); a fix is in progress.
- The port's settings dialog is translated into 13 languages (system locale, English by default).
- Many renderer fixes are still behind switches for A/B testing; see docs/doom/SWITCHES.md.
Requirements: Android SDK with NDK r29, CMake ≥ 3.22 and Ninja, JDK 17+ and Gradle, Python 3. Clone with submodules:
git clone --recursive <this repository>
# or, in an existing clone:
git submodule update --init --recursiveConfigure and build the native host for DOOM (DM_GAME=doom; the default d2r builds the original D2R host):
cmake -S dm/android -B work/build-android -G Ninja \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-31 -DCMAKE_BUILD_TYPE=Release -DDM_GAME=doomThen build, sign and (optionally) install the APK — build.bat on Windows (wraps the PowerShell script), pwsh
elsewhere:
build.bat [-Install <adb serial>] # Windows
pwsh tools/build_apk.ps1 [-Install <adb serial>] # Linux / macOS with PowerShellThe script reads every tool path from the environment (ANDROID_HOME, JAVA_HOME, GRADLE, PYTHON) and signs with
DM_KEYSTORE (default: the Android debug keystore in ~/.android). Output: work/DOOM-port-debug.apk, app id
org.doom.port. work/ is git-ignored and holds every build output and every game-derived file.
Full guide: docs/INSTALL.md (English) / docs/INSTALL.ru.md (Russian).
- Dump your own copy (base game
0100416004C00000+ update0100416004C00800v262144, as NSP / NSZ / XCI / XCZ) and your console'sprod.keys— e.g. with nxdumptool and Lockpick_RCM on your Switch. - Put the files into
put-game-files-here/(any names) and double-clicksetup.bat, or runbash setup.shon Linux / macOS (explicit files in any order work too;setup checkreports what is missing and changes nothing). Setup provides Python, its packages and the .NET 10 SDK intools/.runtimewhen they are missing (it asks first), checks the inputs and the free space (~50 GB while preparing), then extracts, patches and translates everything intowork/DOOM Mobile(~22 GB). Technical details: docs/doom/GAME_FILES.md. - Copy
work/DOOM Mobileto the phone'sDownloadfolder (USB cable, File transfer mode) and install the APK (latest release,DOOM-Mobile-v<version>-arm64.apk, or build it yourself, see Building). - Start DOOM Mobile and allow All files access when asked.
The APK bundles Mesa Turnip v27 (an adrenotools build of Mesa main for Adreno 6xx/7xx) and uses it by default; it falls back to the phone's own driver when Turnip does not load or finds no supported GPU. On Adreno 750 Turnip v27 is as fast as the Qualcomm driver or slightly faster.
Automatic downloads. When the phone is online, the app reads drivers/manifest.json from
this repository in the background and downloads the driver packages listed there that it does not have yet (Turnip
builds for other Adreno generations: A710/A720/A722, A8xx / Snapdragon 8 Elite, A740 on newer One UI firmware). Every
package is checked against the SHA-256 in the manifest. A package whose auto pattern matches the phone's GPU
(/sys/class/kgsl/kgsl-3d0/gpu_model, e.g. Adreno720v1) becomes the default from the next launch, unless you picked a
driver yourself. Offline nothing is downloaded and the bundled Turnip is used.
Your own driver. Copy an adrenotools driver package into Download/DOOM Mobile/drivers/ on the phone, in either
form:
Download/DOOM Mobile/drivers/
my-turnip.zip <- the package zip as released (meta.json + the driver .so), unpacked on the next launch
my-turnip/ <- or the unpacked folder
meta.json
libvulkan_freedreno.so
Restart the game, open the gear dialog, pick it under Vulkan driver and restart again. System selects the phone's
own driver. Compatible packages: adrenotools / Turnip releases such as
Banners-Turnip (use the plain Android builds, not the
-Linux / -Wayland ones). TU_DEBUG (Turnip's debug options, e.g. sysmem) can be set in
Download/DOOM Mobile/dm/env. To offer a driver to everyone, add an entry (name, url, sha256, optional auto regex)
to drivers/manifest.json.
Untested on real hardware yet. These phones use their own Vulkan driver; the engine checks the device's features and,
instead of aborting, falls back where the game's Switch shaders need something the GPU lacks: no geometry shaders
(the game's culling shaders are skipped), no D24 depth (D32 is used), no format-less storage image writes, no
shaderImageGatherExtended, no GPU timestamps. BC textures are decoded on the CPU when the GPU cannot sample them.
Experimental third-party drivers exist and can be added as packages (see above): Mesa PanVK for Mali on stock kernels
(e.g. panvk-kbase-android) and RADV for Xclipse (radv-xclipse); there is none for PowerVR. Expect lower performance
than on Snapdragon 8 Gen 2/3. Reports (device, GPU, driver, log) are very welcome.
| Path | What |
|---|---|
dm/ |
The host (from d2r-mobile): loader, HLE (dm/host), NVN recorder and Vulkan engine (dm/gfx), Android app (dm/android), offline rewriter (dm/tools/patch_nso.py) and its verifiers (dm/verify). DOOM code is behind DM_GAME_DOOM. |
setup.sh, setup.bat, build.bat |
Game file preparation (tools/setup_doom.py) and APK build entry points |
tools/ |
DOOM tooling: game file extraction, shader jobs, APK build, device test and analysis scripts |
third_party/libadrenotools |
git submodule (BSD-2-Clause) |
docs/doom/ |
Port documentation: state, recon, switches, game files, derived information |
docs/research/ |
Analysis notes behind individual fixes |
docs/THIRD_PARTY.md, docs/DEPENDENCIES.md, docs/DERIVED.md, docs/upstream/ |
Attribution: code ported for DOOM, the third-party code and D2R-derived records inherited from d2r-mobile, and d2r-mobile's acknowledgements |
DOOM Mobile stands on the work of others — thank you:
- d2r-mobile by jhaizhou (MIT) — the base of this port: native NSO loader and rewriter, HLE host, NVN → Vulkan engine, shader translation chain and Android app. Its Android app and Vulkan engine came from community contributors; see its acknowledgements.
- nxnative by seedds (MIT) — threads and SVCs, SDK 6.x services, audio renderer, NVN entry points, timestamp units, patcher and translator pieces.
- nx2android / nx2apk (MIT) — window acquire-sync fix (1c6177d), Android haptics, ADPF, gamepad code.
- BOTWRecompAndroid and LASRecompAndroid by mamcjr, and LASRecomp by Peiikai (MIT) — the Turnip / adrenotools driver loading approach, chunked submit and sync-lag ideas, UBWC / format-list and Turnip notes.
- libadrenotools by Billy Laws (BSD-2-Clause).
- Ryujinx shader translator (Ryujinx Team and Contributors, MIT), vendored by d2r-mobile in
dm/third_party/ryujinx. - AMD FidelityFX FSR 1 RCAS (MIT).
- zlib-ng (zlib license) — optional fast inflate for the game's resource containers.
- Mesa Turnip (MIT) — the default Vulkan driver, bundled in the APK as the adrenotools build
by The412Banner (Mesa main). Not stored in this repository:
tools/fetch_turnip.pydownloads it at build time with a pinned SHA-256. - Khronos Vulkan validation layers (Apache-2.0) — used for debugging, not redistributed.
Details per file: docs/THIRD_PARTY.md.
DOOM © id Software LLC, a ZeniMax Media company. DOOM, id, id Software and id Tech are trademarks of ZeniMax Media Inc.; the Switch version was developed with Panic Button. Nintendo Switch and NVN are trademarks of Nintendo. This is an unofficial, non-commercial fan project with no affiliation to any of them. Play it with a copy you own.
MIT — see LICENSE. The d2r-mobile copyright notice is kept; third-party components keep their own licenses.
DOOM Mobile — нативный порт DOOM (2016) для Nintendo Switch на Android. Оригинальный AArch64-код игры исполняется прямо на процессоре телефона (без эмулятора и JIT); небольшой хост подменяет системные сервисы Switch, а графический API NVN воспроизводится через Vulkan. Основа — проект d2r-mobile (MIT).
- Игры в репозитории нет. Нужна своя копия DOOM для Switch (база + обновление v262144) и свои ключи консоли. Установка по шагам: docs/INSTALL.ru.md. Технические подробности подготовки файлов — docs/doom/GAME_FILES.md (англ.).
- Проверено на Adreno 750 (Snapdragon 8 Gen 3, Xiaomi 14 Ultra) и Adreno 740 (Snapdragon 8 Gen 2); другие GPU не проверялись. Драйвер выбирается по GPU: Adreno 6xx/7xx — встроенный Turnip (Mesa), другие Adreno — свой пакет Turnip, Mali/PowerVR/Xclipse — системный драйвер с обходами в движке; если драйвер не запустился, игра переходит на системный и сообщает об этом. Производительность (1600×720): 45–60 fps на большей части кампании, в самых тяжёлых зонах ~35–50 fps на 8 Gen 3 и ~33–40 на 8 Gen 2 (замерено на прогретом, троттлящем телефоне); оптимизация продолжается. На телефонах с 8–12 ГБ памяти перед игрой лучше закрыть фоновые приложения: своп сильно замедляет загрузки.
- Вывод по умолчанию широкий 1600×720 (Hor+: шире обзор по бокам, без растяжения); классические 1280×720 (16:9) с полосами — галочкой «Широкий экран» в настройках (со следующего запуска, на ~25 % легче для GPU).
- Экранный геймпад с обзором «как мышью», геймпады, гироскоп, aim assist, вибрация, русский язык (язык игры берётся из системы или задаётся в настройках), масштаб 3D-разрешения и резкость RCAS.
- Шестерёнка вверху экрана открывает настройки порта (на языке системы, 13 языков; у каждой опции указано, «сразу» или «со следующего запуска»): динамическое разрешение (тот же переключатель, что «Видео → Динамическое разрешение» в игре), лимит FPS 30/60/90/120, драйвер Vulkan, язык игры, сила помощи в прицеливании, вибрация (по умолчанию выключена), счётчик FPS, разрешение 3D, резкость RCAS, чувствительность обзора и компенсация мёртвой зоны стика (см. таблицу «Port settings» выше).
- Известные ограничения: GPU-куллинг треугольников игры выключен (на нашем пути он терял видимые треугольники), динамическое разрешение выключено по умолчанию, поддерживается только обновление v262144, мультиплеер убран, сетевые сервисы отвечают как у консоли без сети.
- Подготовка файлов игры: положите базу, обновление (NSP / NSZ / XCI / XCZ) и
prod.keysвput-game-files-here/и дважды щёлкнитеsetup.bat(Linux / macOS:bash setup.sh); проверка без изменений —setup check. Python, его пакеты и .NET 10 SDK установка при необходимости ставит сама вtools/.runtime(спросив разрешения); нужно ~50 ГБ свободного места на время подготовки. Готовый APK — в Releases. - Сборка:
cmake -S dm/android -B work/build-android … -DDM_GAME=doom, затемbuild.bat/tools/build_apk.ps1(см. «Building»).
Подробности о состоянии порта, переключателях и истории исправлений — в docs/doom/ и docs/research/.






