From c0a26ce858c73ae510283154cd3e99a48c1b6f8f Mon Sep 17 00:00:00 2001
From: FunkyFr3sh <cc.red.alert.1@googlemail.com>
Date: Wed, 3 Oct 2018 08:50:00 +0200
Subject: [PATCH] enables fullscreen exclusive mode for d3d9

---
 inc/main.h        |  1 +
 src/debug.c       |  4 ++--
 src/main.c        |  2 ++
 src/render_d3d9.c | 57 +++++++++++++++++++++++++++++++++--------------
 4 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/inc/main.h b/inc/main.h
index ea5b624..1a050b4 100644
--- a/inc/main.h
+++ b/inc/main.h
@@ -98,6 +98,7 @@ typedef struct IDirectDrawImpl
     char shader[MAX_PATH];
     BOOL wine;
     int sleep;
+    BOOL resetDirect3D9;
     
 } IDirectDrawImpl;
 
diff --git a/src/debug.c b/src/debug.c
index f17e55d..3dde17c 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -52,11 +52,11 @@ void DrawFrameInfoStart()
             debugText,
             sizeof(debugText),
             "FPS: %lu | Time: %2.2f ms  ",
-            DebugFrameCount,
+            DebugFrameCount * 2,
             DebugFrameTime);
 
         DebugFrameCount = 0;
-        tick_fps = tick_start + 1000;
+        tick_fps = tick_start + 500;
 
         CounterStart();
     }
diff --git a/src/main.c b/src/main.c
index 2401d74..1c61bd4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -606,6 +606,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
                 if (!ddraw->windowed)
                 {
                     ChangeDisplaySettings(&ddraw->render.mode, CDS_FULLSCREEN);
+                    InterlockedExchange(&ddraw->resetDirect3D9, TRUE);
 
                     if (wParam == WA_ACTIVE)
                     {
@@ -625,6 +626,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
                 {
                     ShowWindow(ddraw->hWnd, SW_MINIMIZE);
                     ChangeDisplaySettings(&ddraw->mode, 0);
+                    InterlockedExchange(&ddraw->resetDirect3D9, TRUE);
                 }
             }
             return 0;
diff --git a/src/render_d3d9.c b/src/render_d3d9.c
index 92fe259..362608d 100644
--- a/src/render_d3d9.c
+++ b/src/render_d3d9.c
@@ -27,7 +27,7 @@ static void UpdateVertices(BOOL inCutscene);
 static BOOL Reset();
 static void SetMaxFPS(int baseMaxFPS);
 static void Render();
-static void ReleaseDirect3D();
+static BOOL ReleaseDirect3D();
 
 BOOL detect_cutscene();
 DWORD WINAPI render_soft_main(void);
@@ -59,14 +59,12 @@ DWORD WINAPI render_d3d9_main(void)
 
 static BOOL CreateDirect3D()
 {
-    D3d = NULL;
-    D3ddev = NULL;
-    SurfaceTex = NULL;
-    PaletteTex = NULL;
-    D3dvb = NULL;
-    PixelShader = NULL;
+    if (!ReleaseDirect3D())
+        return FALSE;
+
+    if (!hD3D9)
+        hD3D9 = LoadLibrary("d3d9.dll");
 
-    hD3D9 = LoadLibrary("d3d9.dll");
     if (hD3D9)
     {
         IDirect3D9 *(WINAPI *D3DCreate9)(UINT) =
@@ -74,7 +72,7 @@ static BOOL CreateDirect3D()
 
         if (D3DCreate9 && (D3d = D3DCreate9(D3D_SDK_VERSION)))
         {
-            D3dpp.Windowed = TRUE;
+            D3dpp.Windowed = ddraw->windowed;
             D3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
             D3dpp.hDeviceWindow = ddraw->hWnd;
             D3dpp.PresentationInterval = ddraw->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
@@ -99,7 +97,7 @@ static BOOL CreateDirect3D()
                     D3DADAPTER_DEFAULT,
                     D3DDEVTYPE_HAL,
                     ddraw->hWnd,
-                    D3DCREATE_NOWINDOWCHANGES | behaviorFlags[i],
+                    D3DCREATE_MULTITHREADED | D3DCREATE_NOWINDOWCHANGES | behaviorFlags[i],
                     &D3dpp,
                     &D3ddev)))
                     break;
@@ -281,7 +279,11 @@ static void Render()
 
         HRESULT hr = D3ddev->lpVtbl->TestCooperativeLevel(D3ddev);
 
-        if (hr == D3DERR_DEVICENOTRESET)
+        if (InterlockedExchange(&ddraw->resetDirect3D9, FALSE))
+        {
+            Reset();
+        }
+        else if (hr == D3DERR_DEVICENOTRESET && D3dpp.Windowed)
         {
             Reset();
         }
@@ -308,26 +310,47 @@ static void Render()
     }
 }
 
-static void ReleaseDirect3D()
+static BOOL ReleaseDirect3D()
 {
     if (D3dvb)
+    {
         D3dvb->lpVtbl->Release(D3dvb);
-
+        D3dvb = NULL;
+    }
+        
     if (SurfaceTex)
+    {
         SurfaceTex->lpVtbl->Release(SurfaceTex);
+        SurfaceTex = NULL;
+    }
 
     if (PaletteTex)
+    {
         PaletteTex->lpVtbl->Release(PaletteTex);
+        PaletteTex = NULL;
+    }
 
     if (PixelShader)
+    {
         PixelShader->lpVtbl->Release(PixelShader);
+        PixelShader = NULL;
+    }
 
     if (D3ddev)
-        D3ddev->lpVtbl->Release(D3ddev);
+    {
+        if (FAILED(D3ddev->lpVtbl->Release(D3ddev)))
+            return FALSE;
+
+        D3ddev = NULL;
+    }
 
     if (D3d)
-        D3d->lpVtbl->Release(D3d);
+    {
+        if (FAILED(D3d->lpVtbl->Release(D3d)))
+            return FALSE;
 
-    if (hD3D9)
-        FreeLibrary(hD3D9);
+        D3d = NULL;
+    }
+
+    return TRUE;
 }