A work-in-progress decompilation of Lionhead's Black & White.
CMake downloads and uses a patched LLVM for assembly, linking, and a few other compilation steps. This is handled automatically at configure time.
sudo apt install cmake ninja-build mingw-w64 libc6-dev-i386-cross python3
python3 -m venv .venv && source .venv/bin/activate
pip install -r scripts/source_code/requirements.txtbrew install cmake ninja mingw-w64 python3
python3 -m venv .venv && source .venv/bin/activate
pip install -r scripts/source_code/requirements.txtInstall CMake, Ninja, and Python 3, then:
python -m venv .venv && .venv\Scripts\activate
pip install -r scripts/source_code/requirements.txt# Byte-exact reimplementation
cmake --workflow --preset release
# With debug symbols (for Ghidra, IDA Pro, live debugging)
cmake --workflow --preset relwithdebinfoBuilding the release preset prints an md5 checksum to confirm the result is byte-for-byte identical:
| md5sum | version |
|---|---|
174b1a64e74b2321f3c38ccc8a511e78 |
1.20 with no cd |
objdiff lets you compare decompiled functions against the original object files interactively.
# Generate the objdiff build and config
python configure_objdiff.py
# Then open objdiff pointed at the build directory
objdiff --project-dir cmake-build-presets/objdiffThe src/ directory contains the decompilation source:
src/asm/— assembly source for functions not yet decompiled to C/C++src/asm/unprocessed/— raw unprocessed assembly; files namedrunblack.reassemble.*are the main.textsections
src/staging/— C/C++ stubs used as the "base" side in objdiff comparisons
Data section files:
rdata.asm— read-only data (function pointers, vtables)data.asm— read-write data (function pointers, RTTI structs)data1.asm— read-write data (likely from static linking)SELFMOD.asm— executable section (possibly SafeDisc related)rsrc.asm— resource data (icons etc.), built with cvtres from VS97
The relwithdebinfo preset produces a PDB with globals, function definitions, and struct definitions usable in Ghidra and IDA Pro. Pre-built artifacts are available on the Actions page.
For live debugging, build with relwithdebinfo and launch with the working directory set to the original game files directory (where runblack.exe lives).
- Pick a function from
src/asm/and decompile it to C/C++ - Use objdiff (see above) to verify your output matches the original object code
- Open a pull request — the CI will confirm the md5 still matches