crosire / d3d8to9

A D3D8 pseudo-driver which converts API calls and bytecode shaders to equivalent D3D9 ones.
BSD 2-Clause "Simplified" License
911 stars 83 forks source link

Fix device lost error when creating device to fix issue with GTA III/VC #40

Closed elishacloud closed 7 years ago

elishacloud commented 7 years ago

This fix has several changes it in:

  1. Error with lost device when CreateDevice is called:

The core issue with GTA III/VC mentioned in #39 is that GTA would try and create a new device when the old device was still there. This caused it to return error D3DERR_DEVICELOST. However GTA does not know how to properly handle this error and simply crashed. The fix is to call Release() to release the previous device when a device lost error is seen so that a new device can be created.

It also seems that after the new device is created then GTA VC will call Release() and release the old device. So this update will release the Direct3D9 device. When GTA VC calls Release() then the Direct3D8 device (d3d8to9) will get released.

  1. Invalid display type listed with 0-bits of color:

When testing GTA VC I noticed it showed a device with 0-bits of color (should only show 16-bit and 32-bit color). I traced the issue to d3d8to9 using an unsupported D3DFMT_A2R10G10B10 adapter format. See here for documentation on Direct3D8 supported adapter formats. Also you can look at 'd3d8types.h' from the DirectX SDK to see supported Direct3D8 formats.

Note: don't be confused by D3DFMT_A2R10G10B10 and D3DFMT_A2B10G10R10, while similar these are different. I also noticed that D3DFMT_A2R10G10B10 did not exist in d3d8to9's 'd3d8types.cpp'. I am not sure it should be added or not.

  1. Issue with palette when palettes are not supported:

Also while I was testing this fix I found an issue in Indiana Jones and the Emperor's Tomb where it would crash because of how pixels are handled in d3d8to9 (from this change e0d43b5 for the crash in Need for Speed III). To fix this I changed the code to simply return D3DERR_INVALIDCALL when SetCurrentTexturePalette is called and palettes are not supported. This fixes both Indiana Jones and the Emperor's Tomb and Need for Speed III.

  1. Logging will stop when Direct3DCreate8 is called more than once:

In some games Direct3DCreate8() is called more than once. D3d8to9 tries to open the log file each time Direct3DCreate8 is called. This caused logging to stop at that point. This update fixes that issue by checking if the log is already open before opening it again.

elishacloud commented 7 years ago

I forgot to make a new branch so it looks like the check-in to fix Silent Hill 2 got put into this pull request. Basically this undoes part of the pixel shader change I made in #32 to fix lighting issues. I was a bit too zealous when I made that change.

  1. Removed regex that changes a '_bx2' modifier for constant values to use _x2 modifier

This change simply removes one line. I already tested this with other games including Star Wars Republic Commando to make sure I did not revert any of the previous fixes. This line is not needed, as far as I can tell, for any of the games I have tested.

CookiePLMonster commented 7 years ago

I wonder, should you consider this a bug in GTA III/GTA VC? If so, might be a good idea to fix it in http://gtaforums.com/topic/669045-silentpatch/

elishacloud commented 7 years ago

I updated this to Reset the device rather than releasing it. This solves the issue and I think is the proper fix. See comments from Microsoft here:

Reset is the only method that has an effect when a device is lost, and is the only method by which an application can change the device from a lost to an operational state.

I also fixed the way I check for D3DERR_DEVICELOST. The previous way was not very good.

elishacloud commented 7 years ago

Thanks for the all the comments. I removed pointer from PresentParams so that the data would not be lost when the scope is lost (though I don't I did not see any issue with it from my tests) and added a flag to the logging so that message box only is shown once.

Let me know if there are any other changes that are needed here.