mcla-recomp
MCLA: a fork of mcla-recomp is a native PC port of Midnight Club: Los Angeles Complete Edition that adds performance work and game fixes.
- Type: PC port
- Game: Midnight Club: Los Angeles Complete Edition
- Runs on Windows
- By RenanQueiroz
- Latest release v0.3.2, 2026-10-29
- Source: https://github.com/RenanQueiroz/mcla-recomp
README
MCLA: a fork of mcla-recomp
A fork of holdmysocks/mcla-recomp, the static recompilation of Midnight Club: Los Angeles Complete Edition (Xbox 360, title 545407F8) to native code for Windows, Linux and jailbroken PS5 consoles. On top of upstream's main it adds performance work on both Windows renderers, Direct3D 12 and Vulkan, so that higher resolutions and frame rates hold; a Windows launcher that updates, builds and starts the game; and several game fixes. The changes meant for upstream are offered there as pull requests over time.
This repository contains no game code, assets or keys. You supply your own legally obtained copy; a script extracts what is needed on your machine, and the recompiled code is generated locally and never committed. What you build is for you, not for sharing.
Testing so far
Everything this fork adds was built and measured on Windows only, with an NVIDIA RTX 5080 and a Ryzen 7 9800X3D, on both Direct3D 12 and Vulkan. It has also been run on the Ryzen's integrated AMD Radeon graphics (both APIs, 720p to 4K), where the white or grey flashes on AMD with Direct3D 12 were found and fixed in v0.1.3, but not on a discrete AMD card, on Vega-based Ryzen graphics, on Intel graphics, on Linux or on the PS5 yet. If you try it on other hardware, please report how it went in the fork's issues, whether it works or not.
Status
| Target | State in this fork |
|---|---|
| Windows, Direct3D 12 | Plays: career, races, garage and upgrades, with audio and a controller. 30 to 120 FPS or uncapped, at native resolution (720p), 2× or 3× (4K). |
| Windows, Vulkan | Runs with the same settings, through the same scripted runs as D3D12: the map zoom-out, free roam, a drive and a race. Not yet played through by hand. (Upstream lists it as reaching the title screen.) |
| Linux, Vulkan | Upstream's build plays: free roam holds 30 FPS on an Intel Core Ultra 5 238V laptop (Mesa ANV), tested by one user. The fork's SDK patches apply on top, but have not been built or run there. |
| PS5 (jailbroken) | Upstream's build plays at a steady 30 FPS on a PS5 Pro (firmware 13.42), 20 to 25 in the zoomed-out map, and was installed and played on a PS5 Slim (firmware 12.70). The fork's make_ps5.sh also applies the fork's SDK patches, which have not been built or run on a console. |
On the test machine, with the launcher's settings: at native resolution the game's own thread sets the pace, at about 6.8 ms a frame (about 145 FPS uncapped in free roam). At 3× (4K) a 120 FPS cap holds in free roam and while driving in the city, with 93% of frames within 1 ms of the target on D3D12 and 97% on Vulkan (99% on both standing in the city by day since single-tile rendering). Races at 3× run at a median of 8.1 to 8.5 ms a frame on D3D12 and 9.3 to 9.6 ms on Vulkan in the race benchmark (launcher/dev/scripts/race.pad, uncapped, the release build, two runs each); with the scene in two tiles 9.7 to 10.1 and 10.9 to 11.1 ms, where the runs of 2026-10-15 gave 9.3 and 10.8 (the benchmark's runs spread by up to 8%). Method and per-change figures: patches/README.md and launcher/dev/single-tile-edram-2026-10-16.md.
Which release of the game
Only Midnight Club: Los Angeles Complete Edition, USA/Europe, for Xbox 360 (title id 545407F8), as a disc image (.iso). The fixes in config/ are addresses in that release's executable; another region or revision would need them checked again.
How it works
The game's PowerPC code is translated to C++ ahead of time by the ReXGlue SDK (BSD-3, derived from Xenia), which also provides the Xbox 360 kernel, GPU and audio reimplementation. This repository holds the project manifest, function hints, a small host application, patches to the SDK and the build scripts. The fork adds its own SDK patches to patches/, changes to the host application in src/, and the launcher in launcher/.
Windows
You need Windows 10 or 11 (x86-64) with a Direct3D 12 graphics card, and about 20 GB of disk. The build checks for Git, CMake, Ninja, Python 3, Visual Studio Build Tools 2022 version 17.1 or newer (C++ workload), a Windows SDK newer than 10.0.19041 (Windows SDK 10.0.26100 is installed when it is not there) and the project's own Clang 20, and offers to install what is missing (answer y, or add -InstallTools); the Build Tools ask for administrator rights (-Toolchain mingw needs neither them nor Clang from the LLVM project). It also looks for the Vulkan SDK (winget install KhronosGroup.VulkanSDK, administrator rights too), which only the FSR anti-aliasing option needs on Vulkan: without it FSR is built for Direct3D 12 only, and the build goes on. FSR's runtime is built from the FidelityFX SDK's source, which the first build fetches from GitHub; without the network the game builds without FSR. The launcher also needs the .NET 10 SDK (winget install Microsoft.DotNet.SDK.10).
Without any tools (MCLA-Setup.exe, the setup wizard)
Download MCLA-Setup.exe from the latest release and run it. It installs the launcher for your Windows user (no administrator prompt) in %LOCALAPPDATA%\Programs\MCLA, adds Start menu and desktop shortcuts and opens it. On a PC with no install the launcher starts a setup wizard: it asks for a folder and your disc image (or the extracted game), then downloads checked, pinned build tools (llvm-mingw, CMake, Ninja, MinGit and the prebuilt SDK, so no Visual Studio, Git or Python), clones this fork at the release's tag, translates and builds the game and prepares shaders, and opens the launcher. It needs the internet (or the files downloaded by hand, see If something goes wrong) and about 10 GB; the folder's path can be at most 129 characters, with only plain letters, digits, spaces, dots, dashes and underscores. How it works, its limits and its test tools are in launcher/README.md, "The setup wizard" and "The installer". The release also has the launcher as a zip (MCLA-Launcher-<tag>-win-x64.zip, the same folder, unpacked anywhere), which starts the same wizard.
The exe is not signed. Releases are not signed with a code-signing certificate, and will not be. Windows SmartScreen therefore may stop MCLA-Setup.exe the first time with Windows protected your PC (Microsoft Defender SmartScreen prevented an unrecognized app from starting): click More info, then Run anyway. (It asks for the downloaded file; the launcher it unpacks and the game it builds on your PC are written by programs on your PC, so they should not ask again.) If your browser holds the download back as uncommon, choose Keep (Edge: the downloads list, ..., Keep, Show more, Keep anyway), or right-click the file, Properties, tick Unblock. To check that the file is the one the release workflow built, compare Get-FileHash .\MCLA-Setup.exe with the release's SHA256SUMS or release.json, or run gh attestation verify MCLA-Setup.exe -R RenanQueiroz/mcla-recomp. Some antivirus programs distrust any new unsigned program that unpacks files and downloads compilers; if one removes it, nothing is lost: the source of everything is in this repository, and the sections below build the game by hand.
With the launcher (recommended)
In PowerShell:
git clone https://github.com/RenanQueiroz/mcla-recomp.git
cd mcla-recomp
.\launcher\build-game.ps1 -Iso C:\path\to\your.iso
.\launcher\build-launcher.ps1
build-game.ps1 runs scripts\make_pc.ps1, which clones the ReXGlue SDK v0.10.0 and applies upstream's and the fork's patches, builds it (the long step, once), extracts your game into game\, recompiles it and builds out\build\win-amd64-release\mcla.exe. Without -Iso it takes the first .iso in the folder that holds mcla-recomp. Each step is skipped when its result is already there, so after a failure you run the same command again. Logs are in out\logs. build-launcher.ps1 builds the launcher into launcher\app and puts a Midnight Club Los Angeles shortcut on the desktop.
From then on the shortcut is the way in. The launcher opens on the game's settings, and Play starts mcla.exe. When it opens it checks this fork on GitHub; if there are new commits it lists them under What's new and offers Update and rebuild. Commits that change only the launcher or the documentation don't need a game rebuild; when an update changed the launcher itself, it offers Restart to update the launcher. The More menu has Rebuild the game, Re-patch and rebuild the SDK, Run the build in a terminal, Prepare shaders, the game folder and the build logs, and says how many of upstream's commits the fork hasn't taken yet. Keep the repository where it was built: the game data is read from game\.
The launcher also prepares shaders: after every build and update, and before Play whenever the game's record of its shader storage says the graphics driver was updated, the card, the API or the resolution changed, the shader pack changed, or the shader cache was deleted or reset (the status line says why, counts the shaders and pipelines, and the game starts when it's done; Play now starts it at once and Stop ends the preparation without starting the game, which adds the pack by itself when it starts). It runs mcla.exe --mcla_prepare_shaders=true with the game's settings: it adds what the game's shader storage lacks of the fork's shader pack, rebuilding those shaders from your own game files, has the graphics driver compile every stored pipeline for your API and resolution, and quits. Places, cars and races the pack covers then don't compile shaders when you first meet them (no objects missing for a moment). The game itself also adds what its storage lacks of the pack at every start, so a storage that was deleted or reset fills again even without the launcher. The pack holds no game data, only fingerprints and the pipeline descriptions the storage keeps anyway (KNOWN-ISSUES.md). More › Prepare shaders runs it by hand, and also tries again a pack whose import was turned off after it stopped the game's start twice, and the shaders that couldn't be rebuilt.
The launcher's settings are the game's own, kept in mcla.toml next to mcla.exe. The Settings tab of the game's pause menu changes the same ones, so each shows what the other set. A change in the launcher is written to the file at once. While the game runs, the launcher's settings are greyed out: change them in the pause menu then, and the launcher shows them again once the game has closed.
| Setting | Choices | In mcla.toml | In the pause menu |
|---|---|---|---|
| Resolution | Native (720p), 2× (1440p), 3× (2160p, 4K) | resolution_scale = 1, 2 or 3 | DISPLAY › RESOLUTION (next start) |
| Frame rate | 30, 40, 45, 50, 60, 120 FPS, Uncapped | mcla_fps (0 for uncapped) | DISPLAY › FPS TARGET |
| Frame generation | Off (the default), FSR 3.1 (AMD's frame generation: a generated frame between each two the game renders) | frame_generation = off or fsr | DISPLAY › FRAME GENERATION |
| Frame rate with frame generation | Half display (the default: a little under half the refresh rate, 116 on a 240 Hz display), 30, 40, 45, 50, 60, 120 FPS rendered, Uncapped | mcla_fps_frame_generation (-1 for half display, 0 for uncapped) | DISPLAY › FPS TARGET, while frame generation is on |
| NVIDIA Reflex / AMD Anti-Lag 2 (named by the GPU) | Default (on for NVIDIA Reflex, off for AMD Anti-Lag 2; on with frame generation), Off, On, On + Boost (NVIDIA only) | low_latency = auto, off, on or boost | DISPLAY › NVIDIA REFLEX or AMD ANTI LAG 2 |
| Display | Fullscreen, Windowed | fullscreen = true or false | DISPLAY › FULLSCREEN |
| Screen scaling filter | Bilinear (the default), FSR 1, CAS: how the finished picture is scaled to the window or screen when their sizes differ | present_effect = bilinear, fsr or cas | the launcher (next start) |
| Display gamma | TV (as on the console), PC monitor (sRGB, brighter shadows) | mcla_display_gamma = tv or pc | DISPLAY › DISPLAY GAMMA |
| HDR | Off, Auto (when Windows HDR is on; the default), On | hdr = off, auto or on | DISPLAY › HDR |
| HDR peak brightness | Auto (what the display reports), or 200 to 4,000 nits in steps of 50 | hdr_peak_nits (0 for auto) | DISPLAY › PEAK BRIGHTNESS |
| HDR paper white | Auto (Windows' SDR content brightness), or 80 to 480 nits in steps of 10 | hdr_paper_white_nits (0 for auto) | DISPLAY › PAPER WHITE |
| HDR highlights | Normal, Bright, Brighter (the default), Brightest | mcla_hdr_highlights = 1, 1.5, 2 or 3 | DISPLAY › HIGHLIGHTS |
| Anti-aliasing | MSAA 2× (as on the console; the default), FSR 3.1 native AA (AMD FSR at native resolution: steadiest, a little softer), Off (2 to 5% faster at 3× than MSAA) | mcla_anti_aliasing = msaa, fsr or off (an older mcla_msaa = false still means off while it isn't set) | PERFORMANCE › ANTI ALIASING |
| FSR upscaling | Off (the default: FSR at native resolution), Ultra Quality (4/3×: the 3D scene drawn at exactly 1080p at 2×, 1620p at 3×), Quality (1.5×: 1440p for 4K), Balanced (1.7×), Performance (2×: 1080p for 4K); with FSR anti-aliasing only | mcla_upscaling = off, ultra_quality, quality, balanced or performance | PERFORMANCE › ANTI ALIASING: FSR ULTRA Q., QUALITY, BALANCED, PERFORM. (the render size in the label) |
| FSR sharpness | Off, 0.2 (the default), 0.4, 0.6, 0.8, 1.0; FSR only | temporal_aa_sharpness | PERFORMANCE › FSR SHARPNESS |
| Single tile rendering | With MSAA: On (the scene drawn once instead of in two tiles: 9 to 20% faster at 3×), Off (two tiles, as on the console); no difference with FSR or Off | mcla_single_tile = true or false | PERFORMANCE › SINGLE TILE RENDERING |
| Graphics preset | Custom (every option as set; the default), Low-end (anti-aliasing and the full-screen blur off, the far sun shadows drawn every 2nd frame and the environment map every 4th; about 11 to 12% less frame time at native resolution on an integrated Radeon; an option set by hand keeps its value) | mcla_preset = custom or low | (the launcher; the options it stands for are in PERFORMANCE) |
| Far shadow, environment map and reflection updates | Every frame (as shipped), every 2nd, 4th or 8th frame, the last picture kept in between | mcla_far_shadow_interval, mcla_env_map_interval, mcla_reflection_interval = 0 (every frame), 2, 4 or 8 | PERFORMANCE › FAR SHADOW UPDATES, ENVIRONMENT MAP UPDATES, REFLECTION UPDATES |
| HUD updates | 30 per second (as on the console), 60 per second (the default), 120 per second, Every frame | mcla_ui_hud_rate = 30, 60, 120 or 0 | DISPLAY › HUD UPDATES |
| Graphics API | Automatic (Vulkan on Intel graphics and on integrated AMD graphics of the RDNA generation, Direct3D 12 on everything else: NVIDIA, AMD graphics cards and the integrated Vega graphics of the older Ryzen APUs; the one it picks for your GPU is marked recommended; on a PC with two GPUs, the GPU is the high-performance one or the one Windows' graphics settings give mcla.exe, not the first Windows lists), Direct3D 12, Vulkan | mcla_gpu_backend = any, d3d12 or vulkan | DISPLAY › GRAPHICS API (next start) |
| Intro | Normal, Fast, Skip (hides the title logo) | mcla_intro = normal, fast or skip | CONTROLS › INTRO (next start) |
| Button prompts | Follow the controller, Xbox, PlayStation | mcla_button_prompts = auto, xbox or playstation | CONTROLS › BUTTON PROMPTS |
| Language | English (the default), French, German, Italian, Spanish | user_language = 1 (English), 4 (French), 3 (German), 6 (Italian) or 5 (Spanish) | none: the launcher and mcla.toml only (next start) |
| Player name | The name the game shows for you: up to 15 letters, digits and spaces (empty: User, as before) | user_name (a text; the SDK's, patches/rexglue-user-name.patch) | (the launcher and mcla.toml only; read when the game starts) |
Language is the Xbox 360 language the game asks the system for: the SDK's user_language (an Xbox language id, 1 English by default), which the game reads through the console's configuration call. Its own code has text for five languages, English, French, German, Italian and Spanish, which is what the launcher offers; any other id (Japanese 2, Korean 7, Polish 11, and so on) gives English. The game reads it when it needs a text, so set it before starting; the launcher is greyed out while the game runs, and the pause menu has no row for it. On the PS5 the same line in /data/mcla/mcla.toml applies (untested). The SDK's achievement texts follow the same setting where the game's resources have them (KNOWN-ISSUES.md).
Display gamma is the ramp the picture goes through on its way to the screen, as the console's display hardware applied it. The game writes sRGB-encoded colour; TV, the default, is the console's ramp for an HDTV (BT.709), which on a PC monitor makes the shadows darker than the game drew them (8-bit levels 64, 128 and 192 show as 48, 115 and 185). PC monitor leaves the game's output as it is, as an sRGB monitor expects. It changes during play, from the launcher or the pause menu (KNOWN-ISSUES.md).
HDR shows the game in HDR on a display in HDR mode (Windows' Use HDR): the game's HUD, menus and movies at the SDR level, as on the desktop, and its scene from its own tone map's inputs: the same as in SDR up to 60% of the game's white, never darker than SDR from there to the game's white, and brighter above it (lights at night, the sun, a dusk sky, headlights), the brightest highlights reaching about 90% of the peak setting. The default on Windows is Auto, which turns it on whenever Windows has HDR on for the display (with HDR off in Windows the game stays SDR as before); the look was signed off on an ASUS ROG Swift PG32UCDP (WOLED, Gaming HDR mode, Uniform Brightness on), 2026-10-16. Off keeps SDR always. Peak brightness and paper white default to what Windows reports: the peak the Windows HDR Calibration app measured, and the SDR content brightness slider, where the game's white lands; set the peak by hand if your display's HDR mode clips earlier (the launcher shows what Windows reports; --hdr_test_pattern=true shows bars to find where your display stops getting brighter). In the launcher each is a slider with an Auto box; in the pause menu they step by 50 and 10 nits, holding left or right goes faster, and AUTO comes first. The peak is never set below paper white: a step that would cross it stops at the last one that doesn't. A value typed into mcla.toml between the steps is kept and shown as it is. Highlights (Brighter by default) sets how far above the game's white bright things go. DISPLAY GAMMA keeps its meaning in HDR. All of them change during play (KNOWN-ISSUES.md).
FSR upscaling draws the 3D scene at a smaller size and lets FSR 3.1 rebuild the full picture from it over the frames: the HUD, the menus and the post-processing (bloom, tone mapping) stay at the full resolution and sharp. It saves GPU time at the cost of a softer picture (about 19% less fine detail at Ultra Quality, 22% at Quality and 33% at Performance than FSR at native resolution, measured on 4K stills; FSR SHARPNESS brings some back) and faint trails behind fast-moving cars and pedestrians. Ultra