From b4961692439ef9293bc66bc8b7bf1dcae3efe3db Mon Sep 17 00:00:00 2001
From: FunkyFr3sh <cc.red.alert.1@googlemail.com>
Date: Wed, 14 Oct 2020 00:42:42 +0200
Subject: [PATCH] add dummy IDirect3D interface

---
 Makefile                      |  1 +
 cnc-ddraw.vcxproj             |  2 +
 cnc-ddraw.vcxproj.filters     |  9 ++++
 inc/IDirect3D.h               | 42 +++++++++++++++
 src/IDirect3D/IDirect3D.c     | 99 +++++++++++++++++++++++++++++++++++
 src/IDirectDraw/IDirectDraw.c | 29 ++++++++++
 6 files changed, 182 insertions(+)
 create mode 100644 inc/IDirect3D.h
 create mode 100644 src/IDirect3D/IDirect3D.c

diff --git a/Makefile b/Makefile
index 5805122..94bbaff 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,7 @@ FILES = src/debug.c \
         src/render_ogl.c \
         src/render_gdi.c \
         src/render_d3d9.c \
+        src/IDirect3D/IDirect3D.c \
         src/mouse.c \
         src/winapi_hooks.c \
         src/screenshot.c \
diff --git a/cnc-ddraw.vcxproj b/cnc-ddraw.vcxproj
index 06544f3..d770fe5 100644
--- a/cnc-ddraw.vcxproj
+++ b/cnc-ddraw.vcxproj
@@ -32,6 +32,7 @@
     </ClCompile>
     <ClCompile Include="src\directinput.c" />
     <ClCompile Include="src\dllmain.c" />
+    <ClCompile Include="src\IDirect3D\IDirect3D.c" />
     <ClCompile Include="src\utils.c" />
     <ClCompile Include="src\hook.c" />
     <ClCompile Include="src\IDirectDraw\IDirectDraw.c" />
@@ -58,6 +59,7 @@
     <ClInclude Include="inc\directinput.h" />
     <ClInclude Include="inc\dllmain.h" />
     <ClInclude Include="inc\glcorearb.h" />
+    <ClInclude Include="inc\IDirect3D.h" />
     <ClInclude Include="inc\utils.h" />
     <ClInclude Include="inc\hook.h" />
     <ClInclude Include="inc\IDirectDraw.h" />
diff --git a/cnc-ddraw.vcxproj.filters b/cnc-ddraw.vcxproj.filters
index 8f64818..c150b23 100644
--- a/cnc-ddraw.vcxproj.filters
+++ b/cnc-ddraw.vcxproj.filters
@@ -19,6 +19,9 @@
     <Filter Include="Source Files\IDirectDraw">
       <UniqueIdentifier>{37ee5b88-e57f-4c55-a43e-e475cf4e8920}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Source Files\IDirect3D">
+      <UniqueIdentifier>{e6c62066-0a71-4531-ad9a-eb428abc6f44}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\debug.c">
@@ -123,6 +126,9 @@
     <ClCompile Include="src\opengl_utils.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="src\IDirect3D\IDirect3D.c">
+      <Filter>Source Files\IDirect3D</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="inc\ddraw.h">
@@ -212,6 +218,9 @@
     <ClInclude Include="inc\opengl_utils.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="inc\IDirect3D.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="ddraw.rc">
