**DISCLAIMER** Readme and CMakeLists mostly AI-generated. # nfs-recompiled A static recompilation of **Need for Speed II: Special Edition** and **Need for Speed III: Hot Pursuit** from their original Win32 x86 executables into portable C++ that runs natively on Linux (and potentially other platforms). This is a toy project and not meant to be serious. But it works. nfs2 intro video nfs2 menu nfs2 gameplay nfs3 menu nfs3 gameplay ## Quick Start: Running the Game If you have obtained a release binary, here is how to get the game running. ### 1. Game Data You need the original game files. 1. **Install the game** from your original CD (or mount the iso). On Linux, install the game from the CD-ROM through Wine, e.g. `WINEARCH=win32 WINEPREFIX=/opt/win98 wine /mnt/AUTORUN.EXE` 2. **Copy CD data**: The game expects certain files to be on the CD. To run without the CD, copy the `Fedata` and `GameData` folders from the CD-ROM into your game installation directory (merging with existing folders if necessary). * *Tip*: You can check the `install.win` file in your installation directory. It lists paths; any path starting with a drive letter (like `D:\`) needs to be present on your disk relative to the executable for portable play. ### 2. Running Run the executable from the terminal. The game supports positional arguments to locate data files. | Arguments | Behavior | |---|---| | **0 args** | `./nfs3hp` | Uses the current directory for both game data and "CD" files. | | **1 arg** | `./nfs3hp /path/to/game` | Uses the specified path for both game data and "CD" files. | | **2 args** | `./nfs3hp /path/to/install /path/to/cdrom` | Specifies separate paths for the installed files and the CD-ROM content. | **Examples:** ```bash # Data and executable in the same folder $ ./nfs3hp # Executable separate from data $ ./build/nfs3hp /home/user/games/nfs3 # Separate install and CD mount $ ./build/nfs2se /home/user/games/nfs2 /mnt/cdrom ``` ## Building from source ### Prerequisites - CMake ≥ 3.15 - A C++17 compiler (GCC or Clang) - SDL2 development libraries - OpenGL development libraries - NASM (for x87 FPU optimizations) - Python 3 (only if regenerating disassembly) **Debian / Ubuntu:** ```bash sudo apt install build-essential cmake nasm python3 python3-pip \ libsdl2-dev libgl-dev ``` ### Build Instructions Windows users with the bundled SDL2 library can point CMake at the `/sdl2` subdirectory (this is done automatically if you configure from within the project root). ```bash cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build ``` ### CMake Options | Option | Default | Description | |---|---|---| | `WITH_PEDANTIC_FPU` | `OFF` | Use strict 80-bit extended-precision FPU emulation. Required for NFS3 software renderer glitches on Linux. | | `WITH_MMX` | `ON` | Enable MMX instruction support. | Example: ```bash cmake -B build -DWITH_PEDANTIC_FPU=ON ``` ## Regenerating Disassembled Files The repository contains pre-generated C++ code in `src/nfs2se/disassembly` and `src/nfs3hp/disassembly`. You do not need to run the disassembler to build the project. If you modify the disassembly logic in `disasm/`, you must regenerate the sources: 1. Ensure you have the original executables and DLLs: * **NFS II SE**: Place `nfs2sen.exe` and `eacsnd.dll` in the `nfs2se/` folder. * **NFS III HP**: Place `nfs3.exe`, `eacsnd.dll`, `softtria.dll`, and `voodoo2a.dll` in the `nfs3hp/` folder. 2. Install Python dependencies: ```bash pip3 install capstone ``` 3. Run the generation scripts: ```bash python3 disassemble_nfs2se.py python3 disassemble_nfs3hp.py ``` ## Project Structure ### Supported Games | Game | Executable | Generated Target | |---|---|---| | NFS II: SE | `nfs2se/nfs2sen.exe` | `nfs2se` | | NFS III: HP | `nfs3hp/nfs3.exe` | `nfs3hp` | ### How it works 1. **Python disassembler** (`disasm/`) — Uses Capstone to disassemble the original `.exe` and `.dll` files and emit C++ source files that reproduce the original program logic as function calls on a virtual CPU. 2. **Virtual x86 CPU** — A `x86::CPU` struct (`include/cpu.h`) with general-purpose registers, flags, a full x87 FPU (with optional 80-bit extended precision via NASM routines), and MMX support. 3. **Win32 API layer** — Minimal, native C++ reimplementations of 18 Win32 API modules (kernel32, user32, gdi32, DirectDraw, DirectInput, DirectSound, Glide 2x, etc.) provide the runtime environment the original code needs. 4. **SDL2 + OpenGL backend** — Platform services (windowing, audio, input, file I/O, timers, threads) are implemented on top of SDL2. The Glide 2x renderer translates 3Dfx draw calls into OpenGL. ### File Tree ``` disasm/ Python disassembly framework codegen/ x86 instruction -> C++ code generators ordlookup/ DLL ordinal-to-name lookup tables disassemble_nfs2se.py Disassembly driver for NFS II: SE disassemble_nfs3hp.py Disassembly driver for NFS III: HP include/ cpu.h Virtual x86 CPU struct (registers, flags) fpu.h x87 FPU emulation (80-bit extended precision) mmx.h MMX instruction support x86.h Base register types and utility macros lib/ Platform abstraction headers winapi/ Win32 API reimplementation headers ddraw/ IDirectDraw interfaces dinput/ IDirectInput interfaces dsound/ IDirectSound interfaces src/ lib/ Shared runtime library (nfs_core) sdl-backend/ SDL2 platform backend (file, audio, events, etc.) winapi/ Win32 API implementations x87.asm NASM routines for 80-bit FPU operations nfs2se/ NFS II: SE entry point + generated disassembly nfs3hp/ NFS III: HP entry point + generated disassembly nfs2se/ Original executables that can be decompiled for NFS2: SE nfs3hp/ Original executables that can be decompiled for NFS3: HP ```