⚠️ You must supply your own ROM
This release contains no game assets or code from the original cartridge. It ships
only the recompiled executable. To play, you must obtain a legal copy of
Automobili Lamborghini (USA).z64 (the North American release is the only one
supported) and place it next to the executable before launching. See BUILDING.md
for the full instructions; in brief:
- Extract the archive for your platform into its own folder.
- Drop
Automobili Lamborghini (USA).z64into that folder. - Launch the binary.
Game saves go alongside the ROM (or under %LOCALAPPDATA%\LamborghiniRecomp on
Windows / ~/.config/LamborghiniRecomp elsewhere — see README.md).
What's working
This release's headline is portable mode + a revamped settings UI: drop the
binary into a folder (or USB stick), place a portable.txt next to it, and your
settings, Controller Pak saves, logs, and crash dumps stay in that folder
instead of %LOCALAPPDATA% / XDG. The new shared-sidebar settings layout puts
chase-camera distance / height / FOV and your player name where you can reach
them without editing graphics.json by hand, and the controller overlay now
opens and navigates from the device that opened it (#210 — the shoulder-tab
follow-up). The settings overview now also surfaces a Driver Name page.
Three more big additions: the first Android (ARM64) release (Qualcomm
Adreno + Mesa Turnip when needed; Mali explicitly out of scope), import of
common Controller Pak save formats (raw MPK, Mupen64Plus-Next SRM, four-port
MPK, DexDrive N64), and deterministic input-replay + a headless Track Lab
v0 for reviewing stock PVS tables and applying guarded runtime patches.
There's still glitches so please report issues you find.
Closed since v0.6.2:
Settings UI & UX
- #199 / PR #199 — Settings UI revamped around a shared sidebar + content-pane layout; the Controls Mapper sits in the sidebar without competing back controls; controller directional navigation reaches submenu content; Resume Game / Exit to Desktop are back on the overview; per-circuit visibility toggles react to controller activation. Centralised settings option tables and a typed snapshot-toggle state.
- #197 / PR #198 — Camera distance / height / FOV and the player-one name are now reachable from the Enhancements options page; a new Driver Name page (plus launcher display and Game menu entry) edits
player.json. Defaults are preserved when keys are absent ingraphics.json. - #210 / PR #211 — The settings overlay's menu actions (accept, back, apply, toggle, tab L/R) now resolve to the pressing device's controller profile, so a hot-plugged pad that opens the overlay can also switch tabs with the shoulders; a negative profile index no longer reaches
get_input_binding(patch 0017, docs/recompfrontend.md). - #174 / PR #174 — Graphics menu persistence preserves hand-edited and forward-compatible
graphics.jsonkeys with merged runtime deltas; restart-only API selections are kept out of RT64 live updates; the Win32 menu's UTF-16, frame invalidation, and command lookups are modernised; texture / file access is serialised and runtime persistence coalesces off the UI thread; Linux thread linkage added. - #163 / PR #164 — Note: the Alt+F4 shutdown-race fix shipped as v0.6.2; mentioned here because the underlying force-stub audit that enabled it was extended in this cycle.
Portable mode & new platforms
- #190 / PR #194 — Portable mode now anchors to the executable directory (not the launch working directory, which silently broke under shortcuts, Steam, drag-drop, and CLI runs from another folder). Triggers: empty
portable.txtnext to the exe,portable.txtin the launch directory, the--portableCLI flag, orLAMBO_PORTABLE=1. A startup log line answers "where are my saves?".tests/test_portable_paths.cpp(wired into CMake/CTest) covers exe-marker vs CWD-marker, default-off, forced flag, env on/off, and source strings. - PR #193 — First Android (ARM64) release. The launcher imports and validates the USA ROM, keeps assets / saves / logs / imported GPU drivers in app-private storage, and provides touch controls alongside SDL gamepad and keyboard. The app-local Vulkan loader supports Qualcomm Adreno devices using an AdrenoTools-compatible Mesa Turnip driver when the system driver lacks RT64's required features; Mali and other non-Adreno GPUs are explicitly out of scope. The release workflow builds, signs, verifies, and attaches the APK beside the Windows and Linux archives when Android signing is configured; without keystore secrets the Android job skips the APK path and the release still publishes the desktop archives.
Stability / no_lod / audio / rendering
- PR #213 — Two integration-build regressions repaired. Linux:
recompuino longer fails to compilerecompui/src/renderer/rt64_render_context.cppbecause thePLUME_SDL_VULKAN_ENABLEDandRT64_SDL_WINDOW_VULKANdefinitions (which makeplume::RenderWindow = SDL_Window*on Linux) are now attached to therecompuitarget viatarget_compile_definitions—rt64'sadd_compile_definitionsis directory-scoped and never reached the recompui sources, so the assignment at line 229 (appCore.window = window_handle) only compiled because the port had set both definitions onlamborghini_modernexplicitly; the definitions now reach the right target on their own. Windows: the pre-patch reset now runsgit clean -fdalongsidegit checkout -- .in all four patched submodules (N64ModernRuntime, rt64, rt64/src/contrib/plume, RecompFrontend), so patch-created untracked files likesrc/render/rt64_backdrop_projection.hfrom patch 0011 no longer survive into the next build and break the apply withalready exists in working directory. No patch files, generated files, submodule pins, or runtime behavior changed. - PR #214 — Patch
0008(zero-translation skybox heuristic) deleted and patch0011re-authored as additive-only; the explicit backdrop path in0011is now the single source of truth for FOV-independent backdrop coverage.0009remains the owner ofG_EX_ORIGIN_WIDEand0011ofG_EX_ASPECT_BACKDROP+ world-matched horizontal projection + independent vertical coverage; build, inventory, source-comment, and doc references all updated. No runtime behavior change vs the previous end-state — just no longer two redundant mechanisms in the apply pipeline. - #212 / PR #212 — Skybox replaced the linear widescreen strip with an angular cylindrical panorama projected to bearings — a 180° camera turn now traverses half the sky ring while coverage envelope and edge caps stay intact. The menu-to-race transition also defers state-7 asset loading while the game's outstanding graphics-task counter is nonzero (prevents RT64 consuming menu display lists after their texture memory has been reused for race assets) — fixes an intermittent RT64 crash during menu-to-race loading. Sky replay completed 600/600 input frames; menu-to-race replay completed 1272/1272 frames and reached race state 8. (docs/sky-panorama.md).
- #181 / PR #182 — Circuit 6 full-track visibility no longer draws a wall across the upper road: the measured circuit-6 occluded segment stays out of synthesised full-track PVS extras only for camera segment 2; exception data moved to a dedicated implementation file; row construction uses spans and a renderability adapter. A 320×240 software-renderer capture reached race state with no
0x802E7BE0wall display-list reference. (docs/no_lod_audit.md). - #178 / PR #179 — Audio output recovers from transient SDL device-loss and stopped output devices instead of staying silent until relaunch. SDL device discovery / status polling / teardown / reopen run from the main-thread
lambo::audio::pump(); the submission callback exits early when no live sink is available; retry cooldowns apply only to failed attempts and clear after a successful open. A 700-VI headless boot reached music state 6 and emitted non-silent PCM. - PR #203 — Boot-time garbled-graphics regression suppressed (RT64 presentation restored before first frame).
- #200 follow-up / PR #202 — Options overlay toggle fixed; settings overview repaired (Resume / Exit actions back; copy trimmed).
- #201 / PR #204 — RT64 presentation + controller startup restored after the settings rework.
- #195 / PR #205 — Car identities now stay stable across laps under interpolation (no more mid-race car-swap flashes).
- PR #196 — Car-part identity preserved across camera changes (no model LOD flicker on view switches).
- #8 / PR #196 — Camera-cut detector (~20° threshold) suppresses the non-finite interpolation path that previously caused rare car-part spikes.
- #165 / PR #166 —
no_lodnow zeroes the per-car model distance halfword at0x80098720after both stores and before all readers, so each car's chosen model DL pins to its closest-detail branch underno_lod(). Headless A/B DL walks confirm stock0x801A9E68→ patched0x801A9998(same struct, lower level pinned).LAMBO_NO_LOD=0leaves RDRAM untouched. (docs/no_lod_audit.md, §12 addendum).
Controller Pak / saves
- #176 / PR #177 — The Controller Pak now imports raw MPK, Mupen64Plus-Next SRM, four-port MPK, and DexDrive N64 containers; format detection validates Pak identity data, backs up existing saves, and preserves unrelated container regions during shared writes. A single worker thread owns every disk publication: it coalesces 32-byte write bursts, responds immediately to explicit flush requests, and keeps publishing if newer data arrives during a write. UTF-8 Windows paths, physical same-file detection, blank-Pak initialisation, transient replacement retries, and OS error details supported.
- #170 / PR #192 — Persisted player names now restore before the arcade high-score table is recorded, so the default
TITUSplaceholder no longer sticks. - PR #207 — Dev-warp hotkeys moved off F1 to
Ctrl+Shift+1..6, leaving F-keys free for in-game menus on hot-plugged keyboards.
Developer tooling (now ships in the binary)
- PR #189 — Six deterministic lap fixtures (
scenarios/) lock down harness regression coverage for boot, warp, save-state, replay, telemetry, and headless capture. - #183 / PR #185 — Track Lab v0: headless inspection of stock track snapshots, compilation of sparse visibility-row edits, and guarded runtime patches; documented JSON contract; ROM/circuit/baseline/hash/expected-old-value guards. A companion browser editor can consume the contract independently. Geometry, collision, and arbitrary new-track authoring remain explicitly out of scope.
- PR #184 — The deterministic replay runner records effective controller input on the game's 30 Hz dispatch clock, replays it without wall-clock coupling, and reports machine-readable boot/warp/save-state/replay/telemetry/headless-capture evidence. Opt-in via
LAMBO_INPUT_*variables; omit them to keep the normal input path.
Texture tooling (developer-facing)
- #188 / PR #187 — Generic RT64 texture-pack tooling: runtime dumping, hash-named replacement files, manifest generation with explicit
load_opandtexel_shiftdefaults, loose-directory testing, and.rtzloading — documented without coupling the port to any particular artwork project. The public tree contains no pack-specific repository links, artwork, or release metadata. - PR #172 — Readable-text pack refined toward the original style: small atlas families forward-leaning with extra shear on real italic faces; chrome/gold dimensional treatment restored; white-atlas custom cursor slots reworked as opposing arrows; runtime-captured gold U and L hashes raise the loose pack from 57 to 59 replacements. The refined RTZ remains local per the boundary set in #66.
- PR #167 — Decoupled RT64 texture-pack workflow documented:
texture_pack/texture_dumpin the README, complete author guide, verifiedshift: halfversus grid-alignedshift: nonedistinction. The port consumes native RT64 directories /.rtz, not.o2ror legacy Rice packs.
CI / build / project docs
- #134 / #132 / PR #206 — Project documentation reset around current repository facts:
docs/README.mdis now the landing page; durable knowledge lives indocs/controllers.md,docs/peer-projects.md,docs/architecture.md, andpatches/README.md(per-patch inventory with upstream status).CLAUDE.mdtrimmed to project facts + editing rules + deterministic checks. PR template describes change type instead of gating on approval. - PR #180 — Console output is now opt-in (
--console) on Windows; logging has severity thresholds and per-session files; crash reports have a durable destination. CLI parsing, SDL startup, path resolution, console attachment, lifecycle, and log-performance regressions fixed. - PR #208 — Unit-test discovery repaired; vendored docs excluded from the docs check.
- PR #175 — The dev-warp
carargument now means model cursor 0–23 (the real 24-model cursor at0x800CE7E8); difficulty (Novice/Expert) is a separateLAMBO_WARP_DIFFICULTY=0|1knob.func_8001E01Cremains force-stubbed but its range is covered by the live enlargedfunc_80019D20updater and that status is documented explicitly. - #173 / PR #173 — Track runtime bundle (segment display lists, visibility rows, culling, scenery, draw-list limits, waypoint / progress / segment-link structures) documented; collision-table consumers and complete CPU-car AI semantics remain explicitly unresolved and are labeled as hypotheses.
What's not done yet
This is still pre-1.0 — plenty of force_stub.txt still includes real game primitives
rather than no-ops. The tracker is the canonical "what's next" list.
- #210 follow-ups — keyboard menu actions remain the shared frontend's F15/F16/F17 defaults and the Controls page hides the menu section for keyboard profiles; the port also hardcodes F1 + pad Back/Share to toggle the overlay instead of the configurable Toggle Menu binding. The shared
cont_button_to_keyupstream defect still exists and is a candidate upstream proposal (patches/README.md). - #186 — A pre-existing
lambo_controller_pak_testslogging-link failure surfaced by the Track Lab v0 aggregate build, tracked separately. - #133 — Upstream-project proposals (RT64 / RecompFrontend) intentionally left as-is; upstream projects remain the canonical record.
If you find a crash, please open an issue with lamborghini_crash style notes:
- Output window text (or the
crash-*.txtdump if the native handler caught it) - Commit / build provenance (below)
- Approximate in-game location (title screen / car-select / race lap 2 / etc.)
How to run
Linux
unzip lamborghini-recomp-linux-x64.zip -d lamborghini-recomp
cp "Automobili Lamborghini (USA).z64" lamborghini-recomp/
./lamborghini-recomp/lamborghini_modernRequires libsdl2-2.0-0 and a Vulkan-capable GPU + driver at runtime. Most
desktop distros ship these already.
Windows
Extract lamborghini-recomp-windows-x64.zip anywhere, drop your ROM in the same
folder, and double-click lamborghini_modern.exe. The bundled SDL2.dll,
dxcompiler.dll, and dxil.dll must stay alongside the EXE.
F11 / Alt+Enter toggles fullscreen (and remembers the choice next launch).
Android
If Android signing was configured for this build, lamborghini-recomp-android-arm64.apk
is attached; install, grant storage access, and import your USA ROM. Vulkan on
Qualcomm Adreno uses Mesa Turnip when the system driver lacks the required
features.
Build provenance
- Commit:
<SHORT_SHA>(main, ) - Workflow run: #<RUN_ID> (Build & Release, dispatch from this SHA)
- Toolchain: Linux build on
ubuntu-latestwith gcc / cmake / ninja /
libsdl2-dev/libvulkan-dev. Windows build onwindows-latestwith
MinGW-w64 GCC + Ninja (PowerShell, not MSYS bash) per the project's toolchain
notes. Android target onubuntu-latestwith the Android NDK + Gradle.
If you'd rather build it yourself from source instead of running a pre-built
binary, see BUILDING.md. For graphics settings, see README.md.