Android, GLES and Sigma Touch
September 8, 2026 ยท View on GitHub
The Android platform, GLES renderer and Sigma Touch adapter originate in emileb's Android branch and GLES shader variants branch. Credit for this port belongs to emileb. openQ4 adapts his implementation to the current engine, renderer API, multiplayer module and package checks.
Supported build shape
Android targets arm64-v8a, Android API 24 or later, SDL3 and OpenGL ES 3.0.
The native application is libquake4.so. The renderer is
librenderer-gles_arm64.so; the companion openQ4-game repository supplies
libgame-sp_arm64.so and libgame-mp_arm64.so. Both modes use baseoq4/.
Android has no dedicated-server target. Desktop defaults remain unchanged.
Meson is the engine's build entry point on Android as on desktop. The port's older standalone engine CMake file is superseded by the current Meson source lists, generated version/savegame headers and renderer/game export maps. The engine embeds BSE and each game mode keeps its own idlib archive.
The standalone Android application packages these native outputs using Gradle and SDLActivity. It supports ordinary SDL gamepad, keyboard, mouse and menu input; a full touch gameplay overlay uses the optional compatible Sigma Touch host. Device gameplay remains a separate validation step.
Toolchain and dependencies
Use the android-gles branch in both openQ4 and its sibling openQ4-game
checkout. This integration pins the companion to
f9bf8a692de539b9d149cc7b2c47759dbb1ddd62; checking out that commit directly is
also supported. A companion checkout from an older main revision carries
incompatible engine-interface headers. Publish the companion branch before
pushing the engine branch so remote CI can fetch the pinned commit.
Use the Android NDK, Python 3,
Meson 1.6 or newer, Ninja and CMake. NDK r27d is the initial cross-build baseline.
The cross-file generator follows Android's
other build systems guidance:
it invokes Clang directly with the target/API instead of Windows .cmd wrappers.
All native libraries must use the same NDK, ABI, API and shared C++ runtime.
Obtain SDL3 3.4.10 sources (the repository's pinned subproject) and OpenAL Soft 1.24.3 sources separately. SDL is zlib licensed; OpenAL Soft is LGPL licensed. These are the existing engine dependencies, built for the target. Preserve their license notices when distributing the libraries, and satisfy OpenAL Soft's source/relinking requirements. See SDL and OpenAL Soft. The dependency helper also stages the notices for the shared NDK C++ runtime and OpenAL's bundled fmt implementation.
The helper uses each dependency's own CMake build and installs into one prefix; it neither replaces the engine's Meson build nor downloads sources implicitly. From the repository root on Windows, for example:
python tools/build/prepare_android_deps.py --ndk E:/_SOURCE/_CODE/android-ndk-r27d --sdl-source subprojects/SDL3-3.4.10 --openal-source E:/_SOURCE/_CODE/openal-soft-1.24.3 --prefix .tmp/android-build/deps --build-root .tmp/android-build/dependency-builds-1243
python tools/build/android_cross.py --ndk E:/_SOURCE/_CODE/android-ndk-r27d --api 24 --out .tmp/android-build/arm64.ini
powershell -ExecutionPolicy Bypass -File tools/build/meson_setup.ps1 setup builddir/android-arm64 --cross-file .tmp/android-build/arm64.ini -Dandroid_deps_root=E:/Repositories/openQ4/.tmp/android-build/deps -Dbuildtype=release
powershell -ExecutionPolicy Bypass -File tools/build/meson_setup.ps1 compile -C builddir/android-arm64 -j 8
powershell -ExecutionPolicy Bypass -File tools/build/meson_setup.ps1 install -C builddir/android-arm64 --no-rebuild --skip-subprojects
Adjust absolute paths for your checkout. On Linux/macOS, run the same Python
helpers and use bash tools/build/meson_setup.sh setup, compile and install
with the corresponding arguments above. The wrapper refreshes the companion
source stage when engine interfaces change; use it for subsequent rebuilds too.
Use a separate build directory so desktop settings and staged binaries remain
available. Android game-header staging has its own directory under .tmp/.
The dependency prefix must contain include/SDL3, include/AL,
lib/libSDL3.so, lib/libopenal.so and lib/libc++_shared.so.
The helper enables flexible 16 KiB page sizes for dependency builds; the Meson
cross file requests 16 KiB ELF segment alignment for engine and modules.
Packaging
Installation goes to .install/android/arm64-v8a/: native modules in lib/,
generated packs and mod.json in baseoq4/. Copy dependency runtime libraries
from the prefix alongside the native modules in the host's jniLibs/arm64-v8a/.
Use a host that exposes an extracted native library directory for runtime module
loading. Keep the application's SDL Java sources and native SDL library from the
same SDL release.
Meson also installs android-build.json with the ABI, actual native minimum API
and SDL version. The standalone Gradle host requires this file, uses its API for
the APK's minimum SDK and rejects a mismatched SDL source tree. APK version names
follow the staged mod metadata; see the standalone guide for custom version-code
numbering when publishing several builds of one engine version.
Package both generated packs and the matching mod.json. The engine checks
their checksums and required version. Do not reuse stale metadata or disable
checks to load a mismatched package. This integration retains the normal full
pack contents; emileb's reduced CMake-only pak1 recipe is not applied because the
current renderer and content can evolve independently.
Players must provide their own installed Quake 4 base PK4 assets. Retail assets
are not included in a build or an APK. The host must provide filesystem paths
that allow the engine to read those assets and write its save/configuration data.
Automated MP launches must explicitly pass +set ui_autoJoin 1; interactive
launches use +set ui_autoJoin 0.
Optional Sigma Touch host adapter
The default Android build uses SDL and has no Sigma Touch dependency. For a
legally compatible external host, set -Dsigmatouch_root=<Clibs_OpenTouch> and
-Dsigmatouch_controls_root=<touchcontrols-include-root>, and supply the target
touchcontrols and saffal libraries under android_deps_root/lib. This enables
OPENQ4_SIGMATOUCH and builds emileb's portable API and touch-layout adapters
without injecting the engine PCH into the host sources.
This external host also requires its compatible SDL3 callback extensions
(SDL_beloko_extra.h and the corresponding linked exports). Ordinary SDL3
dependency builds support the standalone Activity; they do not supply those
host-specific callbacks. Keep host headers, native SDL and touch libraries from
one compatible integration. The touch editor's labels are resolved after engine
initialization, since the host constructs its controls before starting openQ4.
External host dependencies are not included or licensed by this repository. The examined MobileTouchControls license grants GPLv2 without an "or later" clause, and the examined Clibs_OpenTouch tree has no top-level license grant. Those versions cannot be assumed compatible with openQ4's GPLv3 licensing. Distribution of a linked Sigma Touch build requires an appropriate compatible license grant for those dependencies. The adapter option is not evidence that such a grant exists, and does not enable or remove host validation checks.
Desktop GLES development
On Linux with GLES/EGL development libraries, enable
-Dbuild_renderer_gles=enabled and launch with +set r_renderApi gles.
Windows and macOS may supply an ANGLE SDK through -Dgles_root=<prefix> with
link libraries under lib/ and runtime libraries available to the loader.
Dependencies and renderer modules must have the same architecture.
The original prepare_macos_angle.sh helper remains a local diagnostic tool.
It extracts ANGLE from an installed Chrome; those binaries are not a
redistributable SDK. A GLES module using that implicit local staging directory
is never installed. Explicitly supplied ANGLE builds require their own license
notices and deployment; desktop GLES remains opt-in.
For runtime checks use windowed desktop launches and the engine's screenshot
command. Enter a map before claiming gameplay validation. Android cross-link
success does not verify the app lifecycle, device driver, touch host or gameplay.
The local push/commit validation profiles require a C++ compiler and JDK 17 or
21 (javac/java on PATH, or JAVA_HOME). Their Android host regression runs
the actual Activity against temporary filesystem fixtures without a device.