Mafia: The City of Lost Heaven
TecnologíaPort Nativo C/C++ (Reimplementación de Motor)
Disponible paraWindows, Linux, macOS
Ver proyecto oficialSobre el proyecto
Mafia: The City of Lost Heaven es un videojuego de acci�n y aventura, lanzado en 2000.
Información oficial del proyecto
Mafia-RE
Decompilation of Mafia: The City of Lost Heaven (Illusion Softworks, 2002) for PC, in every released version: the original 1.0, the official patches 1.1 and 1.2, and Steam's rebuild of the setup (Versions). Version 1.2, the last official patch and the version Steam ships, is the main target. The other versions are built from the same source, with their differences kept behind macros.
The goal is a byte-exact decompilation: source code that, built with the compilers and linkers the original binaries were built with, produces files identical to the originals of each version.
Progress
<img src="docs/progress/Game.svg" width="50%"><img src="docs/progress/LS3DF.svg" width="50%"> <img src="docs/progress/LS3DF.1.1.svg" width="50%"><img src="docs/progress/rw_data.svg" width="50%"> <img src="docs/progress/IJoy.svg" width="50%"><img src="docs/progress/setup.svg" width="50%">
The cards count each binary's own functions, without the C runtime linked into it. Implemented is how many of them
have source, accuracy is reccmp's average score for those, and the bar is the
score summed over all of them. The function counts are exact but for Game.exe's, an estimate until its code has been
worked through.
LS3DF.dll (patch 1.1) is the engine of the 1.1 patch, built from the same source with its differences behind
ENGINE_VERSION.
| Binary | Status |
|---|---|
rw_data.dll | Done. The Visual C++ 6.0 build is identical to the original, byte for byte. |
setup.exe | Fully decompiled. The Visual C++ 6.0 build is identical to the 1.2 setup, and with 1.0's differences behind SETUP_1_0 to the 1.0 setup. The same source, with Steam's changes behind SETUP_STEAM, builds Steam's 2010 rebuild with Visual C++ 2008 SP1, identical to it too, and with each language's resources Steam's German, French, Italian and Spanish setups, identical as well, and its Russian one, identical when linked on Windows 2000 (on current Windows the order of its imports differs, as IJoy.dll's does). Its Polish one, a week older than 1.2, is a target of its own with its differences behind SETUP_DATE, and identical too. So is its Czech one, a build of August 2002 without optimization, which keeps the source's shape: compiled the same way, the source gives its code, and the build is identical to it, linked on Windows 2000 like the Russian one. |
LS3DF.dll (engine) | Every source file is written: the 3D engine (frames and visuals, meshes, objects and lightmapped objects, models, animation, cameras, lights, particles, portals and sectors, shadows and projectors, collision, the scene loaders, the renderer, the driver with its vertex and index buffers, and the math), the graphics layer (the Direct3D device, textures, and video through Bink and DirectShow) and the sound driver. About nine in ten of its functions compile to the original instructions. The others differ mostly in register allocation and in what the compiler inlines, and until they match the file differs from the original too, its code shifted by their sizes. The libraries it links are in place: S3's texture compressor comes from the original's own objects, and the DirectX 8.1 SDK's DirectShow base classes build from the SDK's source to the original's bytes. |
Game.exe | Started. The build is in place: the C runtime is linked as in the original, and the resources are the original's. The code is written in the order the game runs, so that the rebuilt executable gets further with each step, each function in the source file the original's layout puts it in (docs/game-files.md). The first step, through the start-up to the main menu, is under way: the entry point and main, the CD check, InitSystem and CloseSystem are written, with part of what they call (the mission, the caches of models, sounds and animations, the effects table, the console's font, the patch's script changes, the logo videos), and most of them compile to the original's instructions. A run of the rebuilt executable goes from the start to the main menu and closes down again; what it reaches that isn't written yet, such as the menu itself, is a stub that logs its name (CONTRIBUTING.md). With about 5,000 functions it is the biggest task ahead. No unprotected copy of the 1.2 executable survives, so the reference it is compared with is rebuilt from the retail copies (CONTRIBUTING.md). |
IJoy.dll | Done. Every function compiles to the original instructions, and linked on Windows 2000 the build is identical to the original. On current Windows the order of the imports within each DLL differs, because the linker sorts them with the system's msvcrt.dll, whose sort has changed since. It is built with the original Visual C++ 6.0 release and the Processor Pack's code generator, as the original was. |
Versions
Each version replaced only some of the binaries. A binary that a version didn't change is the previous version's file.
| Version | Built | Its own binaries | State |
|---|---|---|---|
| 1.0 | July–August 2002 | All of them | setup.exe is a target, built from the setup's source with its differences behind SETUP_DATE: its texts are in the code and the dialog instead of a string table, it has no W-buffer test, and it collects the antialiasing modes differently. The build is identical to it. Its Game.exe and LS3DF.dll aren't started yet. |
| Patch 1.1 | November 2002 – March 2003 | Game.exe, LS3DF.dll, setup.exe | LS3DF.dll is a target, built from the engine's source with its differences behind ENGINE_VERSION (393 against 1.2's 395); about nine in ten of its functions are 1.2's. Its setup.exe is the target above: the 1.2 patch ships the same file. Its Game.exe survives only inside its SafeDisc protection, so it can't be compared yet. |
| Patch 1.2 | June 2003 | Game.exe, LS3DF.dll | The main target, above. |
| Steam | April 2010 | setup.exe | A target, built from the setup's source with Steam's changes behind SETUP_STEAM. Its language versions ship their own setup.exe: German, French, Italian and Spanish are the 2010 rebuild with translated resources, the others older builds (Russian 1.2's code, Polish and Czech versions between 1.0 and 1.2). Steam's other binaries are 1.2's, some with small patches of their own. |
Neither patch contains rw_data.dll or IJoy.dll, and both were built in July 2002, before 1.0's other binaries, so the
targets above are most likely the same files in every version.
Building
You need Windows, Git, Python 3 and CMake 3.29 or newer. Building doesn't need the game, but comparing a build with the original binaries does: bring your own copy of version 1.2.
- Clone the repository with its submodules, keeping git from changing their line endings:
In a clone made without them, rungit -c core.autocrlf=false clone --recurse-submodules https://github.com/Marvisak/mafia-re.gitgit -c core.autocrlf=false submodule update --init. The submodules in3rdparty/are the build tools the original binaries were made with:msvc600_sp5_vcpp: Visual C++ 6.0 with Service Pack 5 and the Processor Pack, from archaic-msvc.msvc600: the original Visual C++ 6.0 release, which buildsIJoy.dll(with the Processor Pack's code generator frommsvc600_sp5_vcpp), also from archaic-msvc.msvc600_sp5: Visual C++ 6.0 with Service Pack 5 but without the Processor Pack, whose code generator builds the DirectShow base classes inLS3DF.dll, also from archaic-msvc.msvc900_sp1: Visual C++ 2008 SP1 with the Windows SDK 6.0A, which Steam's 2010setup.exewas built with, from Marvisak/msvc900_sp1.dx8sdk: the headers and libraries of the DirectX 8.0 SDK, whichsetup.exewas built with, from anominy/dx8sdk.dx81sdk: the headers and libraries of the DirectX 8.1 SDK, which Steam's 2010setup.exe,IJoy.dllandLS3DF.dllwere built with, from Marvisak/dx81sdk.
- Install the Python tools (they include Ninja):
python -m venv .venv && .venv/Scripts/python -m pip install -r requirements.txt - Build with Visual C++ 6.0, the toolchain the game was built with. The output goes to
build/vc6:cmake --preset vc6 && cmake --build --preset vc6 - Optionally, build with an installed Visual Studio from an x86 developer prompt. The output goes to
build/msvc, and it works but doesn't match the original:
Addcmake --preset msvc && cmake --build --preset msvc-DSETUP_STEAM=ONto the first command to build Steam's 2010setup.exeinstead of the 1.2 one. - Optionally, build Steam's 2010
setup.exewith Visual C++ 2008 SP1, the toolchain it was built with. The output goes tobuild/vs2008:cmake --preset vs2008 && cmake --build --preset vs2008
CONTRIBUTING.md describes how to compare a build with the original binaries.
Contributing
Any contributions are welcome, all information for contributors is in CONTRIBUTING.md.
