mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Hook IDirect3DDevice7 only if needed
Creating an instance of the IDirect3DDevice7 interface appears to cause problems in some games that use only older versions of Direct3D. IDirect3DDevice7 is now only hooked when an application creates an instance. Fixes video playback artifacts in Populous: The Beginning. Fixes a crash in Carmageddon (Win95 version) reported in issue #3.
This commit is contained in:
parent
1af227afc4
commit
b78446c16f
@ -1,6 +1,7 @@
|
||||
#include "Common/CompatPtr.h"
|
||||
#include "Direct3d/DepthBuffer.h"
|
||||
#include "Direct3d/Direct3d.h"
|
||||
#include "Direct3d/Direct3dDevice.h"
|
||||
#include "Direct3d/Types.h"
|
||||
|
||||
namespace
|
||||
@ -13,6 +14,21 @@ namespace
|
||||
void* userArg;
|
||||
};
|
||||
|
||||
HRESULT STDMETHODCALLTYPE createDevice(
|
||||
IDirect3D7* This,
|
||||
REFCLSID rclsid,
|
||||
LPDIRECTDRAWSURFACE7 lpDDS,
|
||||
LPDIRECT3DDEVICE7* lplpD3DDevice)
|
||||
{
|
||||
HRESULT result = CompatVtable<IDirect3D7Vtbl>::s_origVtable.CreateDevice(
|
||||
This, rclsid, lpDDS, lplpD3DDevice);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
CompatVtable<IDirect3DDevice7Vtbl>::hookVtable((*lplpD3DDevice)->lpVtbl);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT CALLBACK d3dEnumDevicesCallback(
|
||||
GUID* lpGuid,
|
||||
LPSTR lpDeviceDescription,
|
||||
@ -56,6 +72,16 @@ namespace
|
||||
return CompatVtable<Vtable<TDirect3d>>::s_origVtable.EnumDevices(
|
||||
This, &d3dEnumDevicesCallback, ¶ms);
|
||||
}
|
||||
|
||||
template <typename TDirect3dVtbl>
|
||||
void setCompatVtable7(TDirect3dVtbl& /*vtable*/)
|
||||
{
|
||||
}
|
||||
|
||||
void setCompatVtable7(IDirect3D7Vtbl& vtable)
|
||||
{
|
||||
vtable.CreateDevice = &createDevice;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Direct3d
|
||||
@ -65,6 +91,7 @@ namespace Direct3d
|
||||
{
|
||||
vtable.EnumDevices = &enumDevices;
|
||||
// No need to fix FindDevice since it uses EnumDevices
|
||||
setCompatVtable7(vtable);
|
||||
}
|
||||
|
||||
template Direct3d<IDirect3D>;
|
||||
|
@ -45,21 +45,6 @@ namespace
|
||||
return d3d;
|
||||
}
|
||||
|
||||
template <typename TDirect3dDevice, typename TDirect3d, typename TDirectDrawSurface,
|
||||
typename... Params>
|
||||
CompatPtr<TDirect3dDevice> createDirect3dDevice(
|
||||
CompatRef<TDirect3d> d3d, CompatRef<TDirectDrawSurface> renderTarget, Params... params)
|
||||
{
|
||||
CompatPtr<TDirect3dDevice> d3dDevice;
|
||||
HRESULT result = d3d->CreateDevice(
|
||||
&d3d, IID_IDirect3DRGBDevice, &renderTarget, &d3dDevice.getRef(), params...);
|
||||
if (FAILED(result))
|
||||
{
|
||||
Compat::Log() << "Failed to create a Direct3D device for hooking: " << result;
|
||||
}
|
||||
return d3dDevice;
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> createRenderTarget(CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
@ -99,35 +84,32 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
void hookDirect3d7(CompatRef<IDirectDraw7> dd, CompatRef<IDirectDrawSurface7> renderTarget)
|
||||
void hookDirect3d7(CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
CompatPtr<IDirect3D7> d3d(createDirect3d<IDirect3D7>(dd));
|
||||
if (d3d)
|
||||
{
|
||||
hookVtable<IDirect3D7>(d3d);
|
||||
hookDirect3dDevice7(*d3d, renderTarget);
|
||||
hookDirect3dVertexBuffer7(*d3d);
|
||||
}
|
||||
}
|
||||
|
||||
void hookDirect3dDevice(CompatRef<IDirect3D3> d3d, CompatRef<IDirectDrawSurface4> renderTarget)
|
||||
{
|
||||
CompatPtr<IDirect3DDevice3> d3dDevice(
|
||||
createDirect3dDevice<IDirect3DDevice3>(d3d, renderTarget, nullptr));
|
||||
CompatPtr<IDirect3DDevice3> d3dDevice;
|
||||
HRESULT result = d3d->CreateDevice(
|
||||
&d3d, IID_IDirect3DRGBDevice, &renderTarget, &d3dDevice.getRef(), nullptr);
|
||||
if (FAILED(result))
|
||||
{
|
||||
Compat::Log() << "Failed to create a Direct3D device for hooking: " << result;
|
||||
return;
|
||||
}
|
||||
|
||||
hookVtable<IDirect3DDevice>(d3dDevice);
|
||||
hookVtable<IDirect3DDevice2>(d3dDevice);
|
||||
hookVtable<IDirect3DDevice3>(d3dDevice);
|
||||
}
|
||||
|
||||
void hookDirect3dDevice7(CompatRef<IDirect3D7> d3d, CompatRef<IDirectDrawSurface7> renderTarget)
|
||||
{
|
||||
CompatPtr<IDirect3DDevice7> d3dDevice(
|
||||
createDirect3dDevice<IDirect3DDevice7>(d3d, renderTarget));
|
||||
|
||||
hookVtable<IDirect3DDevice7>(d3dDevice);
|
||||
}
|
||||
|
||||
void hookDirect3dTexture(CompatRef<IDirectDraw> dd)
|
||||
{
|
||||
DDSURFACEDESC desc = {};
|
||||
@ -223,7 +205,7 @@ namespace Direct3d
|
||||
{
|
||||
CompatPtr<IDirectDrawSurface4> renderTarget4(renderTarget7);
|
||||
hookDirect3d(*dd, *renderTarget4);
|
||||
hookDirect3d7(*dd7, *renderTarget7);
|
||||
hookDirect3d7(*dd7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user