BeetleRecomp

BeetleRecomp is a native PC port of Beetle Adventure Racing! built by static recompilation with features like internal-resolution scaling and high-FPS interpolation.

README

BeetleRecomp

Apple Silicon preparation and remaining native qualification are tracked in the macOS review. A fully qualified M1 build is not yet available.

A work-in-progress native PC port of Beetle Adventure Racing! (N64, USA) built by static recompilation with the N64Recomp toolchain — the same approach behind Zelda 64: Recompiled.

Integration status (2026-10-06): Linux build passes; Windows/game verification remains. Daniel Gomes Vieira's frontend, saves/rumble, multiplayer and renderer improvements are integrated with corrections. Read the fork review for verification evidence and the two remaining fidelity/enhancement decisions. The historical baseline status below is not a test of this change.

Controller restoration source checkpoint: the frontend Controls tab now restores BAR gamepad defaults, Auto-configure and reusable templates with persistent per-device mappings. Automated behavior tests and production compilation pass; a complete application rebuild and hands-on menu check remain pending. See controller support.

Historical baseline (2026-07-01): playable. Boots through the intros and menus into races and renders at 60 fps, with keyboard + gamepad input and audio working. Ships an in-app launcher / settings / cheats / pause menu (RmlUi over RT64), internal-resolution scaling (defaults to display-native), MSAA + a VI "divot" seam filter, and high-FPS interpolation (phase 1). A handful of polish items remain — see docs/TODO.md for the roadmap and docs/STATUS.md to resume.

No game data is included. You must supply your own legally-dumped USA ROM (SHA-1 e5ab4d226c08d22f68a2edcc48870203e67454b8). No ROM, assets, or other copyrighted material may ever be committed to this repo.

What this is

Static recompilation translates the N64's MIPS machine code into C automatically, then links it against a modern runtime (CPU via librecomp, graphics via RT64, OS/audio/input via ultramodern). It is not a manual rewrite and does not require a finished decompilation.

This port is a sibling to the BeetleDecomp decompilation. The decomp is not a prerequisite for the recomp, but it is the source of the symbol-rich ELF and the module/relocation metadata the recompiler consumes — which is what makes this port tractable.

Relationship to the decomp

This repo vendors the BeetleDecomp project as a submodule at lib/bar-decomp. Two things are worth knowing up front:

The recomp does not compile the decomp's C. Static recompilation translates the original ROM's MIPS machine code into C automatically; the decomp's hand-written C is never built into the port. What the port takes from the decomp is:

From the decompWhat for
The symbol-rich ELF that rebuilds the ROM byte-for-byteInput to N64Recomp (built in WSL, never committed)
Headers + symbol tablesReadable names + typed interfaces for generated code and patches
Segmentation / module + reloc layoutOverlay handling for BAR's ~130 relocatable modules

Because the decomp is byte-matching, its matching progress doesn't change the port — recompiling a function yields identical output whether it started as hand-written C or raw asm. What flows downstream from decomp work is better names and types (readability of generated code and patches) and the module layout that makes the port tractable.

Changes never go in the decomp — keep it a faithful mirror of the original. Modifications live in two recomp-owned layers:

  • patches/ — C cross-compiled to MIPS that overrides (RECOMP_PATCH) or hooks (RECOMP_HOOK) game functions by name. This is the game-logic layer: bug fixes, widescreen, new features. Patches link before the recompiled output, so they win.
  • src/ — the native C++ host: rendering (RT64), input, audio, saves, config, and the in-app UI.

See BUILDING.md for how the ELF is produced and how to pull decomp updates.

Technical profile

The properties that made BAR a good recomp candidate, and which shape the runtime:

AspectDetail
Graphics microcodeStock gspF3DEX2_fifo (decomp gfx_ucode: f3dex2) — not a custom Paradigm ucode. RT64 supports F3DEX2 directly.
AudioStandard libultra (alAudioFrame/alSeqFileNew/ALSndPlayer) wrapped in Paradigm's "UV" middleware.
SavesController Pak only (osPfs*); no EEPROM/SRAM/Flash. The port emulates a Controller Pak.
Memory4 MB; no Expansion Pak, no TLB-mapped code (flat KSEG0).
Entry point0x80000400 (ROM header offset 0x8 == splat entry segment vram).
Module layoutThe ~130 relocatable code modules (ai, battle, race, …, uv*_rom) were the crux of the port; the uv module overlay bridge (src/main/overlay_bridge.cpp) registers them at load.

The toolchain license analysis and research sources are in THIRD_PARTY_NOTICES.md.

How it fits together

