From d18df5faf16b41c7bd8ec054f05ccddf4cb113bf Mon Sep 17 00:00:00 2001
From: FunkyFr3sh <cc.red.alert.1@googlemail.com>
Date: Wed, 21 Sep 2022 16:07:32 +0200
Subject: [PATCH] #172 Add support for SetSurfaceDesc  (Nancy Drew: Stay Tuned
 For Danger)

---
 inc/ddsurface.h                      |  1 +
 src/IDirectDraw/IDirectDrawSurface.c |  6 +--
 src/ddsurface.c                      | 73 ++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/inc/ddsurface.h b/inc/ddsurface.h
index f641118..b27bf4f 100644
--- a/inc/ddsurface.h
+++ b/inc/ddsurface.h
@@ -31,6 +31,7 @@ HRESULT dds_SetColorKey(IDirectDrawSurfaceImpl* This, DWORD dwFlags, LPDDCOLORKE
 HRESULT dds_SetPalette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* lpDDPalette);
 HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect);
 HRESULT dds_GetDDInterface(IDirectDrawSurfaceImpl* This, LPVOID* lplpDD);
+HRESULT dds__SetSurfaceDesc(IDirectDrawSurfaceImpl* This, LPDDSURFACEDESC2 lpDDSD, DWORD dwFlags);
 void* dds_GetBuffer(IDirectDrawSurfaceImpl* This);
 HRESULT dd_CreateSurface(IDirectDrawImpl* This, LPDDSURFACEDESC lpDDSurfaceDesc, IDirectDrawSurfaceImpl** lpDDSurface, IUnknown FAR* unkOuter);
 
diff --git a/src/IDirectDraw/IDirectDrawSurface.c b/src/IDirectDraw/IDirectDrawSurface.c
index 30f6f6a..7829280 100644
--- a/src/IDirectDraw/IDirectDrawSurface.c
+++ b/src/IDirectDraw/IDirectDrawSurface.c
@@ -501,9 +501,9 @@ HRESULT __stdcall IDirectDrawSurface__PageUnlock(IDirectDrawSurfaceImpl* This, D
 
 HRESULT __stdcall IDirectDrawSurface__SetSurfaceDesc(IDirectDrawSurfaceImpl* This, LPDDSURFACEDESC2 lpDDSD, DWORD dwFlags)
 {
-    TRACE("NOT_IMPLEMENTED -> %s(This=%p)\n", __FUNCTION__, This);
-    HRESULT ret = DDERR_UNSUPPORTED;
-    TRACE("NOT_IMPLEMENTED <- %s\n", __FUNCTION__);
+    TRACE("-> %s(This=%p, lpDDSD=%p, dwFlags=%08X)\n", __FUNCTION__, This, lpDDSD, dwFlags);
+    HRESULT ret = dds__SetSurfaceDesc(This, lpDDSD, dwFlags);
+    TRACE("<- %s\n", __FUNCTION__);
     return ret;
 }
 
diff --git a/src/ddsurface.c b/src/ddsurface.c
index 7fdbf26..10fa487 100644
--- a/src/ddsurface.c
+++ b/src/ddsurface.c
@@ -962,6 +962,79 @@ HRESULT dds_GetDDInterface(IDirectDrawSurfaceImpl* This, LPVOID* lplpDD)
     return DD_OK;
 }
 
+HRESULT dds__SetSurfaceDesc(IDirectDrawSurfaceImpl* This, LPDDSURFACEDESC2 lpDDSD, DWORD dwFlags)
+{
+    dbg_dump_dds_flags(lpDDSD->dwFlags);
+    dbg_dump_dds_caps(lpDDSD->ddsCaps.dwCaps);
+
+    DWORD req_flags = DDSD_LPSURFACE | DDSD_PITCH | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
+
+    if ((lpDDSD->dwFlags & req_flags) != req_flags)
+        return DDERR_UNSUPPORTED;
+
+
+    if (This->bitmap)
+    {
+        DeleteObject(This->bitmap);
+        This->bitmap = NULL;
+    }
+    else if (This->surface && !This->custom_surface)
+    {
+        HeapFree(GetProcessHeap(), 0, This->surface);
+        This->surface = NULL;
+    }
+
+    if (This->hdc)
+    {
+        DeleteDC(This->hdc);
+        This->hdc = NULL;
+    }
+
+    if (This->bmi)
+    {
+        HeapFree(GetProcessHeap(), 0, This->bmi);
+        This->bmi = NULL;
+    }
+
+    if (This->surface_mapping)
+    {
+        CloseHandle(This->surface_mapping);
+        This->surface_mapping = NULL;
+    }
+
+
+    switch (lpDDSD->ddpfPixelFormat.dwRGBBitCount)
+    {
+    case 8:
+        This->bpp = 8;
+        break;
+    case 15:
+        TRACE("     NOT_IMPLEMENTED bpp=%u\n", lpDDSD->ddpfPixelFormat.dwRGBBitCount);
+    case 16:
+        This->bpp = 16;
+        break;
+    case 24:
+        TRACE("     NOT_IMPLEMENTED bpp=%u\n", lpDDSD->ddpfPixelFormat.dwRGBBitCount);
+    case 32:
+        This->bpp = 32;
+        break;
+    default:
+        This->bpp = 8;
+        TRACE("     NOT_IMPLEMENTED bpp=%u\n", lpDDSD->ddpfPixelFormat.dwRGBBitCount);
+        break;
+    }
+
+    This->width = lpDDSD->dwWidth;
+    This->height = lpDDSD->dwHeight;
+    This->surface = lpDDSD->lpSurface;
+    This->l_pitch = lpDDSD->lPitch;
+    This->lx_pitch = This->bpp / 8;
+    This->size = This->l_pitch * This->height;
+    This->custom_surface = TRUE;
+
+    return DD_OK;
+}
+
 void* dds_GetBuffer(IDirectDrawSurfaceImpl* This)
 {
     if (!This)