From 4e6ecfe37c278769e42cdbc17e94a6b79414221b Mon Sep 17 00:00:00 2001
From: FunkyFr3sh <cc.red.alert.1@googlemail.com>
Date: Thu, 17 Sep 2020 05:49:36 +0200
Subject: [PATCH] #39 hook GetDeviceCaps - fixes graphcial glitches for Megaman
 X4

---
 inc/hook.h  |  2 ++
 inc/mouse.h |  1 +
 src/hook.c  |  3 +++
 src/mouse.c | 10 ++++++++++
 4 files changed, 16 insertions(+)

diff --git a/inc/hook.h b/inc/hook.h
index d67e45b..d75cb22 100644
--- a/inc/hook.h
+++ b/inc/hook.h
@@ -23,6 +23,7 @@ typedef LONG (WINAPI* SETWINDOWLONGAPROC)(HWND, int, LONG);
 typedef BOOL (WINAPI* ENABLEWINDOWPROC)(HWND, BOOL);
 typedef HWND (WINAPI* CREATEWINDOWEXAPROC)(DWORD, LPCSTR, LPCSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID);
 typedef BOOL (WINAPI* DESTROYWINDOWPROC)(HWND);
+typedef BOOL(WINAPI* GETDEVICECAPSPROC)(HDC, int);
 
 extern GETCURSORPOSPROC real_GetCursorPos;
 extern CLIPCURSORPROC real_ClipCursor;
@@ -44,6 +45,7 @@ extern SETWINDOWLONGAPROC real_SetWindowLongA;
 extern ENABLEWINDOWPROC real_EnableWindow;
 extern CREATEWINDOWEXAPROC real_CreateWindowExA;
 extern DESTROYWINDOWPROC real_DestroyWindow;
+extern GETDEVICECAPSPROC real_GetDeviceCaps;
 
 extern int HookingMethod;
 extern BOOL Hook_Active;
diff --git a/inc/mouse.h b/inc/mouse.h
index a11fd3d..991e538 100644
--- a/inc/mouse.h
+++ b/inc/mouse.h
@@ -25,6 +25,7 @@ LRESULT WINAPI fake_SendMessageA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lPar
 LONG WINAPI fake_SetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong);
 BOOL WINAPI fake_EnableWindow(HWND hWnd, BOOL bEnable);
 BOOL WINAPI fake_DestroyWindow(HWND hWnd);
+int WINAPI fake_GetDeviceCaps(HDC hdc, int index);
 HWND WINAPI fake_CreateWindowExA(
     DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y,
     int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
diff --git a/src/hook.c b/src/hook.c
index 743f255..340593e 100644
--- a/src/hook.c
+++ b/src/hook.c
@@ -30,6 +30,7 @@ SETWINDOWLONGAPROC real_SetWindowLongA = SetWindowLongA;
 ENABLEWINDOWPROC real_EnableWindow = EnableWindow;
 CREATEWINDOWEXAPROC real_CreateWindowExA = CreateWindowExA;
 DESTROYWINDOWPROC real_DestroyWindow = DestroyWindow;
+GETDEVICECAPSPROC real_GetDeviceCaps = GetDeviceCaps;
 
 
 void Hook_PatchIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction)
@@ -164,6 +165,7 @@ void Hook_Init()
         Hook_Create("user32.dll", "EnableWindow", (PROC)fake_EnableWindow, (PROC *)&real_EnableWindow);
         Hook_Create("user32.dll", "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC *)&real_CreateWindowExA);
         Hook_Create("user32.dll", "DestroyWindow", (PROC)fake_DestroyWindow, (PROC *)&real_DestroyWindow);
+        Hook_Create("gdi.dll",    "GetDeviceCaps ", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps);
     }
 }
 
@@ -193,5 +195,6 @@ void Hook_Exit()
         Hook_Revert("user32.dll", "EnableWindow", (PROC)fake_EnableWindow, (PROC *)&real_EnableWindow);
         Hook_Revert("user32.dll", "CreateWindowExA", (PROC)fake_CreateWindowExA, (PROC *)&real_CreateWindowExA);
         Hook_Revert("user32.dll", "DestroyWindow", (PROC)fake_DestroyWindow, (PROC *)&real_DestroyWindow);
+        Hook_Revert("gdi.dll",    "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps);
     }
 }
diff --git a/src/mouse.c b/src/mouse.c
index b12b0b6..74a9959 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -422,6 +422,16 @@ BOOL WINAPI fake_EnableWindow(HWND hWnd, BOOL bEnable)
     return real_EnableWindow(hWnd, bEnable);
 }
 
+int WINAPI fake_GetDeviceCaps(HDC hdc, int index)
+{
+    if (ddraw && ddraw->bpp && index == BITSPIXEL)
+    {
+        return ddraw->bpp;
+    }
+
+    return real_GetDeviceCaps(hdc, index);
+}
+
 BOOL WINAPI fake_DestroyWindow(HWND hWnd)
 {
     BOOL result = real_DestroyWindow(hWnd);