your ROM ─┐
          ├─► BeetleDecomp (WSL) ──► symbol-rich ELF ──► N64Recomp ──► RecompiledFuncs/*.c ─┐
recomp.ld ┘   (per-module layout)                       (BeetleRecomp.toml)                 ├─► CMake ─► BeetleRecomp(.exe)
                                                                                            │
 patches/*.c ─► clang -target mips ─► patches.elf ─► N64Recomp (patches.toml) ─► RecompiledPatches/*.c ┘
                                                            │
            runtime: librecomp + ultramodern + RT64 ───────┘

Repository layout

BeetleRecomp/
├── BeetleRecomp.toml      # main N64Recomp config (entrypoint 0x80000400, ELF, overlays)
├── patches.toml           # config for the C patches (MIPS override/hook layer)
├── overlays.us.txt        # relocatable module/overlay section list
├── CMakeLists.txt         # host-app build (clang-cl + Ninja)
├── COPYING                # AGPL-3.0 (inherited from the decomp)
├── THIRD_PARTY_NOTICES.md # dependency licenses + research sources
├── BUILDING.md            # full build instructions (Windows + Linux/macOS)
├── docs/                  # STATUS.md (resume guide), TODO.md (roadmap), design notes
├── src/
│   ├── main/              # native host: RT64 render context, input, audio, overlay bridge, config
│   ├── game/              # game-facing config schema (graphics.json)
│   └── ui/                # in-app RmlUi launcher / settings / cheats / pause menu + renderer
├── patches/               # C compiled to MIPS that overrides/hooks game functions
├── include/               # port headers
├── rsp/                   # RSP microcode glue
├── scripts/               # setup / fetch-elf / gen-overlays / fix-recompiled helpers
├── assets/  icons/        # bundled app assets
├── elf/  syms/            # decomp ELF + patch symbol TOMLs land here (git-ignored)
└── lib/                   # git submodules:
    ├── bar-decomp                 # BeetleDecomp — symbols, headers, module/reloc layout (source ref)
    ├── N64Recomp                  # the static recompiler (MIPS → C)
    ├── N64ModernRuntime           # librecomp (CPU) + ultramodern (OS/audio/input)   [bryankruman fork]
    ├── rt64                       # RT64 renderer (D3D12 / Vulkan / Metal)            [bryankruman fork]
    ├── RmlUi                      # HTML/CSS UI toolkit for the in-app menus
    ├── lunasvg                    # SVG rasterizer (RmlUi dependency)
    └── freetype-windows-binaries  # prebuilt Freetype for RmlUi text (Windows)

Quickstart

Full details and prerequisites: BUILDING.md.

# 1. Fetch dependencies and build the recompiler (N64Recomp + RSPRecomp).
scripts/setup.sh                  # or scripts/setup.ps1 on Windows PowerShell

# 2. Build the decomp ELF (in WSL), then copy it in.
#    (WSL) cd ~/projects/bar-decomp && source .venv/bin/activate && make recomp
scripts/fetch-elf.sh              # or scripts/fetch-elf.ps1

# 3. Verify all 29 original identities, then recompile the game to C.
python3 scripts/generate-original-bindings.py resolve \
  --elf elf/recomp.elf --policy config/original-functions.us.json \
  --policy-sha256 a785fc8a8552d22e6cd39403535b247af340b0d6287d60082d7483caefb10a11 \
  --base-config BeetleRecomp.toml --output-toml elf/BeetleRecomp.original-bound.toml
./N64Recomp elf/BeetleRecomp.original-bound.toml  # emits RecompiledFuncs/*.c
scripts/fix-recompiled.sh         # REQUIRED codegen fixup — re-run after every regeneration

# 4. Configure + build the port (clang-cl on Windows, clang on Linux/macOS).
cmake -S . -B build-cmake -G Ninja -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_BUILD_TYPE=Release
cmake --build build-cmake -j

The checked-in policy contains only names, addresses, positive function extents and hashes. The resolver verifies the exact ELF instructions before writing the private ignored binding file. A changed instruction, ambiguous provider, tracked output path or failed ignore check stops generation. For a fresh resolution, retire only an existing ignored elf/BeetleRecomp.original-bound.toml first; the resolver never overwrites it. Keep this file, ELFs and generated game code private.

Status & roadmap

The bring-up milestones — the per-module recomp ELF, overlay wiring, first boot, F3DEX2 rendering, input, audio, and Controller Pak saves — are done, and the game is playable. Current work is polish and features:

  • Rendering — internal-resolution scaling (defaults to display-native), MSAA + a VI "divot" seam filter, and high-FPS interpolation (phase 1 live; throughput/artifact phases pending).
  • Known issues — skippable legal/logo screens, a one-frame menu-transition flash, choppy track-map preview, audio latency-vs-clip tuning.
  • Features — controller rebind UI, mod-manager UI, an app icon, and more settings surfaced in the in-app menu.

The live checklist is docs/TODO.md; per-item status and resume detail is in docs/STATUS.md.

License

AGPL-3.0, inherited from the BeetleDecomp data this port derives from. See THIRD_PARTY_NOTICES.md for the dependency-license analysis and why AGPL is the correct umbrella. Vendored dependencies in lib/ retain their own licenses. Distribute no game assets.

Credits

  • SynaMax / synamaxmusic and LLONSIT — original bar-decomp / RE work this builds on.
  • Wiseguy and contributors — N64Recomp, N64ModernRuntime, Zelda 64: Recompiled.
  • RT64 contributors — the renderer.
  • RmlUi and lunasvg — the in-app menu toolkit and SVG rasterizer.