BMK4 (Braxton · Metal · Kisak · 4) is a work-in-progress native arm64-apple-ios port of
LWSS's KisakCOD, a from-scratch Call of Duty 4
engine decompilation.
The hero frame is intentionally reserved for output from the real COD4 engine renderer. Swift/Metal shell smokes do not qualify; placeholder assets may be used for the first engine-rendered proof.
This repository tests how far KisakCOD, a GPL-3.0 Win32/x86-32/DirectX 9 reimplementation of the Call of Duty 4 multiplayer engine, can be ported to native iOS.
There is no macOS/Linux/ARM branch to start from. The engine assumes Windows APIs, 32-bit x86 struct layouts, and a D3D9 renderer throughout. The port is documented milestone by milestone, with every compile and launch verified on GitHub Actions macOS runners (Xcode 16.4, iOS 18.5 SDK). The work is driven from a Windows laptop with no local compiler.
This is a research/porting project. It contains no game assets and never will — you must own Call of Duty 4 (2007). It is not affiliated with Activision or Infinity Ward.
| Objective | Status |
|---|---|
iOS app shell: Metal layer, simulator-verified launch, unsigned arm64 .ipa artifact |
✅ complete |
| MetalFX spatial upscaling (50/75% → native), runtime + SDK gated | ✅ in the stub |
Controller support: on-screen GCVirtualController + physical gamepads |
✅ in the stub |
| In-app graphics settings menu (MetalFX, render scale, frame cap) | ✅ in the stub |
Build retarget: cmake -DKISAK_PLATFORM=ios + per-file compile census in CI |
✅ complete |
| Windows→iOS dependency map (every API family → concrete replacement) | ✅ DEPENDENCY_MAP.md |
Filesystem sandboxing (fs_basepath → app bundle, fs_homepath → Documents/) |
✅ landed |
Engine translation units compiling for arm64-apple-ios |
✅ 41/41 census TUs — including the real pmove closure, Com_Init, queued-event, dvar-command, and script-string owners |
| D3D9 header layer absorbed by DXVK native headers on the iOS SDK | ✅ proven |
| DXVK d3d9 renderer runtime on iOS | ✅ LIVE ON DEVICE — native CAMetalLayer WSI + static MoltenVK; CreateDevice D3D_OK, Clear readback bit-exact, Present D3D_OK on iPad Pro (M5). Patch + build script |
| Engine linking / running on device | 🟡 first engine code executes on iOS — math/bit-packing/string TUs linked into the stub, verified in simulator and on iPad Pro (M5) with MetalFX spatial upscaling live at 120 fps |
Headless Com_Init (M15) |
✅ simulator-verified: 72 real dvars; real set/dvarlist, filesystem, net/msg, queued event, and script-string lifecycle; arm64 device app links/packages |
| Real player-movement sandbox | ✅ simulator-proven walk + jump + land + friction on a synthetic flat world; thumbstick/HUD live, physical-iPad feel test pending |
| win32 build unaffected by all of the above | ✅ full engine builds green (Debug + Release) |
The full done/remaining checklist is in Path to a complete working game; the execution order is the ten-slice plan in docs/reviews/roadmap-sol.md.
On 2026-07-11, BMK4 produced what we believe is the first publicly documented frame on a
physical iOS/iPadOS device generated by an application calling DXVK's D3D9 frontend
directly. On an iPad Pro (M5): Direct3DCreate9/CreateDevice succeeded, a cleared render
target was verified by bit-exact GPU readback, and Present returned D3D_OK. This was a
synthetic renderer smoke test, not yet a COD4 game frame. Results are recorded in
PORT_JOURNAL.md milestone M12 and in the CI artifacts.
Prior art: a Command & Conquer: Generals port by Ammaar Reshi demonstrated D3D8 gameplay rendering through DXVK's D3D9-backed implementation on iPhone and iPad by 2026-07-04, with its own iOS DXVK patch. BMK4's setup differs in calling the D3D9 frontend directly from engine source. Our search notes and the prior-art assessment are in RENDERER_INIT_NOTES.md.
The setup: because the GPL-3.0 engine source is available, the engine compiles as a native arm64 iOS application and emits D3D9 calls directly. It runs as one process and does not require Wine, x86 emulation, or JIT compilation. The rendering path is:
engine → DXVK d3d9 → Vulkan → static MoltenVK → Metal → iPad GPU
DXVK d3d9 is cross-compiled for iOS with a
small patch that includes a new
CAMetalLayer WSI backend. DXVK issue
#4886 had ruled out iOS for the
Wine/emulation scenario; compiling from engine source avoids those constraints. Other
D3D9-era games with available source may be able to use the same arrangement, subject to
each game's middleware and platform dependencies.
Eight rounds of a CI compile census — representative engine files compiled against the real iOS SDK after each fix wave, failures recorded verbatim:
| Round | Change | Result |
|---|---|---|
| 1 | raw engine vs iOS SDK | 0/13 compile — six distinct error strata identified |
| 2 | <climits>, random() POSIX clash fix, -fdeclspec, FS sandbox patch |
first iOS platform file passes |
| 3 | all 249 x86-32 layout asserts relaxed via auditable macro | SSE wall (xmmintrin.h) reached |
| 4 | sse2neon vendored | SSE wall gone; d3d9.h resolves via DXVK headers |
| 5 | Win32 gateway-header shims | 8 TUs converge on the single d3d9.h wall |
| 6 | DXVK native headers become the baseline | renderer headers fully absorbed |
| 7 | ODE dependency fixes | zero platform headers left in 10 TUs' error paths |
| 8 | -fdelayed-template-parsing |
bg_pmove.cpp compiles clean for arm64-apple-ios |
The Mac bring-up session (journal M7–M11) swept the census from 2/14 to
23/23, built DXVK's d3d9 module as an arm64-apple-ios static library, and
verified the first linked engine code on an iPad Pro (M5). M15 now tracks
41/41 TUs and simulator-verifies the headless Com_Init closure plus real
bg_pmove walking, jumping, landing, and friction on an asset-free synthetic
floor while preserving the Windows build.
Full blow-by-blow log with exact compiler errors: PORT_JOURNAL.md · Detailed M14 implementation/evidence report: docs/M14_PMOVE_SANDBOX_REPORT.md · Current status & next steps: FRONTIER_REPORT.md
flowchart LR
subgraph Engine ["KisakCOD engine (C++)"]
GAME["game / bgame / script VM"] --> RB["gfx_d3d renderer<br/>(D3D9 calls)"]
end
RB -->|"d3d9.h (proven on iOS SDK)"| DXVK["DXVK d3d9<br/>(native build — next frontier)"]
DXVK --> VK["Vulkan"] --> MVK["MoltenVK"] --> MTL["Metal"]
MTL --> CAML["CAMetalLayer<br/>(the stub app's layer, working today)"]
subgraph iOS ["iOS platform layer"]
FS["fs_homepath → Documents/<br/>fs_basepath → app bundle"]
GC["GCVirtualController / GCController"]
FX["MetalFX spatial upscaler"]
end
The renderer follows the translation strategy (as used by the C&C Generals iOS port): keep the engine's D3D9 calls, translate them at the API boundary. The alternative native-Metal rewrite is scoped in DEPENDENCY_MAP.md §8 as fallback.
- 32-bit layout assumptions — 249 struct-size asserts; fastfile deserialization streams zone data into structs that assume 4-byte pointers. The single largest cost.
- Win32 platform layer — ~6,900 LOC of window/input/socket/thread glue; every family has a mapped POSIX/UIKit replacement.
- Binary-only x86 DLLs — Miles Sound, Bink Video, Steam. Require AVAudioEngine / AVFoundation / no-op shims.
- 73 inline x86
__asmblocks — mechanical C/NEON rewrites.
| Path | What it is |
|---|---|
ios/ |
The iOS app shell: XcodeGen spec + Swift/Metal stub with MetalFX, controller support, graphics settings, staged engine smoke, the live pmove sandbox, and signing runbooks (ios/README.md) |
src/ios/ |
The engine-side iOS platform layer: sandbox paths, platform entry (sys_ios_main.mm), MSVC-CRT/Win32 compat headers, Miles stub |
scripts/platform/ios/ |
KISAK_PLATFORM=ios toolchain flags, DXVK header wiring, build-dxvk-ios.sh (renderer library), build-engine-lib.sh (engine archive), the DXVK iOS patch |
scripts/ios/ |
The compile-census target (files graduate in as the port advances) |
.github/workflows/ |
iOS stub build + simulator-launch proof · engine compile census · Windows regression build |
| PORT_JOURNAL.md | The experiment log — every attempt, exact errors, next hypothesis |
| docs/M14_PMOVE_SANDBOX_REPORT.md | Comprehensive Phase 2 implementation, evidence, limitations, physical-test, and handoff report |
| DEPENDENCY_MAP.md | Every Win32/D3D9/x86 dependency → its iOS replacement, with effort ratings |
| FRONTIER_REPORT.md | Furthest milestone, hard blockers, what a human does next |
| docs/UPSTREAM_README.md | Original KisakCOD readme (Windows build instructions) |
git clone https://github.com/Braxton-Bevis/bmk4
brew install xcodegen
cd kisakcod-ios-port/ios && xcodegen generate && open KisakStub.xcodeprojEnable automatic signing with your (free) Apple ID, plug in the phone, Run. Details and the no-Mac Sideloadly path: ios/README.md.
cmake -B build-ios -DKISAK_PLATFORM=ios -DCMAKE_SYSTEM_NAME=iOS \
-DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=15.0or just push a change under src/ — the census workflow runs it for you and publishes the per-file error table as an artifact.
# DXVK d3d9 as an arm64-apple-ios static library (SDL2-iOS WSI, ~10 min)
./scripts/platform/ios/build-dxvk-ios.sh dxvk-ios-work
# Every census-passing engine TU plus required smoke/pmove subset archives
git clone --depth 1 --branch v2.7.1 --recurse-submodules=include/native/directx \
--shallow-submodules https://github.com/doitsujin/dxvk ../dxvk
./scripts/platform/ios/build-engine-lib.sh ../dxvk/include/native bothNeeds cmake/meson/ninja/glslang on PATH (no Homebrew required — see the header of each script for binary-release install one-liners).
Unchanged from upstream — see docs/UPSTREAM_README.md. All iOS work is #ifdef KISAK_IOS-gated; the win32 build is verified green in CI on every tree that touched engine source.
Everything between today's state and playing Call of Duty 4 on an iPad, in dependency order. Checked items are machine-verified in CI or on device.
- Toolchain + app shell — Metal render loop, settings, controllers, signing, device installs
- Engine compiles for iOS — 41/41 census TUs (pmove closure, real filesystem,
common.cpp, queued events, dvar commands, and script strings) - Renderer runtime — D3D9→DXVK→Vulkan→MoltenVK→Metal live on device (Clear/readback/Present verified pixel-exact, journal M12)
- First engine code executing on device — math/bit-packing/string smoke, exact expected values
- Engine subsystems boot in simulator — real memory/dvar/command cold-start init, behavioral markers (journal M13)
- Player movement sandbox — real
bg_pmovewalks, jumps, lands, and stops on a synthetic world; exact simulator proof plus thumbstick/HUD wiring (journal M14) - Real filesystem on iOS —
FS_InitFilesystemunder an explicit headless policy; engine write/read/delete round trip (Phase 3 Wave 1) - Headless
Com_Init— M15 simulator proof earned: 72 live dvars plus behavioral net/msg, queued event, filesystem,set/dvarlist, and script-string checks - Windows asset oracle — CI-built dump tool; all five boot zones plus
mp_killhouse.ffparse clean on first contact (evidence run stays local, never in CI; sanitized findings in docs/REAL_ZONE_EVIDENCE.md) - Layout-map generation — per-struct 32-bit offset/size tables derived two independent ways (OAT's generator and KisakCOD's own headers under MSVC); zero numeric divergence across 17 structures / 155 members, conformance diff now runs in CI
- Fastfile translation kernel — inflate/staging/32→64 fills proven on synthetic zones against the oracle. The dominant remaining cost.
- Oracle-derived asset waves + renderer integration — only the observed boot/map closure;
R_Initand the DXVK dummy-resource fix land with the first material wave -
mp_killhousedirect-client closure — link and run only the TUs a direct map start reaches; map zone loads, client snapshot, cgame renders - Physical-device proofs, batched — M13/M14 markers plus the real-fastfile load, one Sideloadly sitting
- THE ARTIFACT — game data into
Documents/(never in this repo), direct launch intomp_killhouseon the iPad, screenshot posted here - After first playable — audio (AVAudioEngine behind
AIL_*), Bink, menus/UI breadth, full input binds, frame pacing, persistence
DXVK d3d9 as an arm64-apple-ios library✅ done —libdxvk_d3d9.abuilds with a 5-hunk patch; see build-dxvk-ios.sh.pthreads✅ done — all census-verified (threads.cpp→ BSD-socketswin_net.cpp→ platform layer replacingwin_main.cppsys_ios_main.mmis the entry layer).Renderer runtime bring-up✅ done — D3D9 renders on the iPad (journal M12): native CAMetalLayer WSI, static MoltenVK, Clear+readback+Present all D3D_OK.Headless engine boot✅ done — M15 is simulator-green; the unsigned arm64 device app links and packages the same closure.- Current frontier: the 64-bit fastfile wall — load-time 32→64 struct translation gates real game data and the first
mp_killhouseframe. Then AVAudioEngine behind the landedAIL_*stub surface.
- SwagSoftware/KisakCOD — the extraordinary decompilation this builds on, and everyone credited in its readme.
- doitsujin/dxvk + Joshua-Ashton/mingw-directx-headers — D3D9 translation headers · DLTcollab/sse2neon — SSE→NEON (MIT, vendored in
deps/sse2neon). - License: GPL-3.0 (inherited from upstream). Call of Duty® is a trademark of Activision. This project ships no game assets and requires your own legally obtained copy of COD4 (2007). Not affiliated with or endorsed by Activision.