
MechWarrior 2 (demech2)
Port nativo de MechWarrior 2 (demech2) para PC.
MechWarrior 2 (demech2)
Port nativo basado en su ficha de origen.
README del repositorio
MechWarrior 2 Decompilation
This is a work-in-progress decompilation of the Windows 95 release of MechWarrior 2. It aims to be as accurate as possible, matching the recompiled instructions to the original machine code as much as possible. The goal is to provide a workable codebase that can be modified, improved, and ported to other platforms later on.
This project is modeled after the LEGO Island and LEGO Racers decompilations.
Note: This repository is for decompilation only and its code is true to the original release. It will not compile for targets other than 32-bit Windows. A modern, portable adaptation of the MechWarrior 2 codebase is planned.
Status
Progress only counts game code. The statically linked C runtime and the import thunks are left out of both the matched and the total counts. The totals come from Ghidra’s analysis of the original binaries and may grow slightly as decompilation turns up missed functions.
Every game-code function of the four binaries of the 1.1 patch and the retail release is decompiled. A fifth target, the simulator of the Matrox Mystique edition (MW2_MATROX.DLL), is built from the same simulator source, where its differences (it keeps the simulation's values as floats, and draws through Matrox's API) are being worked in. Beyond that edition, two kinds of work remain. One is raising the match: plenty of functions are still short of byte-identical, and many of those differ only by compiler artifacts (stack-slot assignment, operand order), which reccmp still scores as differences. The other is understanding the code: much of it still carries placeholder names (FUN_10003580, m_unk0x04, g_unk0x100a00dc) that need to be studied and replaced with meaningful names and types. Contributions are welcome.
The continuous release (continuous) carries the latest recompiled binaries from main, with their PDBs and progress reports.
Building
This project uses the CMake build system. For the most accurate results, Microsoft Visual C++ 4.1 (the same compiler used to build the original DLLs) is recommended. Since we're trying to match the output of this code to the original executables as closely as possible, all contributions will be graded with the output of this compiler.
These instructions will outline how to compile this repository using Visual C++ 4.1 into highly accurate binaries that closely match the originals. If you wish, you can try using other compilers, but this is at your own risk and won't be covered in this guide.
Prerequisites
You will need the following software installed:
- Microsoft Visual C++ 4.1. A portable version is available that can be downloaded and used quickly.
- MASM 6.11 (ML), for the original's hand-written assembly. A ready-to-use copy is available; the build only needs its
BIN\ML.EXE. Don't put itsBINon yourPATH: it also holds a 16-bitLINK,LIBandNMAKEthat would shadow Visual C++ 4.1's. - Microsoft Visual C++ 2.2, for
MECH2.EXEandNETMECHW.DLL(optional). A portable version is available too. Without it, both are built with Visual C++ 4.1 instead, which isn't their original toolchain. - Microsoft Visual C++ 4.0, for the Matrox edition's
MW2_MATROX.DLL(optional). A portable version is available. Without it, the Matrox edition is built with Visual C++ 4.1, whose stack-slot assignment and C runtime differ from its original toolchain's. - CMake. A copy is often included with the "Desktop development with C++" workload in newer versions of Visual Studio; however, it can also be installed as a standalone app. Version 3.26.6 (i386) is known to work with the VC++ 4.1 NMake generator.
Compiling
- Open a Command Prompt (
cmd). - From Visual C++ 4.1, run
BIN\VCVARS32.BATto populate the path and other environment variables for compiling with MSVC. - Make a folder for compiled objects to go, such as a
buildfolder inside the source repository (the folder you cloned/downloaded to). - In your Command Prompt,
cdto the build folder. - Configure the project with CMake by running:
cmake <path-to-source> -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_ASM_MASM_COMPILER=<path-to-masm>\BIN\ML.EXE
- Visual C++ 4.1 has issues with paths containing spaces. If you get configure or build errors, make sure neither CMake, the repository, nor Visual C++ 4.1 is in a path that contains spaces.
- Replace
<path-to-source>with the source repository. This can be..if your build folder is inside the source repository. RelWithDebInfois recommended because it will produce debug symbols useful for further decompilation work.NMake Makefilesis most recommended because it will be immediately compatible with Visual C++ 4.1.- To build
MECH2.EXEandNETMECHW.DLLwith Visual C++ 2.2, add-DDEMECH2_MSVC22_ROOT=<path-to-msvc22>. CMake builds them in a nested build and sets up Visual C++ 2.2's environment itself, so only Visual C++ 4.1'sVCVARS32.BATneeds to run. - To build
MW2_MATROX.DLLwith Visual C++ 4.0, add-DDEMECH2_MSVC40_ROOT=<path-to-msvc40>: another nested build, set up the same way. - The shell's dialogs show an icon that is not included in this repository. If the original 1.1
MW2SHELL.DLLis in the repository root, the build takes the icon from it; point-DDEMECH2_MW2SHELL_ORIGINAL=<path>at a copy elsewhere. Without it, the shell still builds and runs, and those dialogs just show no icon. The same goes for the launcher's window icons and the originalMECH2.EXE(-DDEMECH2_MECH2_ORIGINAL=<path>), and for the NetMech lobby's icons and bitmaps and the originalNETMECHW.DLL(-DDEMECH2_NETMECHW_ORIGINAL=<path>).
- Build the project by running
nmakeorcmake --build <build-folder> - When this is done, there should be a recompiled
MW2SHELL.DLL,MW2.DLL,NETMECHW.DLL,MECH2.EXEandMW2_MATROX.DLLin the build folder (NETMECHW.DLLandMECH2.EXEin itsvc22subfolder when built with Visual C++ 2.2,MW2_MATROX.DLLin itsvc40subfolder when built with Visual C++ 4.0).
The build configuration for each binary (comparison builds use Visual C++ 4.1's linker with Visual C++ 2.2's libraries for the Visual C++ 2.2 targets, so reccmp can read their PDBs):
| Target | Language | cl flags | CRT | Link |
|---|---|---|---|---|
MW2.DLL | C | /Od /Oi /G5 | /MTd (static debug) | /DLL /DEBUG /INCREMENTAL:no |
MW2SHELL.DLL | C++ (some C files) | /Od /Oi /G5 /Ob1 /GX (C files: no /GX) | /MT (static) | /DLL |
NETMECHW.DLL | C and C++ (Visual C++ 2.2) | /Od /Oi /Z7 (no /GX) | /MT (static) | /DLL, /DEBUG /INCREMENTAL:no |
MECH2.EXE | C (Visual C++ 2.2) | /Od /Oi /G5 /Z7 | /ML (single-threaded) | incremental EXE, /DEBUG |
MW2_MATROX.DLL | C (Visual C++ 4.0) | /Od /Oi /G5 | /MT (static) | /DLL /DEBUG /INCREMENTAL:no |
Docker
Alternatively, we support Docker as a method of compilation. This is ideal for users on Linux and macOS who do not wish to manually configure a Wine environment for compiling this project.
Compilation should be as simple as configuring and running the following command:
docker run -d \
-e CMAKE_FLAGS="-DCMAKE_BUILD_TYPE=RelWithDebInfo" \
-v <path-to-source>:/demech2:rw \
-v <build-folder>:/build:rw \
ghcr.io/anpage/demech2:latest
<path-to-source> should be replaced with the path to the source code directory (ie: the root of this repository).
<build-folder> should be replaced with the path to the build folder you'd like CMake to use during compilation.
You can pass as many CMake flags as you'd like in the CMAKE_FLAGS environment variable, but the default configuration provided in the command is already ideal for building highly-accurate binaries.
Verification
To verify your build against the original binaries, install the reccmp tooling:
pip install -r tools/requirements.txt
This installs a fork pinned to a commit: MECH2.EXE was linked incrementally but has no debug directory, and reccmp only looks for the incremental thunks in images that have one.
Create reccmp-user.yml in the project root pointing to the original binaries:
targets:
MW2SHELL:
path: path/to/MW2SHELL.DLL
MW2:
path: path/to/MW2.DLL
NETMECHW:
path: path/to/NETMECHW.DLL
MECH2:
path: path/to/MECH2.EXE
MW2MATROX:
path: path/to/MW2_MATROX.DLL
Then run:
reccmp-reccmp --target MW2SHELL -S MW2SHELLPROGRESS.SVG
reccmp-reccmp --target MW2 -S MW2PROGRESS.SVG
reccmp-reccmp --target NETMECHW --nolib --total 244
reccmp-reccmp --target MECH2 --nolib --total 21
reccmp-reccmp --target MW2MATROX --nolib --total 1597
Continuous integration
Pull requests are built and verified with Visual C++ 4.1 and 2.2 on GitHub Actions. The 1.1 patch's MW2SHELL.DLL and MW2.DLL are downloaded by the Build workflow itself. The retail NETMECHW.DLL and MECH2.EXE aren't freely downloadable, so a second workflow (verify-retail.yml) runs after Build with access to a private repository holding the originals: it compares the Build run's binaries against them with reccmp and appends the results to the Build workflow's PR comment. Pull requests from forks get the same report.
Project Structure
MECH2/- Decompilation of the retailMECH2.EXElauncher (a reccmp target with Visual C++ 2.2)MW2SHELL/- Decompilation ofMW2SHELL.DLLMW2/- Decompilation ofMW2.DLLNETMECHW/- Decompilation of the retailNETMECHW.DLL, NetMech's lobby (a reccmp target with Visual C++ 2.2)util/- Utility headers for decompilation3rdparty/- Import libraries (.deffiles), DirectX 2 SDK headers, and our own Miles/Smacker declarationscmake/- CMake modulestools/- Python tools and requirementsreccmp/- reccmp data sourcesdocker/- VC++ 4.1 + VC++ 2.2 + CMake under Wine build imagevc22/- The VC++ 2.2 sub-project that buildsMECH2.EXEandNETMECHW.DLLassets/- Progress report icons
Target Binaries
| Binary | Role | Size | SHA256 | Modified |
|---|---|---|---|---|
MW2SHELL.DLL | Shell: FMV, menus, settings, metagame | 545,792 bytes | 1078ccb07fd45388bfd525719a8206ce7a01d6536776d30a5655ccb928900879 | October 9, 1996 |
MW2.DLL | Simulator (in-mission gameplay) | 827,392 bytes | 6212d542f8f915a594b278ab189f20a27e522e7c08ac57ce68bf47f45b17bbb5 | September 19, 1996 |
Both DLLs come from the freely downloadable 1.1 patch.
| Binary | Role | Size | SHA256 | Modified |
|---|---|---|---|---|
NETMECHW.DLL | NetMech lobby | 433,152 bytes | 3f4d1508238d847213127e46623a85b249985686d6053a3d9e1c6deea87c0095 | December 8, 1995 |
MECH2.EXE | Launcher | 53,248 bytes | 064a9f1f45cfd18f0bef1dea9711b7fd582755cfbb8a8e9694f8cef2e5c3690c | December 5, 1995 |
Both come from the retail release, not the patch. Comparing them requires the original retail files and a build with Visual C++ 2.2 (-DDEMECH2_MSVC22_ROOT). Without that compiler the project still builds both, but the results cannot be compared to the originals.
Contributing
Contributions are welcome. Please follow the conventions established in the codebase:
- Use reccmp annotations (
FUNCTION:,STUB:,GLOBAL:) for all decompiled code - Functions in a compilation unit must be ordered by their address in ascending order
- Follow the clang-format configuration
- Use NCC naming conventions (
FUN_XXXXXXXXfor unknown functions,g_unk0xXXXXXXXXfor unknown globals) - Keep pull requests small and focused
Comentarios (0)
Inicia sesión para dejar un comentario.
Sé el primero en comentar sobre este juego.
