From f5698f2d0bf4a7f4855c4e20dbacb0c2488d972d Mon Sep 17 00:00:00 2001
From: FunkyFr3sh <cc.red.alert.1@googlemail.com>
Date: Thu, 23 Aug 2018 00:57:31 +0200
Subject: [PATCH] fix gdi palette bug + refactoring

---
 inc/main.h        |  2 +-
 src/main.c        | 15 ++------
 src/mouse.c       |  2 +-
 src/render.c      | 24 ++++++-------
 src/render_soft.c | 91 ++++++++++++++++++++++++++---------------------
 src/surface.c     |  5 +++
 6 files changed, 70 insertions(+), 69 deletions(-)

diff --git a/inc/main.h b/inc/main.h
index c6fede3..b91ea4a 100644
--- a/inc/main.h
+++ b/inc/main.h
@@ -88,7 +88,7 @@ typedef struct IDirectDrawImpl
     BOOL vhack;
 	BOOL isredalert;
 	BOOL iscnc1;
-	BOOL incutscene;
+    LONG incutscene;
     DWORD (WINAPI *renderer)(void);
     char screenshotKey;
     BOOL fullscreen;
diff --git a/src/main.c b/src/main.c
index 5aae358..16bddce 100644
--- a/src/main.c
+++ b/src/main.c
@@ -842,13 +842,8 @@ HRESULT __stdcall ddraw_SetCooperativeLevel(IDirectDrawImpl *This, HWND hWnd, DW
     ddraw->isredalert = strcmp(This->title, "Red Alert") == 0;
     ddraw->iscnc1 = strcmp(This->title, "Command & Conquer") == 0;
     
-    if(This->vhack == 1)
-    {
-        if (!ddraw->isredalert && !ddraw->iscnc1)
-        {
-            This->vhack = 0;
-        }
-    }
+    if (This->vhack && !ddraw->isredalert && !ddraw->iscnc1)
+        This->vhack = 0;
 
     return DD_OK;
 }
@@ -1195,11 +1190,7 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk
     }
     
     GetPrivateProfileStringA("ddraw", "vhack", "false", tmp, sizeof(tmp), SettingsIniPath);
-    if (tolower(tmp[0]) == 'y' || tolower(tmp[0]) == 't' || tolower(tmp[0]) == 'e' || tmp[0] == '1')
-    {
-        This->vhack = 2;
-    }
-    else if(tolower(tmp[0]) == 'a')
+    if (tolower(tmp[0]) == 'y' || tolower(tmp[0]) == 't' || tolower(tmp[0]) == 'e' || tolower(tmp[0]) == 'a' || tmp[0] == '1')
     {
         This->vhack = 1;
     }
diff --git a/src/mouse.c b/src/mouse.c
index 6b336eb..53675e9 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -82,7 +82,7 @@ BOOL WINAPI fake_GetCursorPos(LPPOINT lpPoint)
             ddraw->cursor.y = pt.y;
         }
 
