Skip to content

Repository files navigation

BMK4

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.

iOS Stub iOS Engine Compile Probe Windows Build License: GPL-3.0

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.


What is this?

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.

Status at a glance

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_homepathDocuments/) ✅ 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.

DXVK's D3D9 frontend on physical iPadOS

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.

The experiment

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

Architecture (chosen path)

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
Loading

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.

The four measured walls

  1. 32-bit layout assumptions — 249 struct-size asserts; fastfile deserialization streams zone data into structs that assume 4-byte pointers. The single largest cost.
  2. Win32 platform layer — ~6,900 LOC of window/input/socket/thread glue; every family has a mapped POSIX/UIKit replacement.
  3. Binary-only x86 DLLs — Miles Sound, Bink Video, Steam. Require AVAudioEngine / AVFoundation / no-op shims.
  4. 73 inline x86 __asm blocks — mechanical C/NEON rewrites.

Repo tour

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)

Quickstart

Run the stub on your iPhone (Mac)

git clone https://github.com/Braxton-Bevis/bmk4
brew install xcodegen
cd kisakcod-ios-port/ios && xcodegen generate && open KisakStub.xcodeproj

Enable automatic signing with your (free) Apple ID, plug in the phone, Run. Details and the no-Mac Sideloadly path: ios/README.md.

Reproduce the engine compile census (Mac)

cmake -B build-ios -DKISAK_PLATFORM=ios -DCMAKE_SYSTEM_NAME=iOS \
      -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=15.0

or just push a change under src/ — the census workflow runs it for you and publishes the per-file error table as an artifact.

Build the renderer library + engine archive (Mac)

# 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 both

Needs cmake/meson/ninja/glslang on PATH (no Homebrew required — see the header of each script for binary-release install one-liners).

Build the original Windows game

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.

Path to a complete working game

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_pmove walks, jumps, lands, and stops on a synthetic world; exact simulator proof plus thumbstick/HUD wiring (journal M14)
  • Real filesystem on iOSFS_InitFilesystem under 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.ff parse 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_Init and the DXVK dummy-resource fix land with the first material wave
  • mp_killhouse direct-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 into mp_killhouse on the iPad, screenshot posted here
  • After first playable — audio (AVAudioEngine behind AIL_*), Bink, menus/UI breadth, full input binds, frame pacing, persistence

Roadmap

  1. DXVK d3d9 as an arm64-apple-ios librarydonelibdxvk_d3d9.a builds with a 5-hunk patch; see build-dxvk-ios.sh.
  2. pthreads threads.cpp → BSD-sockets win_net.cpp → platform layer replacing win_main.cppdone — all census-verified (sys_ios_main.mm is the entry layer).
  3. Renderer runtime bring-updone — D3D9 renders on the iPad (journal M12): native CAMetalLayer WSI, static MoltenVK, Clear+readback+Present all D3D_OK.
  4. Headless engine bootdone — M15 is simulator-green; the unsigned arm64 device app links and packages the same closure.
  5. Current frontier: the 64-bit fastfile wall — load-time 32→64 struct translation gates real game data and the first mp_killhouse frame. Then AVAudioEngine behind the landed AIL_* stub surface.

Credits & legal

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

About

BMK4 (Braxton · Metal · Kisak · 4): a work-in-progress arm64 iOS port of LWSS's GPL-3.0 KisakCOD Call of Duty 4 decompilation. DXVK's D3D9 frontend proven on physical iPadOS. No game assets.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages