Skip to content

x0reaxeax/RE6CrashFix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RE6CrashFix

Fix for immediate startup crash in Resident Evil 6 (Steam)

Usage

  1. Go to Releases and download d3d9.dll
  2. Place d3d9.dll into the main game directory where BH6.exe is located (steamapps\common\Resident Evil 6)
  3. Start the game normally

Notes

The mod will automatically set the game resolution to the resolution of the screen the game is launched on.
There will be NO OTHER RESOLUTIONS available in the game's graphic settings.
To change the resolution, follow these steps:

  1. Navigate to the main game folder where BH6.exe is located (steamapps\common\Resident Evil 6)
  2. Open the resource folder
  3. If you already started the game at least once with this mod, there will be a file named re6cfg.json, if not, create it or run the game once (with this mod in the game dir)
  4. Open the re6cfg.json file, and change the displayWidth and displayHeight to a desired resolution that your screen supports. If you created the file manually, use the config template below.
  5. Save the file and run the game

re6cfg.json config file template:

{
  "displayWidth": 1920,
  "displayHeight": 1080
}

Technical problem description

The game assumes that the screen it's currently running on will have less than 256 modes (apparently this is a trend, Mad Max does the same).
Having less than 256 display modes is very common with older hardware, but modern monitors usually have way more than 256 modes.
This would not be a problem, if the game implemented proper bounds checking, which is unfortunately not the case.
The structure which is to be populated with modes obtained via IDirect3D9::EnumAdapterModes is only big enough to hold 256 modes.
However, the game will happily loop through and process all available modes from 0 up to the number of available modes obtained via IDirect3D9::GetAdapterModeCount.
This can be seen in this rough pseudocode reconstruction:

DWORD32 totalModeCount = IDirect3D9::GetAdapterModeCount(
    currentAdapterIdx,
    D3DFMT_X8R8G8B8
);

DWORD32 modeEnumIndex = 0;

do {
    // ...
    HRESULT hr = pD3D9->EnumAdapterModes(
        edi,
        D3DFMT_X8R8G8B8,
        modeEnumIndex,
        &mode
    );
    // ...
    ++modeEnumIndex;
} while ( modeEnumIndex < totalModeCount);

This could be fixed either by patching this instruction:

.text:00F42939 3B 44 24 30    cmp     eax, [esp+0C0h+totalModeCount]

With a force clamp like:

cmp eax, 0x100
jb _continue

However, this approach would limit the potentially desired display modes from appearing in the game settings.

Resolution

Instead of clamping the loop to for (mode = 0; mode < 256; mode++);, this tool/mod/patch/fix obtains a desired resolution from a config file (or currently used screen res if no cfg file), and filters through all available modes in order to cherry-pick only the ones matching the desired resolution.
This way, the game settings will still contain available refresh rate options for the selected resolution.
However, if the target screen somehow still has more than 256 available modes for the specific given resolution, the modes will be clamped. (i.e. if you're playing this on a 5000000Hz monitor in the year 2369, I have bad news for you).

Hooked VTable functions:

  • IDirect3D9::EnumAdapterModes
  • IDirect3D9::GetAdapterModeCount

Hooked native function:

  • Direct3DCreate9