1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Extended hooking to IDirect3DDevice interfaces

This commit is contained in:
narzoul 2016-06-10 18:21:52 +02:00
parent 691b10bff8
commit 6aba3b6f39
7 changed files with 307 additions and 5 deletions

View File

@ -0,0 +1,11 @@
#include "CompatDirect3dDevice.h"
template <typename TDirect3dDevice>
void CompatDirect3dDevice<TDirect3dDevice>::setCompatVtable(Vtable<TDirect3dDevice>& /*vtable*/)
{
}
template CompatDirect3dDevice<IDirect3DDevice>;
template CompatDirect3dDevice<IDirect3DDevice2>;
template CompatDirect3dDevice<IDirect3DDevice3>;
template CompatDirect3dDevice<IDirect3DDevice7>;

View File

@ -0,0 +1,11 @@
#pragma once
#include "CompatVtable.h"
#include "Direct3dDeviceVtblVisitor.h"
template <typename TDirect3dDevice>
class CompatDirect3dDevice : public CompatVtable<CompatDirect3dDevice<TDirect3dDevice>, TDirect3dDevice>
{
public:
static void setCompatVtable(Vtable<TDirect3dDevice>& vtable);
};

View File

@ -45,6 +45,8 @@ namespace Compat
DEFINE_BASE_INTF(IDirect3D2, IDirectDraw);
DEFINE_BASE_INTF(IDirect3D3, IDirectDraw);
DEFINE_BASE_INTF(IDirect3D7, IDirectDraw);
DEFINE_BASE_INTF(IDirect3DDevice2, IDirect3DDevice);
DEFINE_BASE_INTF(IDirect3DDevice3, IDirect3DDevice);
#undef DEFINE_BASE_INTF
@ -72,6 +74,10 @@ namespace Compat
DEFINE_INTF_ID(IDirect3D2);
DEFINE_INTF_ID(IDirect3D3);
DEFINE_INTF_ID(IDirect3D7);
DEFINE_INTF_ID(IDirect3DDevice);
DEFINE_INTF_ID(IDirect3DDevice2);
DEFINE_INTF_ID(IDirect3DDevice3);
DEFINE_INTF_ID(IDirect3DDevice7);
#undef DEFINE_INTF_ID

View File

@ -146,6 +146,7 @@
<ItemGroup>
<ClInclude Include="CompatActivateAppHandler.h" />
<ClInclude Include="CompatDirect3d.h" />
<ClInclude Include="CompatDirect3dDevice.h" />
<ClInclude Include="CompatDirectDrawPalette.h" />
<ClInclude Include="CompatDisplayMode.h" />
<ClInclude Include="CompatFontSmoothing.h" />
@ -177,6 +178,7 @@
<ClInclude Include="CompatDirectDrawSurface.h" />
<ClInclude Include="DDrawVtableVisitor.h" />
<ClInclude Include="CompatVtable.h" />
<ClInclude Include="Direct3dDeviceVtblVisitor.h" />
<ClInclude Include="Direct3dVtblVisitor.h" />
<ClInclude Include="DirectDrawPaletteVtblVisitor.h" />
<ClInclude Include="DirectDrawSurfaceVtblVisitor.h" />
@ -191,6 +193,7 @@
<ItemGroup>
<ClCompile Include="CompatActivateAppHandler.cpp" />
<ClCompile Include="CompatDirect3d.cpp" />
<ClCompile Include="CompatDirect3dDevice.cpp" />
<ClCompile Include="CompatDirectDraw.cpp" />
<ClCompile Include="CompatDirectDrawPalette.cpp" />
<ClCompile Include="CompatDirectDrawSurface.cpp" />

View File

@ -144,6 +144,12 @@
<ClInclude Include="DDrawHooks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Direct3dDeviceVtblVisitor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompatDirect3dDevice.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="DllMain.cpp">
@ -239,6 +245,9 @@
<ClCompile Include="DDrawHooks.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompatDirect3dDevice.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="DDrawCompat.def">