-        if (ddraw->vhack && (ddraw->iscnc1 || ddraw->isredalert) && ddraw->incutscene)
+        if (ddraw->vhack && InterlockedExchangeAdd(&ddraw->incutscene, 0))
         {
             diffx = 0;
             diffy = 0;
diff --git a/src/render.c b/src/render.c
index 43bfa81..f272529 100644
--- a/src/render.c
+++ b/src/render.c
@@ -487,24 +487,20 @@ DWORD WINAPI render_main(void)
 
         if (ddraw->primary && ddraw->primary->palette)
         {
-            if (ddraw->vhack && detect_cutscene())
+            if (ddraw->vhack)
             {
-                scale_w *= (float)CUTSCENE_WIDTH / ddraw->width;
-                scale_h *= (float)CUTSCENE_HEIGHT / ddraw->height;
-
-                if (!ddraw->incutscene)
+                if (detect_cutscene())
                 {
-                    scaleChanged = TRUE;
-                    ddraw->incutscene = TRUE;
+                    scale_w *= (float)CUTSCENE_WIDTH / ddraw->width;
+                    scale_h *= (float)CUTSCENE_HEIGHT / ddraw->height;
+
+                    if (!InterlockedExchange(&ddraw->incutscene, TRUE))
+                        scaleChanged = TRUE;
                 }
-
-            }
-            else
-            {
-                if (ddraw->incutscene)
+                else
                 {
-                    scaleChanged = TRUE;
-                    ddraw->incutscene = FALSE;
+                    if (InterlockedExchange(&ddraw->incutscene, FALSE))
+                        scaleChanged = TRUE;
                 }
             }
 
diff --git a/src/render_soft.c b/src/render_soft.c
index 758840f..c486c9c 100644
--- a/src/render_soft.c
+++ b/src/render_soft.c
@@ -35,9 +35,6 @@ BOOL detect_cutscene()
     if(ddraw->width <= CUTSCENE_WIDTH || ddraw->height <= CUTSCENE_HEIGHT)
         return FALSE;
         
-    //if (ddraw->isredalert && *InMovie)
-    //    return !*IsVQA640;
-        
     if (ddraw->isredalert)
     {
         if ((*InMovie && !*IsVQA640) || *ShouldStretch)
@@ -120,13 +117,8 @@ DWORD WINAPI render_soft_main(void)
         
         EnterCriticalSection(&ddraw->cs);
 
-        if (ddraw->primary && (ddraw->primary->palette || ddraw->bpp == 16))
+        if (ddraw->primary && ddraw->primary->palette && ddraw->primary->palette->data_rgb)
         {
-            if (ddraw->primary->palette && ddraw->primary->palette->data_rgb == NULL)
-            {
-                ddraw->primary->palette->data_rgb = &ddraw->primary->bmi->bmiColors[0];
-            }
-
             if (warningText[0])
             {
                 if (timeGetTime() < warningEndTick)
@@ -138,44 +130,61 @@ DWORD WINAPI render_soft_main(void)
                     warningText[0] = 0;
             }
 
-            if ((ddraw->render.width != ddraw->width || ddraw->render.height != ddraw->height) && 
-                !(ddraw->vhack && detect_cutscene()) )
+            BOOL scaleCutscene = ddraw->vhack && detect_cutscene();
+
+            if (ddraw->vhack)
+                InterlockedExchange(&ddraw->incutscene, scaleCutscene);
+
+            if (scaleCutscene)
             {
                 StretchDIBits(
-                    ddraw->render.hDC, ddraw->render.viewport.x, ddraw->render.viewport.y, 
-                    ddraw->render.viewport.width, ddraw->render.viewport.height, 
-                    0, 0, ddraw->width, ddraw->height, ddraw->primary->surface, 
-                    ddraw->primary->bmi, DIB_RGB_COLORS, SRCCOPY);
+                    ddraw->render.hDC, 
+                    ddraw->render.viewport.x, 
+                    ddraw->render.viewport.y,
+                    ddraw->render.viewport.width, 
+                    ddraw->render.viewport.height,
+                    0, 
+                    ddraw->height - 400, 
+                    CUTSCENE_WIDTH, 
+                    CUTSCENE_HEIGHT, 
+                    ddraw->primary->surface,
+                    ddraw->primary->bmi, 
+                    DIB_RGB_COLORS, 
+                    SRCCOPY);
             }
-            else if (!(ddraw->vhack && detect_cutscene()))
+            else if (ddraw->render.width != ddraw->width || ddraw->render.height != ddraw->height)
+            {
+                StretchDIBits(
+                    ddraw->render.hDC, 
+                    ddraw->render.viewport.x, 
+                    ddraw->render.viewport.y, 
+                    ddraw->render.viewport.width, 
+                    ddraw->render.viewport.height, 
+                    0, 
+                    0, 
+                    ddraw->width, 
+                    ddraw->height, 
+                    ddraw->primary->surface, 
+                    ddraw->primary->bmi, 
+                    DIB_RGB_COLORS, 
+                    SRCCOPY);
+            }
+            else
             {
                 SetDIBitsToDevice(
-                    ddraw->render.hDC, 0, 0, ddraw->width, ddraw->height, 0, 0, 0, 
-                    ddraw->height, ddraw->primary->surface, ddraw->primary->bmi, DIB_RGB_COLORS);
+                    ddraw->render.hDC, 
+                    0, 
+                    0, 
+                    ddraw->width, 
+                    ddraw->height, 
+                    0, 
+                    0, 
+                    0, 
+                    ddraw->height, 
+                    ddraw->primary->surface, 
+                    ddraw->primary->bmi, 
+                    DIB_RGB_COLORS);
             }
-
-        }
-        if (ddraw->vhack && ddraw->primary && detect_cutscene()) // for vhack
-        {
-            if (ddraw->primary->palette && ddraw->primary->palette->data_rgb == NULL)
-            {
-                ddraw->primary->palette->data_rgb = &ddraw->primary->bmi->bmiColors[0];
-            }
-            
-            StretchDIBits(
-                ddraw->render.hDC, ddraw->render.viewport.x, ddraw->render.viewport.y, 
-                ddraw->render.viewport.width, ddraw->render.viewport.height, 
-                0, ddraw->height-400, CUTSCENE_WIDTH, CUTSCENE_HEIGHT, ddraw->primary->surface, 
-                ddraw->primary->bmi, DIB_RGB_COLORS, SRCCOPY);
-
-            if (ddraw->primary->palette && !ddraw->incutscene)
-            {
-                ddraw->incutscene = TRUE;
-            }
-        }
-        else if(ddraw->primary && ddraw->primary->palette && ddraw->incutscene)
-        {
-            ddraw->incutscene = FALSE;
         }
 
         LeaveCriticalSection(&ddraw->cs);
diff --git a/src/surface.c b/src/surface.c
index 569fa17..91d82ef 100644
--- a/src/surface.c
+++ b/src/surface.c
@@ -420,7 +420,12 @@ HRESULT __stdcall ddraw_surface_SetPalette(IDirectDrawSurfaceImpl *This, LPDIREC
         IDirectDrawPalette_Release(This->palette);
     }
 
+    EnterCriticalSection(&ddraw->cs);
+
     This->palette = (IDirectDrawPaletteImpl *)lpDDPalette;
+    This->palette->data_rgb = &This->bmi->bmiColors[0];
+
+    LeaveCriticalSection(&ddraw->cs);
 
     return DD_OK;
 }