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(IDirect3D2, IDirectDraw);
DEFINE_BASE_INTF(IDirect3D3, IDirectDraw); DEFINE_BASE_INTF(IDirect3D3, IDirectDraw);
DEFINE_BASE_INTF(IDirect3D7, IDirectDraw); DEFINE_BASE_INTF(IDirect3D7, IDirectDraw);
DEFINE_BASE_INTF(IDirect3DDevice2, IDirect3DDevice);
DEFINE_BASE_INTF(IDirect3DDevice3, IDirect3DDevice);
#undef DEFINE_BASE_INTF #undef DEFINE_BASE_INTF
@ -72,6 +74,10 @@ namespace Compat
DEFINE_INTF_ID(IDirect3D2); DEFINE_INTF_ID(IDirect3D2);
DEFINE_INTF_ID(IDirect3D3); DEFINE_INTF_ID(IDirect3D3);
DEFINE_INTF_ID(IDirect3D7); DEFINE_INTF_ID(IDirect3D7);
DEFINE_INTF_ID(IDirect3DDevice);
DEFINE_INTF_ID(IDirect3DDevice2);
DEFINE_INTF_ID(IDirect3DDevice3);
DEFINE_INTF_ID(IDirect3DDevice7);
#undef DEFINE_INTF_ID #undef DEFINE_INTF_ID

View File

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

View File

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

View File

@ -4,6 +4,7 @@
#include "CompatActivateAppHandler.h" #include "CompatActivateAppHandler.h"
#include "CompatDirect3d.h" #include "CompatDirect3d.h"
#include "CompatDirect3dDevice.h"
#include "CompatDirectDraw.h" #include "CompatDirectDraw.h"
#include "CompatDirectDrawSurface.h" #include "CompatDirectDrawSurface.h"
#include "CompatDirectDrawPalette.h" #include "CompatDirectDrawPalette.h"
@ -17,6 +18,9 @@
namespace namespace
{ {
void hookDirect3dDevice(CompatRef<IDirect3D3> d3d, CompatRef<IDirectDrawSurface4> renderTarget);
void hookDirect3dDevice7(CompatRef<IDirect3D7> d3d, CompatRef<IDirectDrawSurface7> renderTarget);
template <typename CompatInterface> template <typename CompatInterface>
void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf); void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf);
@ -33,26 +37,85 @@ namespace
return d3d; 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) if (d3d)
{ {
hookVtable<CompatDirect3d<IDirect3D>>(d3d); hookVtable<CompatDirect3d<IDirect3D>>(d3d);
hookVtable<CompatDirect3d<IDirect3D2>>(d3d); hookVtable<CompatDirect3d<IDirect3D2>>(d3d);
hookVtable<CompatDirect3d<IDirect3D3>>(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)); CompatPtr<IDirect3D7> d3d(createDirect3d<IDirect3D7>(dd));
if (d3d) if (d3d)
{ {
hookVtable<CompatDirect3d<IDirect3D7>>(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) void hookDirectDraw(CompatRef<IDirectDraw7> dd)
{ {
CompatDirectDraw<IDirectDraw7>::s_origVtable = *(&dd)->lpVtbl; CompatDirectDraw<IDirectDraw7>::s_origVtable = *(&dd)->lpVtbl;
@ -125,6 +188,13 @@ namespace DDrawHooks
return; 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()); auto dd7(DDrawRepository::getDirectDraw());
if (!dd7) if (!dd7)
{ {
@ -135,8 +205,15 @@ namespace DDrawHooks
hookDirectDraw(*dd7); hookDirectDraw(*dd7);
hookDirectDrawSurface(*dd7); hookDirectDrawSurface(*dd7);
hookDirectDrawPalette(*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(); 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);
}
};