View File

@ -4,6 +4,7 @@
#include "CompatActivateAppHandler.h"
#include "CompatDirect3d.h"
#include "CompatDirect3dDevice.h"
#include "CompatDirectDraw.h"
#include "CompatDirectDrawSurface.h"
#include "CompatDirectDrawPalette.h"
@ -17,6 +18,9 @@
namespace
{
void hookDirect3dDevice(CompatRef<IDirect3D3> d3d, CompatRef<IDirectDrawSurface4> renderTarget);
void hookDirect3dDevice7(CompatRef<IDirect3D7> d3d, CompatRef<IDirectDrawSurface7> renderTarget);
template <typename CompatInterface>
void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf);
@ -33,26 +37,85 @@ namespace
return d3d;
}
void hookDirect3d(CompatRef<IDirectDraw> dd)
template <typename TDirect3dDevice, typename TDirect3d, typename TDirectDrawSurface,
typename... Params>
CompatPtr<TDirect3dDevice> createDirect3dDevice(
CompatRef<TDirect3d> d3d, CompatRef<TDirectDrawSurface> renderTarget, Params... params)
{
CompatPtr<IDirect3D> d3d(createDirect3d<IDirect3D>(dd));
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 = {};
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
desc.dwWidth = 1;
desc.dwHeight = 1;
desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
desc.ddpfPixelFormat.dwRGBBitCount = 32;
desc.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
desc.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
desc.ddpfPixelFormat.dwBBitMask = 0x000000FF;
desc.ddsCaps.dwCaps = DDSCAPS_3DDEVICE;
CompatPtr<IDirectDrawSurface7> renderTarget;
HRESULT result = dd->CreateSurface(&dd, &desc, &renderTarget.getRef(), nullptr);
if (FAILED(result))
{
Compat::Log() << "Failed to create a render target for hooking: " << result;
}
return renderTarget;
}
void hookDirect3d(CompatRef<IDirectDraw> dd, CompatRef<IDirectDrawSurface4> renderTarget)
{
CompatPtr<IDirect3D3> d3d(createDirect3d<IDirect3D3>(dd));
if (d3d)
{
hookVtable<CompatDirect3d<IDirect3D>>(d3d);
hookVtable<CompatDirect3d<IDirect3D2>>(d3d);
hookVtable<CompatDirect3d<IDirect3D3>>(d3d);
hookDirect3dDevice(*d3d, renderTarget);
}
}
void hookDirect3d7(CompatRef<IDirectDraw7> dd)
void hookDirect3d7(CompatRef<IDirectDraw7> dd, CompatRef<IDirectDrawSurface7> renderTarget)
{
CompatPtr<IDirect3D7> d3d(createDirect3d<IDirect3D7>(dd));
if (d3d)
{
hookVtable<CompatDirect3d<IDirect3D7>>(d3d);
hookDirect3dDevice7(*d3d, renderTarget);
}
}
void hookDirect3dDevice(CompatRef<IDirect3D3> d3d, CompatRef<IDirectDrawSurface4> renderTarget)
{
CompatPtr<IDirect3DDevice3> d3dDevice(
createDirect3dDevice<IDirect3DDevice3>(d3d, renderTarget, nullptr));
hookVtable<CompatDirect3dDevice<IDirect3DDevice>>(d3dDevice);
hookVtable<CompatDirect3dDevice<IDirect3DDevice2>>(d3dDevice);
hookVtable<CompatDirect3dDevice<IDirect3DDevice3>>(d3dDevice);
}
void hookDirect3dDevice7(CompatRef<IDirect3D7> d3d, CompatRef<IDirectDrawSurface7> renderTarget)
{
CompatPtr<IDirect3DDevice7> d3dDevice(
createDirect3dDevice<IDirect3DDevice7>(d3d, renderTarget));
hookVtable<CompatDirect3dDevice<IDirect3DDevice7>>(d3dDevice);
}
void hookDirectDraw(CompatRef<IDirectDraw7> dd)
{
CompatDirectDraw<IDirectDraw7>::s_origVtable = *(&dd)->lpVtbl;
@ -125,6 +188,13 @@ namespace DDrawHooks
return;
}
HRESULT result = dd->SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL);
if (FAILED(result))
{
Compat::Log() << "Failed to set the cooperative level for hooking: " << result;
return;
}
auto dd7(DDrawRepository::getDirectDraw());
if (!dd7)
{
@ -135,8 +205,15 @@ namespace DDrawHooks
hookDirectDraw(*dd7);
hookDirectDrawSurface(*dd7);
hookDirectDrawPalette(*dd7);
hookDirect3d(*dd);
hookDirect3d7(*dd7);
CompatPtr<IDirectDrawSurface7> renderTarget7(createRenderTarget(*dd7));
if (renderTarget7)
{
CompatPtr<IDirectDrawSurface4> renderTarget4(renderTarget7);
hookDirect3d(*dd, *renderTarget4);
hookDirect3d7(*dd7, *renderTarget7);
}
CompatActivateAppHandler::installHooks();
}

