A cross-platform editor/patcher for Grand Prix 2's GP2.EXE. It edits the
24 per-slot "magic data" tuning tables and a curated set of statically-patchable
physics values (engine, power curve, aero, brakes, mass/grip, tyres,
slipstream), and reads/writes the legacy .m2d magic-data format plus a new,
human-readable physics TOML format.
This tool patches
GP2.EXEin place. Before you write anything, keep your own copy of the original executable somewhere safe.As a safety net, the editor automatically copies the file to
GP2.EXE.bakonce (the first time you write), and verifies every write by reloading the file and comparing bytes. But the.bakis only created on the first write and is never overwritten — it is not a substitute for your own backup. If you patch a file you already patched before, the.bakstill holds the previous state, not the factory original. Keep a pristine copy yourself.
GP2 Workshop draws its interface with OpenGL (eframe's glow backend), so it
needs a working OpenGL 2.1+ driver on the machine that runs it:
- On any PC with normal GPU drivers installed, this is already the case.
- On a bare Windows 7 install that only has Microsoft's default software OpenGL 1.1 (i.e. no GPU vendor driver), the window will fail to render. Install the GPU driver (Intel/NVIDIA/AMD) first.
Windows 7 also needs a dedicated build — Rust dropped Windows 7/8 support in
1.78, so the ordinary Windows build fails at launch with a missing
api-ms-win-core-*.dll. See docs/WINDOWS7-BUILD.md
for how the Win7 package is produced.
- Magic Data tab — pick a slot (1–16), edit the 24 tables in a labelled
grid, and Import/Export the slot directly to/from the EXE or Load/Save a
.m2dfile. The.m2dformat is unchanged from the old editor (24 decimal lines, table order 1–24, one file per slot), so files are interchangeable. Table 6 is dead data (ignored by the game) and is shown disabled. - Physics tab — sub-tabs for Engine, Power Curve, Aero, Brakes, Mass/Grip, Tyres and Slipstream. Basic fields are always shown; Advanced fields live behind a collapsing section. Fixed-point fields show their float value and a hex tooltip, and every field has a "↺ stock" reset button. The Power Curve sub-tab has an editable 36-entry table plus a line plot. Import/Export the whole physics set to/from the EXE, or Load/Save it as TOML.
A calibration step verifies known stock values in the EXE before any write.
If the file calibrates you'll see a green ✓ calibrated (Δ=0x…) badge; if it
can't be calibrated (unknown/garbage image) the badge reads ⚠ uncalibrated
and all Export-to-EXE actions are disabled (you can still load/save files).
In scope: the 24 magic-data tables, the curated physics inventory above, the power curve, the four tyre compounds' base grip/wear + worn floor. Out of scope in this version: deep editing of the tyre wear curve and track-abrasion tables (read-only / Advanced), per-car horsepower, track management, and saved-game editing.
crates/gp2ws-core— all logic (offsets, calibration, encoding, field registry,.m2dand TOML I/O). No GUI, fully unit-tested. The GUI holds no file offsets — it only talks to theSessionfaçade.crates/gp2ws-gui— theeframe/eguidesktop application.
cargo build --release -p gp2ws-gui
cargo run -p gp2ws-guiThe Windows binary is built with the GNU toolchain via mingw-w64. One-time setup:
rustup target add x86_64-pc-windows-gnu
sudo apt-get install -y mingw-w64 # Debian/Ubuntu.cargo/config.toml already points the linker at x86_64-w64-mingw32-gcc, so:
cargo build --release --target x86_64-pc-windows-gnu -p gp2ws-guiproduces target/x86_64-pc-windows-gnu/release/gp2ws-gui.exe.
cargo testSome integration tests verify offsets/values against a real GP2.EXE. They
are skipped unless you point them at a reference executable via the
GP2WS_TEST_EXE environment variable (the EXE is never committed to this repo):
GP2WS_TEST_EXE=/path/to/GP2.EXE cargo testGP2.EXEis an uncompressed DOS executable; it is patched raw at file offsets. All multi-byte values are little-endian; fixed-point is Q.14 (0x4000= 1.0).- The standard EXE has no segment shift (Δ = 0). Calibration first tries Δ = 0, then a small window-scan fallback to derive a consistent delta.