From a6a95ec936064253bc780431b6e79fe74a6d90b8 Mon Sep 17 00:00:00 2001
From: FunkyFr3sh <cc.red.alert.1@googlemail.com>
Date: Sat, 9 Jan 2021 19:51:26 +0100
Subject: [PATCH] add dummy IDirectDrawGammaControl

---
 cnc-ddraw.vcxproj                         |  2 +
 cnc-ddraw.vcxproj.filters                 |  6 +++
 inc/IDirectDrawGammaControl.h             | 38 ++++++++++++++
 src/IDirectDraw/IDirectDrawGammaControl.c | 62 +++++++++++++++++++++++
 src/IDirectDraw/IDirectDrawSurface.c      | 34 +++++++++++--
 src/ddsurface.c                           |  3 ++
 6 files changed, 140 insertions(+), 5 deletions(-)
 create mode 100644 inc/IDirectDrawGammaControl.h
 create mode 100644 src/IDirectDraw/IDirectDrawGammaControl.c

diff --git a/cnc-ddraw.vcxproj b/cnc-ddraw.vcxproj
index f24d77d..d58bc6c 100644
--- a/cnc-ddraw.vcxproj
+++ b/cnc-ddraw.vcxproj
@@ -37,6 +37,7 @@
     <ClCompile Include="src\IDirect3D\IDirect3D3.c" />
     <ClCompile Include="src\IDirect3D\IDirect3D7.c" />
     <ClCompile Include="src\IAMMediaStream\IAMMediaStream.c" />
+    <ClCompile Include="src\IDirectDraw\IDirectDrawGammaControl.c" />
     <ClCompile Include="src\utils.c" />
     <ClCompile Include="src\hook.c" />
     <ClCompile Include="src\IDirectDraw\IDirectDraw.c" />
@@ -65,6 +66,7 @@
     <ClInclude Include="inc\glcorearb.h" />
     <ClInclude Include="inc\IDirect3D.h" />
     <ClInclude Include="inc\IAMMediaStream.h" />
+    <ClInclude Include="inc\IDirectDrawGammaControl.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 58df40d..5aef37b 100644
--- a/cnc-ddraw.vcxproj.filters
+++ b/cnc-ddraw.vcxproj.filters
@@ -144,6 +144,9 @@
     <ClCompile Include="src\IAMMediaStream\IAMMediaStream.c">
       <Filter>Source Files\IAMMediaStream</Filter>
     </ClCompile>
+    <ClCompile Include="src\IDirectDraw\IDirectDrawGammaControl.c">
+      <Filter>Source Files\IDirectDraw</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="inc\ddraw.h">
@@ -242,6 +245,9 @@
     <ClInclude Include="inc\wglext.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="inc\IDirectDrawGammaControl.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="ddraw.rc">
