From 652bf677066bb7b82922d624a44af1ae2416eb23 Mon Sep 17 00:00:00 2001 From: narzoul Date: Fri, 17 Apr 2020 23:53:18 +0200 Subject: [PATCH] Hook Direct3D light and material interfaces --- DDrawCompat/Common/CompatQueryInterface.h | 5 ++ DDrawCompat/DDrawCompat.vcxproj | 6 ++ DDrawCompat/DDrawCompat.vcxproj.filters | 18 +++++ DDrawCompat/Direct3d/Direct3dLight.cpp | 8 +++ DDrawCompat/Direct3d/Direct3dLight.h | 16 +++++ DDrawCompat/Direct3d/Direct3dMaterial.cpp | 13 ++++ DDrawCompat/Direct3d/Direct3dMaterial.h | 19 +++++ DDrawCompat/Direct3d/Hooks.cpp | 50 ++++++++++--- DDrawCompat/Direct3d/Log.cpp | 70 +++++++++++++++++++ DDrawCompat/Direct3d/Log.h | 6 ++ .../Visitors/Direct3dLightVtblVisitor.h | 19 +++++ .../Visitors/Direct3dMaterialVtblVisitor.h | 46 ++++++++++++ 12 files changed, 268 insertions(+), 8 deletions(-) create mode 100644 DDrawCompat/Direct3d/Direct3dLight.cpp create mode 100644 DDrawCompat/Direct3d/Direct3dLight.h create mode 100644 DDrawCompat/Direct3d/Direct3dMaterial.cpp create mode 100644 DDrawCompat/Direct3d/Direct3dMaterial.h create mode 100644 DDrawCompat/Direct3d/Visitors/Direct3dLightVtblVisitor.h create mode 100644 DDrawCompat/Direct3d/Visitors/Direct3dMaterialVtblVisitor.h diff --git a/DDrawCompat/Common/CompatQueryInterface.h b/DDrawCompat/Common/CompatQueryInterface.h index f10f0ec..8646192 100644 --- a/DDrawCompat/Common/CompatQueryInterface.h +++ b/DDrawCompat/Common/CompatQueryInterface.h @@ -46,6 +46,8 @@ namespace Compat DEFINE_BASE_INTF(IDirect3D7, IDirectDraw); DEFINE_BASE_INTF(IDirect3DDevice2, IDirect3DDevice); DEFINE_BASE_INTF(IDirect3DDevice3, IDirect3DDevice); + DEFINE_BASE_INTF(IDirect3DMaterial2, IDirect3DMaterial); + DEFINE_BASE_INTF(IDirect3DMaterial3, IDirect3DMaterial); DEFINE_BASE_INTF(IDirect3DTexture, IDirectDrawSurface); DEFINE_BASE_INTF(IDirect3DTexture2, IDirectDrawSurface); DEFINE_BASE_INTF(IDirect3DViewport2, IDirect3DViewport); @@ -81,6 +83,9 @@ namespace Compat DEFINE_INTF_ID(IDirect3DDevice2); DEFINE_INTF_ID(IDirect3DDevice3); DEFINE_INTF_ID(IDirect3DDevice7); + DEFINE_INTF_ID(IDirect3DMaterial); + DEFINE_INTF_ID(IDirect3DMaterial2); + DEFINE_INTF_ID(IDirect3DMaterial3); DEFINE_INTF_ID(IDirect3DTexture); DEFINE_INTF_ID(IDirect3DTexture2); DEFINE_INTF_ID(IDirect3DViewport); diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj index e99294a..2560c9c 100644 --- a/DDrawCompat/DDrawCompat.vcxproj +++ b/DDrawCompat/DDrawCompat.vcxproj @@ -195,6 +195,8 @@ + + @@ -202,6 +204,8 @@ + + @@ -267,6 +271,8 @@ + + diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters index 6b372e6..bfa63e8 100644 --- a/DDrawCompat/DDrawCompat.vcxproj.filters +++ b/DDrawCompat/DDrawCompat.vcxproj.filters @@ -369,6 +369,18 @@ Header Files\Win32 + + Header Files\Direct3d + + + Header Files\Direct3d\Visitors + + + Header Files\Direct3d\Visitors + + + Header Files\Direct3d + @@ -569,6 +581,12 @@ Source Files\Win32 + + Source Files\Direct3d + + + Source Files\Direct3d + diff --git a/DDrawCompat/Direct3d/Direct3dLight.cpp b/DDrawCompat/Direct3d/Direct3dLight.cpp new file mode 100644 index 0000000..f261f7f --- /dev/null +++ b/DDrawCompat/Direct3d/Direct3dLight.cpp @@ -0,0 +1,8 @@ +#include + +namespace Direct3d +{ + void Direct3dLight::setCompatVtable(IDirect3DLightVtbl& /*vtable*/) + { + } +} diff --git a/DDrawCompat/Direct3d/Direct3dLight.h b/DDrawCompat/Direct3d/Direct3dLight.h new file mode 100644 index 0000000..d0299e6 --- /dev/null +++ b/DDrawCompat/Direct3d/Direct3dLight.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include + +namespace Direct3d +{ + class Direct3dLight : public CompatVtable + { + public: + static void setCompatVtable(IDirect3DLightVtbl& vtable); + }; +} + +SET_COMPAT_VTABLE(IDirect3DLightVtbl, Direct3d::Direct3dLight); diff --git a/DDrawCompat/Direct3d/Direct3dMaterial.cpp b/DDrawCompat/Direct3d/Direct3dMaterial.cpp new file mode 100644 index 0000000..7c13091 --- /dev/null +++ b/DDrawCompat/Direct3d/Direct3dMaterial.cpp @@ -0,0 +1,13 @@ +#include + +namespace Direct3d +{ + template + void Direct3dMaterial::setCompatVtable(Vtable& /*vtable*/) + { + } + + template Direct3dMaterial; + template Direct3dMaterial; + template Direct3dMaterial; +} diff --git a/DDrawCompat/Direct3d/Direct3dMaterial.h b/DDrawCompat/Direct3d/Direct3dMaterial.h new file mode 100644 index 0000000..044c83b --- /dev/null +++ b/DDrawCompat/Direct3d/Direct3dMaterial.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include +#include + +namespace Direct3d +{ + template + class Direct3dMaterial : public CompatVtable> + { + public: + static void setCompatVtable(Vtable& vtable); + }; +} + +SET_COMPAT_VTABLE(IDirect3DMaterialVtbl, Direct3d::Direct3dMaterial); +SET_COMPAT_VTABLE(IDirect3DMaterial2Vtbl, Direct3d::Direct3dMaterial); +SET_COMPAT_VTABLE(IDirect3DMaterial3Vtbl, Direct3d::Direct3dMaterial); diff --git a/DDrawCompat/Direct3d/Hooks.cpp b/DDrawCompat/Direct3d/Hooks.cpp index 676b3ee..af0167a 100644 --- a/DDrawCompat/Direct3d/Hooks.cpp +++ b/DDrawCompat/Direct3d/Hooks.cpp @@ -1,17 +1,21 @@ #include -#include "Common/CompatRef.h" -#include "Common/Log.h" -#include "Direct3d/Direct3d.h" -#include "Direct3d/Direct3dDevice.h" -#include "Direct3d/Direct3dTexture.h" -#include "Direct3d/Direct3dVertexBuffer.h" -#include "Direct3d/Direct3dViewport.h" -#include "Direct3d/Hooks.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace { void hookDirect3dDevice(CompatRef d3d, CompatRef renderTarget); + void hookDirect3dLight(CompatRef d3d); + void hookDirect3dMaterial(CompatRef d3d); void hookDirect3dTexture(CompatRef dd); void hookDirect3dVertexBuffer(CompatRef d3d); void hookDirect3dVertexBuffer7(CompatRef d3d); @@ -70,6 +74,8 @@ namespace hookVtable(d3d); hookVtable(d3d); hookDirect3dDevice(*d3d, renderTarget); + hookDirect3dLight(*d3d); + hookDirect3dMaterial(*d3d); hookDirect3dTexture(dd); hookDirect3dVertexBuffer(*d3d); hookDirect3dViewport(*d3d); @@ -102,6 +108,34 @@ namespace hookVtable(d3dDevice); } + void hookDirect3dLight(CompatRef d3d) + { + CompatPtr light; + HRESULT result = d3d->CreateLight(&d3d, &light.getRef(), nullptr); + if (FAILED(result)) + { + Compat::Log() << "ERROR: Failed to create a light for hooking: " << Compat::hex(result); + return; + } + + hookVtable(light); + } + + void hookDirect3dMaterial(CompatRef d3d) + { + CompatPtr material; + HRESULT result = d3d->CreateMaterial(&d3d, &material.getRef(), nullptr); + if (FAILED(result)) + { + Compat::Log() << "ERROR: Failed to create a material for hooking: " << Compat::hex(result); + return; + } + + hookVtable(material); + hookVtable(material); + hookVtable(material); + } + void hookDirect3dTexture(CompatRef dd) { DDSURFACEDESC desc = {}; diff --git a/DDrawCompat/Direct3d/Log.cpp b/DDrawCompat/Direct3d/Log.cpp index 6029d48..4ab0e25 100644 --- a/DDrawCompat/Direct3d/Log.cpp +++ b/DDrawCompat/Direct3d/Log.cpp @@ -1,5 +1,14 @@ #include +std::ostream& operator<<(std::ostream& os, const D3DCOLORVALUE& data) +{ + return Compat::LogStruct(os) + << data.r + << data.g + << data.b + << data.a; +} + std::ostream& operator<<(std::ostream& os, const D3DDP_PTRSTRIDE& data) { return Compat::LogStruct(os) @@ -17,6 +26,67 @@ std::ostream& operator<<(std::ostream& os, const D3DDRAWPRIMITIVESTRIDEDDATA& da << Compat::array(data.textureCoords, D3DDP_MAXTEXCOORD); } +std::ostream& operator<<(std::ostream& os, const D3DLIGHT& data) +{ + D3DLIGHT2 light = {}; + reinterpret_cast(light) = data; + return os << light; +} + +std::ostream& operator<<(std::ostream& os, const D3DLIGHT2& data) +{ + return Compat::LogStruct(os) + << data.dltType + << data.dcvColor + << data.dvPosition + << data.dvDirection + << data.dvRange + << data.dvFalloff + << data.dvAttenuation0 + << data.dvAttenuation1 + << data.dvAttenuation2 + << data.dvTheta + << data.dvPhi + << Compat::hex(data.dwFlags); +} + +std::ostream& operator<<(std::ostream& os, const D3DLIGHT7& data) +{ + return Compat::LogStruct(os) + << data.dltType + << data.dcvDiffuse + << data.dcvSpecular + << data.dcvAmbient + << data.dvPosition + << data.dvDirection + << data.dvRange + << data.dvFalloff + << data.dvAttenuation0 + << data.dvAttenuation1 + << data.dvAttenuation2 + << data.dvTheta + << data.dvPhi; +} + +std::ostream& operator<<(std::ostream& os, const D3DMATERIAL& data) +{ + return Compat::LogStruct(os) + << data.diffuse + << data.ambient + << data.specular + << data.emissive + << data.power + << Compat::hex(data.hTexture) + << data.dwRampSize; +} + +std::ostream& operator<<(std::ostream& os, const D3DMATERIAL7& data) +{ + D3DMATERIAL material = {}; + reinterpret_cast(material) = data; + return os << material; +} + std::ostream& operator<<(std::ostream& os, const D3DVERTEXBUFFERDESC& data) { return Compat::LogStruct(os) diff --git a/DDrawCompat/Direct3d/Log.h b/DDrawCompat/Direct3d/Log.h index fb8eddc..f0ed0a5 100644 --- a/DDrawCompat/Direct3d/Log.h +++ b/DDrawCompat/Direct3d/Log.h @@ -4,6 +4,12 @@ #include +std::ostream& operator<<(std::ostream& os, const D3DCOLORVALUE& data); std::ostream& operator<<(std::ostream& os, const D3DDP_PTRSTRIDE& data); std::ostream& operator<<(std::ostream& os, const D3DDRAWPRIMITIVESTRIDEDDATA& data); +std::ostream& operator<<(std::ostream& os, const D3DLIGHT& data); +std::ostream& operator<<(std::ostream& os, const D3DLIGHT2& data); +std::ostream& operator<<(std::ostream& os, const D3DLIGHT7& data); +std::ostream& operator<<(std::ostream& os, const D3DMATERIAL& data); +std::ostream& operator<<(std::ostream& os, const D3DMATERIAL7& data); std::ostream& operator<<(std::ostream& os, const D3DVERTEXBUFFERDESC& data); diff --git a/DDrawCompat/Direct3d/Visitors/Direct3dLightVtblVisitor.h b/DDrawCompat/Direct3d/Visitors/Direct3dLightVtblVisitor.h new file mode 100644 index 0000000..3cb5020 --- /dev/null +++ b/DDrawCompat/Direct3d/Visitors/Direct3dLightVtblVisitor.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include + +template <> +struct VtableForEach +{ + template + static void forEach(Visitor& visitor) + { + VtableForEach::forEach(visitor); + + DD_VISIT(Initialize); + DD_VISIT(SetLight); + DD_VISIT(GetLight); + } +}; diff --git a/DDrawCompat/Direct3d/Visitors/Direct3dMaterialVtblVisitor.h b/DDrawCompat/Direct3d/Visitors/Direct3dMaterialVtblVisitor.h new file mode 100644 index 0000000..ffe0de0 --- /dev/null +++ b/DDrawCompat/Direct3d/Visitors/Direct3dMaterialVtblVisitor.h @@ -0,0 +1,46 @@ +#pragma once + +#include + +#include + +template <> +struct VtableForEach +{ + template + static void forEach(Visitor& visitor) + { + VtableForEach::forEach(visitor); + + DD_VISIT(Initialize); + DD_VISIT(SetMaterial); + DD_VISIT(GetMaterial); + DD_VISIT(GetHandle); + DD_VISIT(Reserve); + DD_VISIT(Unreserve); + } +}; + +template <> +struct VtableForEach +{ + template + static void forEach(Visitor& visitor) + { + VtableForEach::forEach(visitor); + + DD_VISIT(SetMaterial); + DD_VISIT(GetMaterial); + DD_VISIT(GetHandle); + } +}; + +template <> +struct VtableForEach +{ + template + static void forEach(Visitor& visitor) + { + VtableForEach::forEach(visitor); + } +};