diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj
index 5f7435f..07f24aa 100644
--- a/DDrawCompat/DDrawCompat.vcxproj
+++ b/DDrawCompat/DDrawCompat.vcxproj
@@ -197,11 +197,13 @@
+
+
@@ -247,6 +249,7 @@
+
diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters
index 17de3a4..467dcb5 100644
--- a/DDrawCompat/DDrawCompat.vcxproj.filters
+++ b/DDrawCompat/DDrawCompat.vcxproj.filters
@@ -270,6 +270,12 @@
Header Files\Direct3d
+
+ Header Files\Direct3d\Visitors
+
+
+ Header Files\Direct3d
+
@@ -407,6 +413,9 @@
Source Files\Direct3d
+
+ Source Files\Direct3d
+
diff --git a/DDrawCompat/Direct3d/Direct3dVertexBuffer.cpp b/DDrawCompat/Direct3d/Direct3dVertexBuffer.cpp
new file mode 100644
index 0000000..4b91f5f
--- /dev/null
+++ b/DDrawCompat/Direct3d/Direct3dVertexBuffer.cpp
@@ -0,0 +1,13 @@
+#include "Direct3d/Direct3dVertexBuffer.h"
+
+namespace Direct3d
+{
+ template
+ void Direct3dVertexBuffer::setCompatVtable(
+ Vtable& /*vtable*/)
+ {
+ }
+
+ template Direct3dVertexBuffer;
+ template Direct3dVertexBuffer;
+}
diff --git a/DDrawCompat/Direct3d/Direct3dVertexBuffer.h b/DDrawCompat/Direct3d/Direct3dVertexBuffer.h
new file mode 100644
index 0000000..c564ca2
--- /dev/null
+++ b/DDrawCompat/Direct3d/Direct3dVertexBuffer.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "Common/CompatVtable.h"
+#include "Direct3d/Visitors/Direct3dVertexBufferVtblVisitor.h"
+
+namespace Direct3d
+{
+ template
+ class Direct3dVertexBuffer : public CompatVtable>
+ {
+ public:
+ static void setCompatVtable(Vtable& vtable);
+ };
+}
+
+SET_COMPAT_VTABLE(IDirect3DVertexBufferVtbl, Direct3d::Direct3dVertexBuffer);
+SET_COMPAT_VTABLE(IDirect3DVertexBuffer7Vtbl, Direct3d::Direct3dVertexBuffer);
diff --git a/DDrawCompat/Direct3d/Hooks.cpp b/DDrawCompat/Direct3d/Hooks.cpp
index f15d522..a17a1d2 100644
--- a/DDrawCompat/Direct3d/Hooks.cpp
+++ b/DDrawCompat/Direct3d/Hooks.cpp
@@ -1,5 +1,7 @@
#define CINTERFACE
+#include
+
#include
#include "Common/CompatPtr.h"
@@ -9,6 +11,7 @@
#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 "Dll/Procs.h"
@@ -18,8 +21,14 @@ namespace
void hookDirect3dDevice(CompatRef d3d, CompatRef renderTarget);
void hookDirect3dDevice7(CompatRef d3d, CompatRef renderTarget);
void hookDirect3dTexture(CompatRef dd);
+ void hookDirect3dVertexBuffer(CompatRef d3d);
+ void hookDirect3dVertexBuffer7(CompatRef d3d);
void hookDirect3dViewport(CompatRef d3d);
+ template
+ void hookVertexBuffer(
+ const std::function createVertexBuffer);
+
template
void hookVtable(const CompatPtr& intf);
@@ -64,7 +73,7 @@ namespace
desc.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
desc.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
desc.ddpfPixelFormat.dwBBitMask = 0x000000FF;
- desc.ddsCaps.dwCaps = DDSCAPS_3DDEVICE;
+ desc.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_SYSTEMMEMORY;
CompatPtr renderTarget;
HRESULT result = dd->CreateSurface(&dd, &desc, &renderTarget.getRef(), nullptr);
@@ -85,6 +94,7 @@ namespace
hookVtable(d3d);
hookDirect3dDevice(*d3d, renderTarget);
hookDirect3dTexture(dd);
+ hookDirect3dVertexBuffer(*d3d);
hookDirect3dViewport(*d3d);
}
}
@@ -96,6 +106,7 @@ namespace
{
hookVtable(d3d);
hookDirect3dDevice7(*d3d, renderTarget);
+ hookDirect3dVertexBuffer7(*d3d);
}
}
@@ -138,6 +149,20 @@ namespace
hookVtable(texture);
}
+ void hookDirect3dVertexBuffer(CompatRef d3d)
+ {
+ hookVertexBuffer(
+ [&](D3DVERTEXBUFFERDESC& desc, IDirect3DVertexBuffer*& vb) {
+ return d3d->CreateVertexBuffer(&d3d, &desc, &vb, 0, nullptr); });
+ }
+
+ void hookDirect3dVertexBuffer7(CompatRef d3d)
+ {
+ hookVertexBuffer(
+ [&](D3DVERTEXBUFFERDESC& desc, IDirect3DVertexBuffer7*& vb) {
+ return d3d->CreateVertexBuffer(&d3d, &desc, &vb, 0); });
+ }
+
void hookDirect3dViewport(CompatRef d3d)
{
CompatPtr viewport;
@@ -153,6 +178,26 @@ namespace
hookVtable(viewport);
}
+ template
+ void hookVertexBuffer(
+ const std::function createVertexBuffer)
+ {
+ D3DVERTEXBUFFERDESC desc = {};
+ desc.dwSize = sizeof(desc);
+ desc.dwCaps = D3DVBCAPS_SYSTEMMEMORY;
+ desc.dwFVF = D3DFVF_VERTEX;
+ desc.dwNumVertices = 1;
+
+ CompatPtr vertexBuffer = nullptr;
+ HRESULT result = createVertexBuffer(desc, vertexBuffer.getRef());
+ if (FAILED(result))
+ {
+ Compat::Log() << "Failed to create a vertex buffer for hooking: " << result;
+ }
+
+ hookVtable(vertexBuffer);
+ }
+
template
void hookVtable(const CompatPtr& intf)
{
diff --git a/DDrawCompat/Direct3d/Visitors/Direct3dVertexBufferVtblVisitor.h b/DDrawCompat/Direct3d/Visitors/Direct3dVertexBufferVtblVisitor.h
new file mode 100644
index 0000000..8f72c2c
--- /dev/null
+++ b/DDrawCompat/Direct3d/Visitors/Direct3dVertexBufferVtblVisitor.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#define CINTERFACE
+
+#include
+
+#include "Common/VtableVisitor.h"
+
+template <>
+struct VtableForEach
+{
+ template
+ static void forEach(Visitor& visitor)
+ {
+ VtableForEach::forEach(visitor);
+
+ DD_VISIT(Lock);
+ DD_VISIT(Unlock);
+ DD_VISIT(ProcessVertices);
+ DD_VISIT(GetVertexBufferDesc);
+ DD_VISIT(Optimize);
+ }
+};
+
+template <>
+struct VtableForEach
+{
+ template
+ static void forEach(Visitor& visitor)
+ {
+ VtableForEach::forEach(visitor);
+
+ DD_VISIT(ProcessVerticesStrided);
+ }
+};