diff --git a/inc/IDirectDrawGammaControl.h b/inc/IDirectDrawGammaControl.h
new file mode 100644
index 0000000..12fbdde
--- /dev/null
+++ b/inc/IDirectDrawGammaControl.h
@@ -0,0 +1,38 @@
+#ifndef IDIRECTDRAWGAMMACONTROL_H
+#define IDIRECTDRAWGAMMACONTROL_H
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include "ddraw.h"
+
+
+DEFINE_GUID(IID_IDirectDrawGammaControl, 0x69C11C3E, 0xB46B, 0x11D1, 0xAD, 0x7A, 0x00, 0xC0, 0x4F, 0xC2, 0x9B, 0x4E);
+
+struct IDirectDrawGammaControlImpl;
+struct IDirectDrawGammaControlImplVtbl;
+
+typedef struct IDirectDrawGammaControlImpl
+{
+    struct IDirectDrawGammaControlImplVtbl *lpVtbl;
+
+    ULONG ref;
+
+} IDirectDrawGammaControlImpl;
+
+typedef struct IDirectDrawGammaControlImplVtbl IDirectDrawGammaControlImplVtbl;
+
+struct IDirectDrawGammaControlImplVtbl
+{
+    /* IUnknown */
+    HRESULT (__stdcall *QueryInterface)(IDirectDrawGammaControlImpl *, REFIID, void **);
+    ULONG (__stdcall *AddRef)(IDirectDrawGammaControlImpl *);
+    ULONG (__stdcall *Release)(IDirectDrawGammaControlImpl *);
+
+    /* IDirectDrawGammaControl */
+    HRESULT(__stdcall* GetGammaRamp)(IDirectDrawGammaControlImpl*, DWORD, void*);
+    HRESULT(__stdcall* SetGammaRamp)(IDirectDrawGammaControlImpl*, DWORD, void*);
+};
+
+extern struct IDirectDrawGammaControlImplVtbl g_ddgc_vtbl;
+
+#endif
diff --git a/src/IDirectDraw/IDirectDrawGammaControl.c b/src/IDirectDraw/IDirectDrawGammaControl.c
new file mode 100644
index 0000000..54767fd
--- /dev/null
+++ b/src/IDirectDraw/IDirectDrawGammaControl.c
@@ -0,0 +1,62 @@
+#include "IDirectDrawGammaControl.h"
+#include "debug.h"
+
+HRESULT __stdcall IDirectDrawGammaControl__QueryInterface(IDirectDrawGammaControlImpl *This, REFIID riid, void **obj)
+{
+    dprintf("NOT_IMPLEMENTED -> %s(This=%p, riid=%08X, obj=%p)\n", __FUNCTION__, This, (unsigned int)riid, obj);
+    HRESULT ret = S_OK;
+    dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+    return ret;
+}
+
+ULONG __stdcall IDirectDrawGammaControl__AddRef(IDirectDrawGammaControlImpl *This)
+{
+    dprintf("-> %s(This=%p)\n", __FUNCTION__, This);
+    ULONG ret = ++This->ref;
+    dprintf("<- %s(This ref=%u)\n", __FUNCTION__, ret);
+    return ret;
+}
+
+ULONG __stdcall IDirectDrawGammaControl__Release(IDirectDrawGammaControlImpl *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 IDirectDrawGammaControl__GetGammaRamp(IDirectDrawGammaControlImpl *This, DWORD dwFlags, void *lpRampData)
+{
+    dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+    HRESULT ret = DDERR_EXCEPTION;
+    dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+    return ret;
+}
+
+HRESULT __stdcall IDirectDrawGammaControl__SetGammaRamp(IDirectDrawGammaControlImpl *This, DWORD dwFlags, void *lpRampData)
+{
+    dprintf("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
+    HRESULT ret = DDERR_EXCEPTION;
+    dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+    return ret;
+}
+
+struct IDirectDrawGammaControlImplVtbl g_ddgc_vtbl =
+{
+    /* IUnknown */
+    IDirectDrawGammaControl__QueryInterface,
+    IDirectDrawGammaControl__AddRef,
+    IDirectDrawGammaControl__Release,
+    /* IDirectDrawGammaControl */
+    IDirectDrawGammaControl__GetGammaRamp,
+    IDirectDrawGammaControl__SetGammaRamp,
+};
diff --git a/src/IDirectDraw/IDirectDrawSurface.c b/src/IDirectDraw/IDirectDrawSurface.c
index bcc3f83..1a6d008 100644
--- a/src/IDirectDraw/IDirectDrawSurface.c
+++ b/src/IDirectDraw/IDirectDrawSurface.c
@@ -1,4 +1,6 @@
+#include <initguid.h>
 #include "IDirectDrawSurface.h"
+#include "IDirectDrawGammaControl.h"
 #include "ddsurface.h"
 #include "dd.h"
 #include "debug.h"
@@ -9,15 +11,37 @@ HRESULT __stdcall IDirectDrawSurface__QueryInterface(IDirectDrawSurfaceImpl *Thi
     dprintf("NOT_IMPLEMENTED -> %s(This=%p, riid=%08X, obj=%p)\n", __FUNCTION__, This, (unsigned int)riid, obj);
     HRESULT ret = S_OK;
 
-    if (riid && !IsEqualGUID(&IID_IDirectDrawSurface, riid))
+    if (riid)
     {
-        dprintf("     GUID = %08X\n", ((GUID *)riid)->Data1);
+        if (IsEqualGUID(&IID_IDirectDrawGammaControl, riid))
+        {
+            IDirectDrawGammaControlImpl* gc = (IDirectDrawGammaControlImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawGammaControlImpl));
 
-        IDirectDrawSurface_AddRef(This);
+            dprintf("     GUID = %08X (IID_IDirectDrawGammaControl), gammacontrol = %p\n", ((GUID*)riid)->Data1, gc);
+
+            gc->lpVtbl = &g_ddgc_vtbl;
+            gc->lpVtbl->AddRef(gc);
+
+            *obj = gc;
+
+            ret = S_OK;
+        }
+        else if (!IsEqualGUID(&IID_IDirectDrawSurface, riid))
+        {
+            dprintf("     GUID = %08X\n", ((GUID*)riid)->Data1);
+
+            IDirectDrawSurface_AddRef(This);
+
+            *obj = This;
+        }
+        else
+        {
+            dprintf("     GUID = %08X\n", ((GUID*)riid)->Data1);
+
+            *obj = This;
+        }
     }
 
-    *obj = This;
-
     dprintf("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
     return ret;
 }
diff --git a/src/ddsurface.c b/src/ddsurface.c
index 370a06e..aef009e 100644
--- a/src/ddsurface.c
+++ b/src/ddsurface.c
@@ -709,6 +709,9 @@ HRESULT dds_SetColorKey(IDirectDrawSurfaceImpl *This, DWORD flags, LPDDCOLORKEY
 
 HRESULT dds_SetPalette(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWPALETTE lpDDPalette)
 {
+    if (!lpDDPalette)
+        return DDERR_INVALIDPARAMS;
+
     IDirectDrawPalette_AddRef(lpDDPalette);
 
     if (This->palette)