ZOYKU火线榜

desm0nt/doom-port技术文档

DOOM Mobile: the Nintendo Switch release of DOOM (2016) running natively on ARM64 Android (Vulkan). Bring your own game files.

多语言回退提示:当前仓库原作者暂未发布本地化文档,已为您无缝切换至官方英文原版(English),排版及代码实例完整保真。
极速安装
git clone https://github.com/desm0nt/doom-port.git

DOOM Mobile

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).

Screenshots

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):

Desert, on-screen controls Fight, on-screen controls

With a gamepad (Bluetooth / USB): the on-screen controls hide themselves and come back when it disconnects.

Mars surface, gamepad Fight with an imp, gamepad
Canyon, gamepad Main menu in Russian, on-screen controls

Port settings (gear button)

The gear at the top of the screen opens the port's own settings, on top of the game's menus:

Port settings dialog

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.

What it is, and what it is not

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.

Current state

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.

Known issues

  • 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.

Building

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 --recursive

Configure 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=doom

Then 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 PowerShell

The 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.

Installing

Full guide: docs/INSTALL.md (English) / docs/INSTALL.ru.md (Russian).

  1. Dump your own copy (base game 0100416004C00000 + update 0100416004C00800 v262144, as NSP / NSZ / XCI / XCZ) and your console's prod.keys — e.g. with nxdumptool and Lockpick_RCM on your Switch.
  2. Put the files into put-game-files-here/ (any names) and double-click setup.bat, or run bash setup.sh on Linux / macOS (explicit files in any order work too; setup check reports what is missing and changes nothing). Setup provides Python, its packages and the .NET 10 SDK in tools/.runtime when they are missing (it asks first), checks the inputs and the free space (~50 GB while preparing), then extracts, patches and translates everything into work/DOOM Mobile (~22 GB). Technical details: docs/doom/GAME_FILES.md.
  3. Copy work/DOOM Mobile to the phone's Download folder (USB cable, File transfer mode) and install the APK (latest release, DOOM-Mobile-v<version>-arm64.apk, or build it yourself, see Building).
  4. Start DOOM Mobile and allow All files access when asked.

Vulkan drivers

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.

Other GPUs (Mali, PowerVR, Xclipse)

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.

Repository layout

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

Credits

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.py downloads 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.

License

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/.

文档镜像归档自 GitHub 官方源路径 · 访问原项目 GitHub
最后同步快照:2026-11-13