View File

@ -0,0 +1,185 @@
#pragma once
#define CINTERFACE
#include <d3d.h>
#include "DDrawVtableVisitor.h"
template <>
struct DDrawVtableForEach<IDirect3DDeviceVtbl>
{
template <typename Vtable, typename Visitor>
static void forEach(Visitor& visitor)
{
DDrawVtableForEach<IUnknownVtbl>::forEach<Vtable>(visitor);
DD_VISIT(Initialize);
DD_VISIT(GetCaps);
DD_VISIT(SwapTextureHandles);
DD_VISIT(CreateExecuteBuffer);
DD_VISIT(GetStats);
DD_VISIT(Execute);
DD_VISIT(AddViewport);
DD_VISIT(DeleteViewport);
DD_VISIT(NextViewport);
DD_VISIT(Pick);
DD_VISIT(GetPickRecords);
DD_VISIT(EnumTextureFormats);
DD_VISIT(CreateMatrix);
DD_VISIT(SetMatrix);
DD_VISIT(GetMatrix);
DD_VISIT(DeleteMatrix);
DD_VISIT(BeginScene);
DD_VISIT(EndScene);
DD_VISIT(GetDirect3D);
}
};
template <>
struct DDrawVtableForEach<IDirect3DDevice2Vtbl>
{
template <typename Vtable, typename Visitor>
static void forEach(Visitor& visitor)
{
DDrawVtableForEach<IUnknownVtbl>::forEach<Vtable>(visitor);
DD_VISIT(GetCaps);
DD_VISIT(SwapTextureHandles);
DD_VISIT(GetStats);
DD_VISIT(AddViewport);
DD_VISIT(DeleteViewport);
DD_VISIT(NextViewport);
DD_VISIT(EnumTextureFormats);
DD_VISIT(BeginScene);
DD_VISIT(EndScene);
DD_VISIT(GetDirect3D);
DD_VISIT(SetCurrentViewport);
DD_VISIT(GetCurrentViewport);
DD_VISIT(SetRenderTarget);
DD_VISIT(GetRenderTarget);
DD_VISIT(Begin);
DD_VISIT(BeginIndexed);
DD_VISIT(Vertex);
DD_VISIT(Index);
DD_VISIT(End);
DD_VISIT(GetRenderState);
DD_VISIT(SetRenderState);
DD_VISIT(GetLightState);
DD_VISIT(SetLightState);
DD_VISIT(SetTransform);
DD_VISIT(GetTransform);
DD_VISIT(MultiplyTransform);
DD_VISIT(DrawPrimitive);
DD_VISIT(DrawIndexedPrimitive);
DD_VISIT(SetClipStatus);
DD_VISIT(GetClipStatus);
}
};
template <>
struct DDrawVtableForEach<IDirect3DDevice3Vtbl>
{
template <typename Vtable, typename Visitor>
static void forEach(Visitor& visitor)
{
DDrawVtableForEach<IUnknownVtbl>::forEach<Vtable>(visitor);
DD_VISIT(GetCaps);
DD_VISIT(GetStats);
DD_VISIT(AddViewport);
DD_VISIT(DeleteViewport);
DD_VISIT(NextViewport);
DD_VISIT(EnumTextureFormats);
DD_VISIT(BeginScene);
DD_VISIT(EndScene);
DD_VISIT(GetDirect3D);
DD_VISIT(SetCurrentViewport);
DD_VISIT(GetCurrentViewport);
DD_VISIT(SetRenderTarget);
DD_VISIT(GetRenderTarget);
DD_VISIT(Begin);
DD_VISIT(BeginIndexed);
DD_VISIT(Vertex);
DD_VISIT(Index);
DD_VISIT(End);
DD_VISIT(GetRenderState);
DD_VISIT(SetRenderState);
DD_VISIT(GetLightState);
DD_VISIT(SetLightState);
DD_VISIT(SetTransform);
DD_VISIT(GetTransform);
DD_VISIT(MultiplyTransform);
DD_VISIT(DrawPrimitive);
DD_VISIT(DrawIndexedPrimitive);
DD_VISIT(SetClipStatus);
DD_VISIT(GetClipStatus);
DD_VISIT(DrawPrimitiveStrided);
DD_VISIT(DrawIndexedPrimitiveStrided);
DD_VISIT(DrawPrimitiveVB);
DD_VISIT(DrawIndexedPrimitiveVB);
DD_VISIT(ComputeSphereVisibility);
DD_VISIT(GetTexture);
DD_VISIT(SetTexture);
DD_VISIT(GetTextureStageState);
DD_VISIT(SetTextureStageState);
DD_VISIT(ValidateDevice);
}
};
template <>
struct DDrawVtableForEach<IDirect3DDevice7Vtbl>
{
template <typename Vtable, typename Visitor>
static void forEach(Visitor& visitor)
{
DDrawVtableForEach<IUnknownVtbl>::forEach<Vtable>(visitor);
DD_VISIT(GetCaps);
DD_VISIT(EnumTextureFormats);
DD_VISIT(BeginScene);
DD_VISIT(EndScene);
DD_VISIT(GetDirect3D);
DD_VISIT(SetRenderTarget);
DD_VISIT(GetRenderTarget);
DD_VISIT(Clear);
DD_VISIT(SetTransform);
DD_VISIT(GetTransform);
DD_VISIT(SetViewport);
DD_VISIT(MultiplyTransform);
DD_VISIT(GetViewport);
DD_VISIT(SetMaterial);
DD_VISIT(GetMaterial);
DD_VISIT(SetLight);
DD_VISIT(GetLight);
DD_VISIT(SetRenderState);
DD_VISIT(GetRenderState);
DD_VISIT(BeginStateBlock);
DD_VISIT(EndStateBlock);
DD_VISIT(PreLoad);
DD_VISIT(DrawPrimitive);
DD_VISIT(DrawIndexedPrimitive);
DD_VISIT(SetClipStatus);
DD_VISIT(GetClipStatus);
DD_VISIT(DrawPrimitiveStrided);
DD_VISIT(DrawIndexedPrimitiveStrided);
DD_VISIT(DrawPrimitiveVB);
DD_VISIT(DrawIndexedPrimitiveVB);
DD_VISIT(ComputeSphereVisibility);
DD_VISIT(GetTexture);
DD_VISIT(SetTexture);
DD_VISIT(GetTextureStageState);
DD_VISIT(SetTextureStageState);
DD_VISIT(ValidateDevice);
DD_VISIT(ApplyStateBlock);
DD_VISIT(CaptureStateBlock);
DD_VISIT(DeleteStateBlock);
DD_VISIT(CreateStateBlock);
DD_VISIT(Load);
DD_VISIT(LightEnable);
DD_VISIT(GetLightEnable);
DD_VISIT(SetClipPlane);
DD_VISIT(GetClipPlane);
DD_VISIT(GetInfo);
}
};