# 🏁 nfsu2_decomp ### *Need for Speed: Underground 2* β€” rebuilt from the PS2 binary as **native Linux code** **No emulator. No Wine. No Proton. No PS2 CPU, VU or GS emulation.** Every frame you see is produced by readable C++ and OpenGL running directly on your machine. ![platform](https://img.shields.io/badge/platform-Linux%20x86-orange?style=flat-square) ![language](https://img.shields.io/badge/C%2B%2B17-SDL2%20%2B%20OpenGL-blue?style=flat-square) ![emulation](https://img.shields.io/badge/emulation-none-brightgreen?style=flat-square) ![status](https://img.shields.io/badge/status-playable%20prototype-yellow?style=flat-square) ![commits](https://img.shields.io/badge/commits-377%2B-lightgrey?style=flat-square) ![log](https://img.shields.io/badge/ISSUES.md-333%20entries-informational?style=flat-square) Pre-race cinematic, countdown and launch in the Israeli-themed city *Live capture of the native build: the cinematic pre-race camera sweeping round the Skyline, the 3-2-1 countdown and the launch with the speed blur, the glass minimap and speed dial, AI rivals alongside β€” all running from decompiled game logic and the disc's own data files.*
--- ## What is this? This project is a **functional decompilation** of *Need for Speed: Underground 2* (PlayStation 2, PAL v2.00, `SLES_527.25`). Instead of emulating the console, the game's logic is reverse-engineered from the MIPS R5900 executable and rewritten as ordinary C++: | PS2 hardware | Linux replacement | |---|---| | EE CPU + VU0/VU1 microcode | Native C++ (VU strip data decoded into plain triangles) | | GS rasteriser | OpenGL pipeline with custom GLSL shaders | | SPU2 / IOP audio | SDL2 audio mixer fed from the game's own sound banks | | DVD + `ZDIR.BIN` archive | A native reader for the disc's `ZDIR.BIN` + `ZZDATA*.BIN` | | Memory card | A save layer writing profile files (versioned, currently v21) | It is a **bring-your-own-disc** project. The repository contains **no game code and no game assets** β€” you supply your own legally obtained copy of the game and the program reads it at run time. On top of the faithful port sits a deliberately **modern presentation layer** β€” shader sky, god rays, a 3D showroom for the menus, a new loading screen, a rebuilt HUD and a re-skinned, Israeli-themed city β€” all switchable off with environment variables (see the table at the bottom) if you want the original look. ## See it running
The new main menu
New main menu β€” flat and high-contrast: a column of big caps, a hard-edged signal-yellow highlight that glides to the selected row, a one-line description, your player, cash, reputation and current car, and the 3D showroom behind it. The original FEng carousel still runs underneath as the logic (input, selection, navigation); NFSU2_CLASSIC_MENU=1 shows the original screen.
Night street main menu
Night street showroom β€” a low rear three-quarter hero shot (0.3 m off the asphalt, aimed up, a 42Β° lens) on a procedural Israeli night street: apartment blocks with balconies, lit windows and shutters, a kiosk with a neon script sign, sodium streetlights as bokeh discs, wet asphalt mirroring the street and the car, linear-depth depth of field focused on the car, bloom and an anamorphic streak, ACES, a teal / amber grade and edge chromatic aberration (NFSU2_NO_STREET=1 restores the studio).
Garage and Body Shop
Garage and Body Shop β€” the garage list over the 3D room, then the Body Shop: a category column, the highlighted part with its price, total cost and cash, the camera swooping to the part's side of the car with a title card on every change, and the engine, hood and doors the original's animation data opens. The paint shop, world map, car select, results, reward and countdown are drawn natively the same way.
Quick Race menus
Quick Race menus β€” mode select and track select redrawn natively in the same flat style (a sliding yellow blade, a windowed list with lock marks and a scrollbar, the highlighted track's type, distance and best time); the car select, Options categories and the race options use the same list, settings and car panels. The original screens keep running underneath as the logic.
Garage 3D transitions
Garage 3D transitions β€” every change of shop shot swoops the camera round the car (orbit, dolly, lens punch, radial blur, easing past the mark and settling), a yellow blade wipes across and the title cuts in; the boot, hood and doors open and close with the original's own animation curves, decoded from CARS\<car>\PARTS_ANIMATIONS.BIN (tools/car_part_anims.py). NFSU2_GARAGE_TOUR=1 cycles the shots.
Wet paint
Rain on the paint β€” water drops modelled as spherical caps (about 65Β° contact angle): Fresnel reflection, catch-lights, a caustic crescent, drops stretched by gravity and by the wind of the car's speed, trails behind the big ones (NFSU2_WET=<0..1>).
Exhaust flames
Exhaust flames β€” short, ragged and pulsing (a few tens of centimetres, three tongues, blue-white at the pipe fading to orange) instead of the old missile trail (NFSU2_FORCE_FLAMES=1 to preview).
Loading screen
Loading screen β€” an animated full-window backdrop (the artwork with drifting smoke, played back and forth with a cross-fade), a glass progress bar that only moves forward across every load phase (menus, race interface, streaming and building the city), stage names and rotating hints.
Main menu showroom
Main-menu showroom β€” the real 3D car on a dark studio floor with a mirrored reflection, softbox light panels and a gentle camera sway, behind the original menu.
Car select
Car select β€” the car under studio strip lights turns slowly; changing car, paint or parts updates it live, through the same car shader the race uses.
Free-roam event prompt
Free-roam events β€” a light column marks every open career event; drive into it and the event is offered with its real name, type, distance and purse.
Sky, clouds, god rays and lens reflections
Sky, god rays and lens reflections β€” a per-pixel procedural sky with drifting cumulus and cirrus, shafts of sun cut out by the buildings, and lens ghosts, a halo and a streak while the sun is in view.
Old Israeli apartment block
Old apartment blocks β€” generated "shikun" buildings with slatted plastic shutters, wall air-conditioners, balconies and a roof of solar water heaters, in Jerusalem stone.
Police pursuit
Police pursuit β€” patrols watch the lanes; speeding in their sight starts a chase with heat levels 1–5, reinforcements, roadblocks, a BUSTED bar, a COOLDOWN bar and a bounty (NFSU2_NO_POLICE=1 turns it off). The car is a converted third-party model that is not in this repository.
Nitrous flames
Nitrous flames β€” a turbulent flame jet from each exhaust with shock-diamond beads, fire-frame particles, embers, a glare and a road glow; hold Space with a nitrous tank.
Trees and bushes in the wind
Living vegetation β€” leaf-card trees, flowering bushes and agave built from the game's own foliage textures, with a wind shader (travelling gusts, leaf flutter), per-tree colour variation and light through the leaves.
Pause menu
Esc menu β€” the glass pause dialog now opens the original in-race options (audio, video…) and Back returns to it; Resume, Main Menu and Quit work.
Screen transitions
Screen transitions β€” menu β†’ loading β†’ game, with a glowing diagonal wipe between screens and a loading backdrop that keeps moving (NFSU2_NO_TRANSITIONS=1 turns the wipes off).
Night racing
Night racing β€” emissive headlights and tail lights, glass covers, light pools on the road, a dusk sky with stars; one clock now runs day β†’ afternoon β†’ sunset β†’ night (F5, NFSU2_TIME=<hours>).
The police car
A patrol car at night with its light bar flashing (the model is the user's own download and is not distributed with the project).
## A modern presentation layer | Piece | What it does | Log | |---|---|---| | **Loading screen** | `ModernUI::DrawLoading`: your artwork cover-fitted with a Ken-Burns drift, grading, hints, a single monotonic progress bar fed by every loader (`FENativeInterface::SetLoadingHook`, `TrackWorld::SetProgress`) | #301 | | **Screen transitions** | A slanted, glowing light edge wipes one screen away to reveal the next: the menu frame into the loading screen, the finished loading frame over the game (`ModernUI::CaptureFrame` / `DrawWipe`); the graphics upload is done in slices under the loading screen so it never freezes at 100 % | #311 | | **Menu showroom** | `TrackWorld::RenderStage`: dark studio backdrop shader, the car drawn by the race's car shader in a *studio* environment (overhead strip box, tall coloured panels), mirrored reflection pass, glossy fading floor, light pool, bloom | #304 | | **Modern HUD** | Glass minimap rendered from the live road mesh, speed dial with nitrous gauge, drift counter, wind streaks and a radial speed blur (references: NFS Unbound) | #276, #295–#298 | | **Main menu and flat theme** | Native screens for the main menu, garage, mode / track / car select, settings lists, results, reward and countdown; a native main menu (flat caps, angled yellow highlight, player / cash / car) over the 3D showroom with a warm studio instead of the blue wash; the shared backdrop and the pause / confirm dialogs use the same flat style. The old blue-glow, violet and perspective-grid backdrop is gone | #352, #357 | | **Hybrid UI theme** | The original FEng menus keep their layout but sit on the flat backdrop | #290, #357 | | **Wet cars** | Drop-based rain on paint and glass | #356 | | **Garage transitions and opening panels** | Choreographed 3D camera moves, blade wipe and title cards between shop shots; hood / boot / doors play the decoded original animation banks | #358, #359 | | **Built-in profiler** | `F3`: frame time, CPU sections, GPU timer queries, a bound-ness verdict; draw-call batching and a single vertex arena took the city from 27 to a locked 60 fps | #282, #283 | | **Memory telemetry** | `F4`: every resident texture, vertex arena, cell list, car and sound buffer with its cost, priority and last use; `--mem-report` prints the loaded world's report and quits | #331 | | **Texture residency manager** | Over a VRAM budget the least recently used world textures are paged out and decoded again the next time their cell is in view (`NFSU2_TEX_BUDGET_MB`, `NFSU2_TEX_IDLE`); the report and the F4 panel show the budget and what was trimmed | #332 | ## Atmosphere
Exported apartment block, front Exported apartment block, roof
The exported shikun asset (5 floors, ~26,000 triangles, rendered here by the project's own tiny software rasteriser β€” flat vertex colours, no lighting).
- **Procedural shader sky (#302)** β€” a per-pixel view ray through a scattering-style gradient, a sun with disc, glare and warm low-sun band, perspective-projected cumulus with self-shadowed bases and silver rims, a high cirrus veil, and at night stars and a moon. - **God rays and lens reflections (#305)** β€” the post pass keeps the frame's depth (far = sky) and marches 48 jittered samples from every pixel towards the sun, so shafts only appear through real gaps; five ghosts, a halo ring and an anamorphic streak appear while the sun disc is visible; the sun is also mirrored in the interior-mapped window glass. Costs about 1.7 ms of GPU time. - **Weathered ground (#299, #300)** β€” a worn asphalt with repaired patches, fine cracks, stains and sheen; Israeli interlocking paving ("Eckerstein") with per-block tones, pale worn edges, sandy joints, dry leaves and litter; painted kerbs that are sun-bleached, chipped and grimy at the foot. - **An Israeli city (#272–#280, #306)** β€” four districts blended by the world shader (Tel Aviv Bauhaus, Jerusalem stone, Haifa terraces, Be'er Sheva brutalist concrete) with CC0 photographic materials, Hebrew signage, ~2 million triangles of street life (palms and pines, bus stops, scooters, cafΓ©s, dumpsters with cats, EV chargers, utility poles and cables, balconies, roller shutters, awnings) and generated buildings: Bauhaus "White City" blocks in Tel Aviv, old **shikun** apartment blocks elsewhere. - **Vegetation (#314)** β€” palms, pines, cypresses and olive trees rebuilt from textured leaf cards, plus ~11,000 bushes, agaves and flower beds; one foliage shader gives wind, translucency and per-tree colour. - **Cars (#312)** β€” a clear-coat shader with grounding and sun shadow, real lamp interiors and headlight cones on the road; a post-race reward screen (#313); nitrous flames (#317); better landings after a jump and a roll-stability torque (#316). - **Police (#318)** β€” the Israeli police Ε koda (converted from the user's own GTA V mod by `tools/convert_police.py`, output kept outside the repo), AI cops on the lane network, heat, roadblocks, bust and escape, a siren, and a pursuit HUD. - **Wet roads, interior-mapped offices, bloom, MSAA 4Γ—, anisotropic filtering, widescreen Hor+** from the earlier shader work. ### The apartment-block asset `./build/nfsu2 --export-shikun [floors width depth seed]` writes the building as `.obj` (vertex colours after `x y z`) and `.ply`. Two ready-made blocks are in [`assets/israel/shikun/`](assets/israel/shikun). It has weathered plaster panels, sliding aluminium windows with sills and lintels, **plastic roller shutters in every state** (each slat is geometry in the export), wall-mounted air-conditioner condensers with drain pipes and damp streaks, balconies with laundry, a glass-block stair tower, a yellow gas riser, patches of peeled plaster and rust, and a flat roof crowded with **solar water heaters (white tank on a flat black panel)**, black tanks, dishes and aerials. Honest limits: flat vertex colours rather than UV textures, no open ground floor, no interior. ## Custom shaders The PS2 had no programmable pixel pipeline, so the original look is baked into textures and vertex colours. This port keeps the original assets but renders them through **custom GLSL programs** (GLSL 1.20, so they work on older drivers; automatic fallback to fixed-function with `NFSU2_NO_SHADERS=1`). | Shader | What it does | |---|---| | **World grade + fog + district theme** | Colour grading, distance fog, four-district facade re-skinning and photographic materials (`World/Shaders.h`) | | **Road and pavement** | Worn asphalt, paver pattern, painted kerbs, wet-road puddles and sheen | | **Sky** | Procedural atmosphere, sun, two cloud layers, night stars and moon | | **Car clear coat** | Per-pixel lit paint with Fresnel and a procedural environment (night city, or the studio in the menus) | | **Wheel materials** | Alloy rim, rubber tyre and brake-disc shading, hub-relative normals, spoke blur at speed | | **Interior-mapped windows** | Tall office facades fake whole rooms behind the glass with a ray/box test, plus a sun glint β€” zero extra geometry | | **Post-process** | Bloom, filmic curve, vignette, radial speed blur, **god rays** and **lens reflections** from the frame's depth | | **Studio stage** | Backdrop with accent glow, light slabs and horizon seam for the menu showroom | | **Lamps and glass** | Emissive lenses that react to the brake pedal, translucent clear covers, soft glows, night light pools | | **Foliage** | Wind sway and flutter, per-tree tint, sun-through-leaf translucency, alpha-to-coverage edges | | **Flames and sirens** | Additive procedural flame sprites for the nitrous jet, red/blue light-bar flashes and road pools | | **Hot-spot and event beacons** | Additive light columns marking shops, car lots, the crib and open career events | ## Free-roam career layer The region data hides a whole trigger layer (#303): named locators in `PATHSFREEROAM.BIN`. Every career event record names the locator it starts at, so the 221 events now have real places on the map β€” drive into the marker and the event is offered; Accept starts the race. The same layer holds the car-show spots, the unique-part events (ported: #320-#325) and the tutorial-tip spots (ported: #308). ## Camera The original game's cameras were rebuilt on a small spring-based rig (`World/CameraRig.h`) so every move is frame-rate independent and nothing ever pops: | Camera | What it does | |---|---| | **Chase** | Spring heading, distance and height; leans into the car's *real* direction of travel in a slide; lens widens 70Β° β†’ ~81Β° with speed (+7Β° with nitrous); noses down under braking; subtle shake at speed | | **Pre-race cinematic** | Three constant-speed shots, then an orbit round the car (never through it) into the chase view, with letterbox bars | | **Garage** | The open shop screen maps to a pose: bumpers, skirts, spoiler, hood, roof, lights, exhaust, rims, paint, neon | | **Showroom** | Menu orbit and sway around the staged car | ## How much of the game is done? Honest numbers first, because "percent complete" means different things for a decompilation: | Measure | Result | |---|---| | Functions in the PS2 executable (Ghidra) | **16,897** | | Functions individually traced to an address in our source/notes | **β‰ˆ 810 (4.8 %)** β€” about **8 %** of the code by size | | UI screens (`.fng` packages) ported | **β‰ˆ 65 of 150** β€” about **62 % of the 104 that are not online / debug / demo** | | Findings, decodes and design notes logged | **373 entries** in [`ISSUES.md`](ISSUES.md) | | Commits | **393** | | C++ written | **β‰ˆ 46,500 lines in 131 files** (plus β‰ˆ 287,000 lines of vendored CC0 engine core) | | Frame rate | **60 fps** at 1280Γ—720 with MSAA 4Γ— on an integrated GPU (Intel Iris Xe); the new god-ray pass costs β‰ˆ 1.7 ms | | Triangles in view in the city | β‰ˆ 1.1 million per frame, β‰ˆ 560 draw calls | > **Why the function percentage is low:** the executable holds a huge amount of code this project deliberately > does **not** port one-for-one β€” online lobbies (~35 screens), the Sony/IOP/network SDKs, PS2 DMA/VU upload > plumbing, and EA's engine layer that is shared with the CC0 *Most Wanted* decompilation. Where the original > hardware code isn't needed on Linux, we replace it instead of translating it. The number that matters for > *playability* is the feature table below. ### Feature status (estimate) | Area | Status | Notes | |---|---|---| | Boot, EA logos, movies | βœ… working | Boot order mirrors `0x2dbd88`; the loading screens are replaced by the new one | | Front end / menus | 🟒 ~62 % of the screens | Main menu, Options, Quick Race flow, profiles, keyboard, 3D showroom background | | Quick Race | βœ… playable | Real car DB, tracks, 3-2-1 start, laps, finish, results, best times | | Free roam / city | βœ… working | Whole city streams in, collision mesh, traffic, minimap, full map, shop and event locators | | Driving physics | 🟒 solid | UG2 vehicle model from the car records, drivetrain, tuning, drift layer, regression benchmark | | AI opponents | 🟒 working | Route followers with skill scaling | | Police pursuit | 🟑 playable | Patrols, heat 1–5, roadblocks, bust / escape and a bounty in free roam; no spike strips, helicopters or bust animation | | Career mode | 🟑 mostly | Events, areas, sponsors, SMS inbox, car lot, crib, progression rules, events started from the street | | Car customisation | 🟑 mostly | Parts, performance packages, tuning sliders, dyno, vinyls, decals, paint, rims, spinners, neon | | Garage / shops (3D) | 🟑 partial | The garage room and the four street shops (body, paint, performance, specialty) render their own 3D interior over the city without a reload, with a part-following camera; the original street-shop plumbing and per-shop car placement are stand-ins (#330) | | Graphics | 🟒 beyond original | Custom shaders, shader sky, god rays, MSAA, widescreen Hor+, working car lights and glass, a full time-of-day clock (day / afternoon / sunset / night, `F5`) | | Audio | 🟑 partial | Engine, skid, turbo, wind and UI sounds; music streams; full mix not final | | Online / network | β›” out of scope | Needs EA servers that no longer exist | | Car shows / magazine covers, tutorial tips, Uniques | 🟑 playable | Car-show spots win magazine covers (#309), tip spots deliver SMS (#308), the seven Unique spots of a region offer a part / rim / vinyl or a performance slot (#320-#325); the original's 3D preview and prices are not ported | | Reverse lamps, turn signals | β›” not in the original | The PS2 cars ship no such solids (`ISSUES.md` #329) | If you want **one number** for "can I play the game": roughly **half of the single-player game is reachable and playable natively today** (menus β†’ Quick Race β†’ free roam β†’ career flow β†’ customisation), with the long tail being polish screens, shops' per-category logic and audio mixing. ## Quick start Built as **native 32-bit x86** (the original data and EA's engine code assume 4-byte pointers). You need `g++-multilib`, CMake, Ninja and `libsdl2-dev:i386`. ```sh cmake -S . -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=cmake/linux-i386.cmake cmake --build build ./build/bware_test # engine core self-test NFSU2_DATA=/path/to/your/disc ./build/nfsu2 --test # disc file-system self-test NFSU2_DATA=/path/to/your/disc ./build/nfsu2 # play ``` `/path/to/your/disc` must contain `NFSUNDER/ZDIR.BIN` and `ZZDATA*.BIN` from **your own** PAL disc image. | Key | Action | |---|---| | Arrows / WASD | Steer and menu navigation | | Enter / Space | Accept | | **Esc** | Back in menus, **pause** while driving | | X / Left Shift | Handbrake while driving (starts a drift); pad square in menus | | Q / E | L1 / R1 | | F3 | Performance overlay | | F4 | Memory / residency overlay | | F5 | Next time of day: day β†’ afternoon β†’ sunset β†’ night | | F6 | Freeze / resume the time-of-day clock | | F10 | Quit | The window is 16:9 by default and resizable. The 3D world widens with the window (no stretching), while the UI keeps its original 4:3 layout, pillar-boxed.
Useful developer environment variables | Variable | Effect | |---|---| | `NFSU2_WORLD=L4RA` | Jump straight into a region | | `NFSU2_RACE=4012` | Start a specific race | | `NFSU2_RACETYPE=9` | Free roam | | `NFSU2_AUTODRIVE=1` | The AI drives the player's car | | `NFSU2_DRIVE="3500-9000:up,..."` | Hold buttons for a time window (hand-driven tests) | | `NFSU2_SPAWN=x,y,yaw` | Teleport the player (dev aid) | | `NFSU2_WORLD_FLY=1` + `NFSU2_WORLD_CAM=x,y,z,yaw,pitch` | Free camera; `NFSU2_FLY_SPIN=` turns it, `NFSU2_FLY_ORBIT="cx,cy,r,zLook,rad/s"` circles a point | | `NFSU2_TIME=` / `NFSU2_TIME_PRESET=day\|afternoon\|sunset\|night` | Set the hour (the presets are 12.5 / 16.0 / 17.8 / 21.0 h); `F5` cycles them | | `NFSU2_TIME_SPEED=` / `F6` | Run the time-of-day clock (`0.02` = a day in 20 minutes); `F6` freezes / resumes; `NFSU2_NIGHT=1` = 21:00 | | `NFSU2_NO_SHADERS=1` | Fixed-function fallback | | `NFSU2_CLASSIC_SKY=1` / `NFSU2_NO_RAYS=1` | Old sky gradient / no god rays and lens reflections (`NFSU2_RAYS=` sets the strength) | | `NFSU2_NO_STAGE=1` / `NFSU2_CLASSIC_LOADING=1` / `NFSU2_CLASSIC_UI=1` | Original menu backdrop and car preview / original loading screens / original UI look | | `NFSU2_NO_THEME=1` / `NFSU2_NO_PROPS=1` / `NFSU2_NO_SHIKUN=1` | Turn the Israeli theme, street props or generated apartment blocks off | | `NFSU2_MSAA=0/2/4/8` | Multisampling | | `NFSU2_PERF=1` | Print the profiler every 2 s (`F3` shows it on screen) | | `NFSU2_MEM_OVERLAY=1` / `--mem-report` | Start with the residency panel (`F4`) on / print the loaded world's memory report and quit (`NFSU2_MEM_REPORT_MS` delays it) | | `NFSU2_TEX_BUDGET_MB=192` | Texture VRAM budget of the residency manager; `0` never trims (`NFSU2_TEX_IDLE=10` = seconds a texture must be unused) | | `NFSU2_SCREENSHOT=f.bmp` | Save the whole window and quit | | `NFSU2_MEMCARD=dir` | Use a scratch save directory | | `NFSU2_PACKAGE=UI_Main.fng` | Open a front-end screen directly |
## How it was done (the short version) 1. **Extract the disc.** `tools/zdir_names.py` and `tools/zz_extract.py` solved the `ZDIR.BIN` index (24-byte records keyed by EA's `bStringHash`) and pull files out of `ZZDATA0-3.BIN`. 2. **Analyse the executable.** Ghidra with the *Emotion Engine* extension decompiles the R5900 code; a pseudocode dump of all 16,897 functions is kept **locally** (never committed) and used as the reference. 3. **Decode the data.** EA `bChunk` containers, JDLZ compression, TPK textures, solid meshes whose triangle strips live in **VU1 packets** (including the odd-vertex UV swap and R-register ADC strip topology), the collision mesh, road/traffic graphs, the car database, part database, GLOBALB career tables, FNG UI packages and the audio banks. 4. **Rewrite, don't emulate.** Each decoded behaviour becomes normal C++ with a `// 0xADDRESS` comment to its original. Bugs and findings are recorded in [`ISSUES.md`](ISSUES.md) (333 entries so far β€” read it, it is the real project diary). 5. **Reuse where legal and sensible.** The engine core shared with the CC0 *Most Wanted* decompilation ([`dbalatoni13/nfsmw`](https://github.com/dbalatoni13/nfsmw)) is vendored in `third_party/nfsmw`. ## Repository layout | Path | What | |---|---| | `src/game/bWare/` | EA Black Box engine core | | `src/game/indep/` | Platform-independent game code: `Career/`, `Frontend/`, `Physics/`, `Sound/`, `World/`, `Texture/`, `FEng/` | | `src/platform/linux/` | Linux replacements for PS2 hardware and SDK calls | | `tools/` | Archive, chunk, VU-strip, audio and hot-spot analysis scripts; `record_gif.sh` captures the game window to a GIF for the README; `obj_preview.py` is a tiny software rasteriser for the exported building asset | | `docs/` | Function map, UI screen registry, physics notes, media | | `assets/` | Open-licence material the theme uses: CC0 ambientCG photo materials, the Rajdhani / Alef typefaces (SIL OFL), the loading-screen artwork and the exported apartment-block asset (`assets/israel/shikun/`) | | `third_party/nfsmw/` | Vendored CC0 engine code, local changes in `PATCHES.md` | | `ISSUES.md` | Numbered log of every decode, fix and open question | ## πŸš€ The future: smart optimisation and smart memory The PS2 version was designed around **32 MB of RAM, 4 MB of VRAM, fixed DMA budgets and a DVD seek time**. Every one of those limits shaped the original code β€” and none of them exist on a modern Linux box. Now that the game runs as plain native code, those assumptions can be replaced instead of preserved. This is the roadmap (all **planned**, none of it is done yet): **Smart memory management** - 🧠 **Budgeted residency manager** β€” replace the PS2's fixed streaming slots with a single arena-based manager that tracks every texture, solid and sound with a cost, priority and last-use time, and evicts by value instead of by slot. - πŸ—œοΈ **Asynchronous decompression** β€” JDLZ/Huffman decode on worker threads feeding a lock-free queue, so the render thread never waits on a chunk (today it decodes the region synchronously at load). - πŸ“¦ **64-bit clean data layer** β€” the 32-bit build exists only because EA's chunk layouts embed pointers. A load-time relocation pass would let the engine run as a normal 64-bit process. - πŸ” **Built-in memory telemetry** β€” an in-game overlay (and `--mem-report`) showing live residency, peak usage, fragmentation and per-subsystem budgets, so every change can be measured. **Smart optimisation** - 🎯 **GPU-driven world rendering** β€” the city is ~61,000 placed instances and ~4 million triangles; move culling and instancing onto the GPU instead of rebuilding client-side arrays per cell. - 🧩 **Texture streaming and atlasing** β€” mip-level residency from screen-space size, one bindless/atlas path instead of a bind per run. - πŸ“ˆ **Adaptive quality** β€” a frame-time controller that raises/lowers MSAA, draw distance, bloom and shadow quality to hold a target frame rate. - 🧡 **Job-system simulation** β€” traffic, AI and collision queries on a thread pool with deterministic results, so physics stays identical to the original model. - πŸ§ͺ **Profile-guided regression tests** β€” golden-frame and golden-lap tests so optimisations can never silently change gameplay. ## Credits and legal - Original code in this repository is under the [MIT License](LICENSE); `third_party/nfsmw` keeps its own (CC0). - Built by reverse-engineering a personally owned copy of the game for **interoperability, preservation and education**. All game code and art remain the property of Electronic Arts. - **This repository contains no EA code, executables, textures, models, music or other assets.** The loading-screen artwork and the apartment-block asset are original to this project; the photo materials are CC0. The screenshots and GIFs under `docs/media` are captures of the running program, included to document the project; if a rights holder objects, they will be removed. - The police car is **not** part of this repository: it is converted at run time from a third-party mod the user owns (its author forbids redistribution), kept outside git. The GIFs and the still show it only as running in the game; they will be removed on request. - Not affiliated with or endorsed by Electronic Arts or Black Box. - Thanks to [`dbalatoni13/nfsmw`](https://github.com/dbalatoni13/nfsmw) (CC0 Most Wanted decompilation), [`cobanov/nfsu2-decomp`](https://github.com/cobanov/nfsu2-decomp) (GC/PC day-zero work), the Ghidra project and the `ghidra-emotionengine-reloaded` extension. ---
Made on Kali Linux. No emulators were harmed in the making of this port.