diff --git a/inc/IDirect3D.h b/inc/IDirect3D.h
new file mode 100644
index 0000000..ae13919
--- /dev/null
+++ b/inc/IDirect3D.h
@@ -0,0 +1,42 @@
+#ifndef IDIRECTD3D_H 
+#define IDIRECTD3D_H
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+
+DEFINE_GUID(IID_IDirect3D, 0x3BBA0080, 0x2421, 0x11CF, 0xA3, 0x1A, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56);
+DEFINE_GUID(IID_IDirect3D2, 0x6aae1ec1, 0x662a, 0x11d0, 0x88, 0x9d, 0x00, 0xaa, 0x00, 0xbb, 0xb7, 0x6a);
+DEFINE_GUID(IID_IDirect3D3, 0xbb223240, 0xe72b, 0x11d0, 0xa9, 0xb4, 0x00, 0xaa, 0x00, 0xc0, 0x99, 0x3e);
+DEFINE_GUID(IID_IDirect3D7, 0xf5049e77, 0x4861, 0x11d2, 0xa4, 0x7, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0xa8);
+
+extern struct IDirect3DImplVtbl g_d3d_vtbl1;
+
+struct IDirect3DImpl;
+struct IDirect3DImplVtbl;
+
+typedef struct IDirect3DImpl
+{
+    struct IDirect3DImplVtbl* lpVtbl;
+
+    ULONG ref;
+
+} IDirect3DImpl;
+
+typedef struct IDirect3DImplVtbl IDirect3DImplVtbl;
+
+struct IDirect3DImplVtbl
+{
+    HRESULT(__stdcall* QueryInterface) (IDirect3DImpl*, const IID* const riid, LPVOID* ppvObj);
+    ULONG(__stdcall* AddRef) (IDirect3DImpl*);
+    ULONG(__stdcall* Release) (IDirect3DImpl*);
+
+    HRESULT(__stdcall* Initialize)(IDirect3DImpl*, int);
+    HRESULT(__stdcall* EnumDevices)(IDirect3DImpl*, int, int);
+    HRESULT(__stdcall* CreateLight)(IDirect3DImpl*, int, int);
+    HRESULT(__stdcall* CreateMaterial)(IDirect3DImpl*, int, int);
+    HRESULT(__stdcall* CreateViewport)(IDirect3DImpl*, int, int);
+    HRESULT(__stdcall* FindDevice)(IDirect3DImpl*, int, int);
+};
+
+#endif
diff --git a/src/IDirect3D/IDirect3D.c b/src/IDirect3D/IDirect3D.c
new file mode 100644
index 0000000..4fb0443
--- /dev/null
+++ b/src/IDirect3D/IDirect3D.c
@@ -0,0 +1,99 @@
+#include "IDirect3D.h"
+#include "debug.h"
+
+
+HRESULT __stdcall IDirect3D__QueryInterface(IDirect3DImpl* This, REFIID riid, void** obj)
+{
+    dprintf("NOT_IMPLEMENTED -> %s(This=%p, riid=%08X, obj=%p)\n", __FUNCTION__, This, (unsigned int)riid, obj);
+    HRESULT ret = E_FAIL;
+    dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+    return ret;
+}
+
+ULONG __stdcall IDirect3D__AddRef(IDirect3DImpl* This)
+{
+    dprintf("-> %s(This=%p)\n", __FUNCTION__, This);
+    ULONG ret = ++This->ref;
+    dprintf("<- %s(This ref=%u)\n", __FUNCTION__, ret);
+    return ret;
+}
+
+ULONG __stdcall IDirect3D__Release(IDirect3DImpl* This)
+{
+    dprintf("-> %s(This=%p)\n", __FUNCTION__, This);
+
+    ULONG ret = --This->ref;
+
+    if (This->ref == 0)
+    {
+        dprintf("     Released (%p)\n", This);
+
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    dprintf("<- %s(This ref=%u)\n", __FUNCTION__, ret);
+    return ret;
+}
+
+HRESULT __stdcall IDirect3D__Initialize(IDirect3DImpl* This, int a)
+{
+    dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+    HRESULT ret = E_FAIL;
+    dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+    return ret;
+}
+
+HRESULT __stdcall IDirect3D__EnumDevices(IDirect3DImpl* This, int a, int b)
+{
+    dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+    HRESULT ret = E_FAIL;
+    dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+    return ret;
+}
+
+HRESULT __stdcall IDirect3D__CreateLight(IDirect3DImpl* This, int a, int b)
+{
+    dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+    HRESULT ret = E_FAIL;
+    dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+    return ret;
+}
+
+HRESULT __stdcall IDirect3D__CreateMaterial(IDirect3DImpl* This, int a, int b)
+{
+    dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+    HRESULT ret = E_FAIL;
+    dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+    return ret;
+}
+
+HRESULT __stdcall IDirect3D__CreateViewport(IDirect3DImpl* This, int a, int b)
+{
+    dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+    HRESULT ret = E_FAIL;
+    dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+    return ret;
+}
+
+HRESULT __stdcall IDirect3D__FindDevice(IDirect3DImpl* This, int a, int b)
+{
+    dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+    HRESULT ret = E_FAIL;
+    dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+    return ret;
+}
+
+struct IDirect3DImplVtbl g_d3d_vtbl1 =
+{
+    /* IUnknown */
+    IDirect3D__QueryInterface,
+    IDirect3D__AddRef,
+    IDirect3D__Release,
+    /* IDirect3DImpl */
+    IDirect3D__Initialize,
+    IDirect3D__EnumDevices,
+    IDirect3D__CreateLight,
+    IDirect3D__CreateMaterial,
+    IDirect3D__CreateViewport,
+    IDirect3D__FindDevice,
+};
diff --git a/src/IDirectDraw/IDirectDraw.c b/src/IDirectDraw/IDirectDraw.c
index 6cc6acc..5fc92ab 100644
--- a/src/IDirectDraw/IDirectDraw.c
+++ b/src/IDirectDraw/IDirectDraw.c
@@ -1,5 +1,6 @@
 #include <initguid.h>
 #include "IDirectDraw.h"
+#include "IDirect3D.h"
 #include "dd.h"
 #include "ddclipper.h"
 #include "ddpalette.h"
@@ -28,6 +29,34 @@ HRESULT __stdcall IDirectDraw__QueryInterface(IDirectDrawImpl* This, REFIID riid
 
             ret = S_OK;
         }
+        else if (IsEqualGUID(&IID_IDirectDraw, riid))
+        {
+            dprintf("     GUID = %08X (IID_IDirectDraw)\n", ((GUID*)riid)->Data1);
+
+            IDirectDrawImpl* dd = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl));
+            dd->lpVtbl = &g_dd_vtbl1;
+
+            *obj = dd;
+            IDirectDraw_AddRef(dd);
+
+            ret = S_OK;
+        }
+        else if (IsEqualGUID(&IID_IDirect3D, riid))
+        {
+            dprintf("     GUID = %08X (IID_IDirect3D)\n", ((GUID*)riid)->Data1);
+
+            IDirect3DImpl* d3d = (IDirect3DImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl));
+            d3d->lpVtbl = &g_d3d_vtbl1;
+
+            *obj = d3d;
+            d3d->lpVtbl->AddRef(d3d);
+
+            ret = S_OK;
+        }
+        else if (IsEqualGUID(&IID_IDirect3D2, riid) || IsEqualGUID(&IID_IDirect3D3, riid) || IsEqualGUID(&IID_IDirect3D7, riid))
+        {
+            dprintf("     GUID = %08X (IID_IDirect3DX)\n", ((GUID*)riid)->Data1);
+        }
         else
         {
             dprintf("     GUID = %08X\n", ((GUID*)riid)->Data1);