First off — thanks for maintaining this guide. It's one of the few genuinely useful MW3 resources out there, and the "living guide" approach is the right call.
I want to flag a problem with the dgVoodoo2 recommendation and propose an alternative, because I think the current advice steers some people straight into a crash that actually has a clean fix.
Symptom
On a clean, fully-patched (v1.2) install on Windows 11 (and, by the same mechanism, Windows 10), using dgVoodoo2 as the DirectDraw wrapper gets you to the menus and mech lab fine — but the game crashes 100% deterministically the instant any mission's cockpit/HUD starts compositing. Windows Error Reporting shows:
STATUS_GUARD_PAGE_VIOLATION (0x80000001) at Mech3.exe+0x16d4a5, followed by
a STATUS_ACCESS_VIOLATION (0xc0000005) with a faulting address of 0x424a424a — ASCII "JBJB", i.e. texture/pixel data.
Root cause
I disassembled the faulting function and traced it live with a debugger. The short version:
The code at +0x16d4a5 is a software span blitter using a 90s speed trick: it repurposes the CPU stack pointer (ESP) as its pixel write pointer and emits pixels with push:
mov [saved_esp], esp ; stash the real stack pointer
mov esp, [dest_surface_ptr] ; point ESP into the render surface
add esp, edi ; ESP = end of span (writes go downward)
loop:
mov al, [ebp+esi] ; sample 8-bit source texel
push word [ebx+eax*2] ; <-- FAULTS: write palette[texel] via ESP
jne loop
mov esp, [saved_esp] ; restore the real stack pointer
dgVoodoo2 emulates video memory in system RAM and marks its surface pages PAGE_GUARD for dirty-tracking. When a guard-page fault fires while ESP is pointing into the surface, Windows has to deliver the exception by pushing a context frame onto the stack — but the stack is the framebuffer. The dispatch can't complete (and/or re-faults on the bogus stack), so no in-process handler runs and the process dies. The 0x424a424a "return into garbage" is the signature of exception dispatch landing on a stack full of pixels.
dgVoodoo's FastVideoMemoryAccess = true does not fix it for the surface type MW3 uses here.
Fix
DDrawCompat (narzoul) wraps the real Windows DirectDraw without guard-page tracking, so the ESP-as-framebuffer writes simply succeed and the crash mechanism can't occur. Since MW3 imports only ddraw.dll for graphics, DDrawCompat's single ddraw.dll is sufficient — no Direct3D wrapper DLLs needed (and dgVoodoo's D3DImm.dll / D3D8.dll / D3D9.dll should be removed).
Game speed (MW3's clock is frame-rate-coupled) is handled with a DDrawCompat.ini:
FpsLimiter = flipstart(30)
I know dgVoodoo runs fine on some setups, so I'm not suggesting you rip it out — but on modern Windows it's at minimum unreliable for missions, and DDrawCompat has been rock-solid for me on both the base game and Pirate's Moon.
Full writeup
Root-cause analysis, the disassembly, the diagnostic method (WER + a ctypes/Wow64 debugger), and the other fixes I ran into (mandatory FMVs and the ISc(-vs-RIFF trap, Indeo 5 codec registration, the InstallOptions registry value) are all here:
https://github.com/telltaleatheist/mechwarrior3-windows-fix
Happy to open a PR adding a DDrawCompat section and a warning note on the dgVoodoo method if you're open to it.
First off — thanks for maintaining this guide. It's one of the few genuinely useful MW3 resources out there, and the "living guide" approach is the right call.
I want to flag a problem with the dgVoodoo2 recommendation and propose an alternative, because I think the current advice steers some people straight into a crash that actually has a clean fix.
Symptom
On a clean, fully-patched (v1.2) install on Windows 11 (and, by the same mechanism, Windows 10), using dgVoodoo2 as the DirectDraw wrapper gets you to the menus and mech lab fine — but the game crashes 100% deterministically the instant any mission's cockpit/HUD starts compositing. Windows Error Reporting shows:
STATUS_GUARD_PAGE_VIOLATION (0x80000001) at Mech3.exe+0x16d4a5, followed by
a STATUS_ACCESS_VIOLATION (0xc0000005) with a faulting address of 0x424a424a — ASCII "JBJB", i.e. texture/pixel data.
Root cause
I disassembled the faulting function and traced it live with a debugger. The short version:
The code at +0x16d4a5 is a software span blitter using a 90s speed trick: it repurposes the CPU stack pointer (ESP) as its pixel write pointer and emits pixels with push:
mov [saved_esp], esp ; stash the real stack pointer
mov esp, [dest_surface_ptr] ; point ESP into the render surface
add esp, edi ; ESP = end of span (writes go downward)
loop:
mov al, [ebp+esi] ; sample 8-bit source texel
push word [ebx+eax*2] ; <-- FAULTS: write palette[texel] via ESP
jne loop
mov esp, [saved_esp] ; restore the real stack pointer
dgVoodoo2 emulates video memory in system RAM and marks its surface pages PAGE_GUARD for dirty-tracking. When a guard-page fault fires while ESP is pointing into the surface, Windows has to deliver the exception by pushing a context frame onto the stack — but the stack is the framebuffer. The dispatch can't complete (and/or re-faults on the bogus stack), so no in-process handler runs and the process dies. The 0x424a424a "return into garbage" is the signature of exception dispatch landing on a stack full of pixels.
dgVoodoo's FastVideoMemoryAccess = true does not fix it for the surface type MW3 uses here.
Fix
DDrawCompat (narzoul) wraps the real Windows DirectDraw without guard-page tracking, so the ESP-as-framebuffer writes simply succeed and the crash mechanism can't occur. Since MW3 imports only ddraw.dll for graphics, DDrawCompat's single ddraw.dll is sufficient — no Direct3D wrapper DLLs needed (and dgVoodoo's D3DImm.dll / D3D8.dll / D3D9.dll should be removed).
Game speed (MW3's clock is frame-rate-coupled) is handled with a DDrawCompat.ini:
FpsLimiter = flipstart(30)
I know dgVoodoo runs fine on some setups, so I'm not suggesting you rip it out — but on modern Windows it's at minimum unreliable for missions, and DDrawCompat has been rock-solid for me on both the base game and Pirate's Moon.
Full writeup
Root-cause analysis, the disassembly, the diagnostic method (WER + a ctypes/Wow64 debugger), and the other fixes I ran into (mandatory FMVs and the ISc(-vs-RIFF trap, Indeo 5 codec registration, the InstallOptions registry value) are all here:
https://github.com/telltaleatheist/mechwarrior3-windows-fix
Happy to open a PR adding a DDrawCompat section and a warning note on the dgVoodoo method if you're open to it.