github alondero/automobililamborghini-recomp v0.7.0
Automobili Lamborghini Recompiled v0.7.0

latest releases: v0.7.2, v0.7.1
4 hours ago

⚠️ 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:

  1. Extract the archive for your platform into its own folder.
  2. Drop Automobili Lamborghini (USA).z64 into that folder.
  3. 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 in graphics.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.json keys 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 #164Note: 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.txt next to the exe, portable.txt in the launch directory, the --portable CLI flag, or LAMBO_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 #193First 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: recompui no longer fails to compile recompui/src/renderer/rt64_render_context.cpp because the PLUME_SDL_VULKAN_ENABLED and RT64_SDL_WINDOW_VULKAN definitions (which make plume::RenderWindow = SDL_Window* on Linux) are now attached to the recompui target via target_compile_definitionsrt64's add_compile_definitions is 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 on lamborghini_modern explicitly; the definitions now reach the right target on their own. Windows: the pre-patch reset now runs git clean -fd alongside git checkout -- . in all four patched submodules (N64ModernRuntime, rt64, rt64/src/contrib/plume, RecompFrontend), so patch-created untracked files like src/render/rt64_backdrop_projection.h from patch 0011 no longer survive into the next build and break the apply with already 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 patch 0011 re-authored as additive-only; the explicit backdrop path in 0011 is now the single source of truth for FOV-independent backdrop coverage. 0009 remains the owner of G_EX_ORIGIN_WIDE and 0011 of G_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 0x802E7BE0 wall 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 #166no_lod now zeroes the per-car model distance halfword at 0x80098720 after both stores and before all readers, so each car's chosen model DL pins to its closest-detail branch under no_lod(). Headless A/B DL walks confirm stock 0x801A9E68 → patched 0x801A9998 (same struct, lower level pinned). LAMBO_NO_LOD=0 leaves 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 TITUS placeholder 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 #185Track 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_op and texel_shift defaults, loose-directory testing, and .rtz loading — 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_dump in the README, complete author guide, verified shift: half versus grid-aligned shift: none distinction. The port consumes native RT64 directories / .rtz, not .o2r or legacy Rice packs.

CI / build / project docs

  • #134 / #132 / PR #206 — Project documentation reset around current repository facts: docs/README.md is now the landing page; durable knowledge lives in docs/controllers.md, docs/peer-projects.md, docs/architecture.md, and patches/README.md (per-patch inventory with upstream status). CLAUDE.md trimmed 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 car argument now means model cursor 0–23 (the real 24-model cursor at 0x800CE7E8); difficulty (Novice/Expert) is a separate LAMBO_WARP_DIFFICULTY=0|1 knob. func_8001E01C remains force-stubbed but its range is covered by the live enlarged func_80019D20 updater 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_key upstream defect still exists and is a candidate upstream proposal (patches/README.md).
  • #186 — A pre-existing lambo_controller_pak_tests logging-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-*.txt dump 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_modern

Requires 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-latest with gcc / cmake / ninja /
    libsdl2-dev / libvulkan-dev. Windows build on windows-latest with
    MinGW-w64 GCC + Ninja (PowerShell, not MSYS bash) per the project's toolchain
    notes. Android target on ubuntu-latest with 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.

Don't miss a new automobililamborghini-recomp release

NewReleases is sending notifications on new releases.