From b4b3e95832b16ae7bfeff8c12170f29508ed6e85 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 26 Sep 2023 00:51:53 +0200 Subject: [PATCH 01/37] dvd movie tests --- src/utils.c | 1 + src/winapi_hooks.c | 24 +++++++++--------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/utils.c b/src/utils.c index 8477297..596e0bf 100644 --- a/src/utils.c +++ b/src/utils.c @@ -473,6 +473,7 @@ BOOL CALLBACK util_enum_child_proc(HWND hwnd, LPARAM lparam) if (g_config.fixchilds == FIX_CHILDS_DETECT_HIDE || strcmp(class_name, "VideoRenderer") == 0 || strcmp(class_name, "AVIWnd32") == 0 || + strcmp(class_name, "Afx:400000:3") == 0 || strcmp(class_name, "MCIWndClass") == 0) { LONG style = real_GetWindowLongA(hwnd, GWL_EXSTYLE); diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index f795b27..28783e6 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -738,9 +738,11 @@ BOOL WINAPI fake_StretchBlt( (g_config.fixchilds && IsChild(g_ddraw->hwnd, hwnd) && (g_config.fixchilds == FIX_CHILDS_DETECT_HIDE || strcmp(class_name, "AVIWnd32") == 0 || + strcmp(class_name, "Afx:400000:3") == 0 || + strcmp(class_name, "VideoRenderer") == 0 || strcmp(class_name, "MCIWndClass") == 0)))) { - if (g_ddraw->primary && (g_ddraw->primary->bpp == 16 || g_ddraw->primary->bpp == 32 || g_ddraw->primary->palette)) + if (0)//g_ddraw->primary && (g_ddraw->primary->bpp == 16 || g_ddraw->primary->bpp == 32 || g_ddraw->primary->palette)) { HDC primary_dc; dds_GetDC(g_ddraw->primary, &primary_dc); @@ -1190,22 +1192,14 @@ 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) { - /* Center Claw DVD movies */ - if (HIWORD(lpClassName) && - _strcmpi(lpClassName, "Afx:400000:3") == 0 && - g_ddraw && g_ddraw->hwnd && g_ddraw->width && + /* Claw DVD movies */ + if (HIWORD(lpClassName) && _strcmpi(lpClassName, "Afx:400000:3") == 0 && + g_ddraw && g_ddraw->hwnd && (dwStyle & (WS_POPUP | WS_CHILD)) == (WS_POPUP | WS_CHILD)) { - POINT pt = { 0, 0 }; - real_ClientToScreen(g_ddraw->hwnd, &pt); - - int added_height = g_ddraw->render.height - g_ddraw->height; - int added_width = g_ddraw->render.width - g_ddraw->width; - int align_y = added_height > 0 ? added_height / 2 : 0; - int align_x = added_width > 0 ? added_width / 2 : 0; - - X = pt.x + align_x; - Y = pt.y + align_y; + dwStyle &= ~WS_POPUP; + LoadLibraryA("quartz.dll"); + hook_init(FALSE); } /* Fix for SMACKW32.DLL creating another window that steals the focus */ From 453d266d7640444f619af09e0e357ed9c8f19aed Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 26 Sep 2023 01:50:58 +0200 Subject: [PATCH 02/37] add temporary game patches for testing --- src/dllmain.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/dllmain.c b/src/dllmain.c index ff55417..945ee6b 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -9,6 +9,7 @@ #include "debug.h" #include "config.h" #include "hook.h" +#include "patch.h" /* export for cncnet cnc games */ @@ -38,6 +39,56 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) #endif g_ddraw_module = hDll; + + + /* Claw DVD Movie experiments */ + + /* change file extension .vob to .avi */ + HMODULE game_exe = GetModuleHandleA(NULL); + + PIMAGE_DOS_HEADER dos_hdr = (void*)game_exe; + PIMAGE_NT_HEADERS nt_hdr = (void*)((char*)game_exe + dos_hdr->e_lfanew); + + for (int i = 0; i < nt_hdr->FileHeader.NumberOfSections; i++) + { + PIMAGE_SECTION_HEADER sct_hdr = IMAGE_FIRST_SECTION(nt_hdr) + i; + + if (strcmp(".data", (char*)sct_hdr->Name) == 0) + { + char* s = (char*)((char*)game_exe + sct_hdr->VirtualAddress); + int s_len = sct_hdr->Misc.VirtualSize; + + for (int i = 0; i < s_len; i++, s++) + { + if (*s == '.' && memcmp(s, "\x2E\x76\x6F\x62\x00", 5) == 0) /* .vob */ + { + memcpy(s, "\x2E\x61\x76\x69", 4); /* .avi */ + } + } + + break; + } + sct_hdr++; + } + + /* add registry key for x264vfw */ + + HKEY hkey; + LONG status = + RegOpenKeyExA( + HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32", 0L, KEY_WRITE, &hkey); + + if (status == ERROR_SUCCESS) + { + LPCTSTR data = "x264vfw.dll"; + RegSetValueExA(hkey,"vidc.x264", 0, REG_SZ, data, strlen(data)+1); + RegCloseKey(hkey); + } + + + + + char buf[1024]; if (GetEnvironmentVariable("__COMPAT_LAYER", buf, sizeof(buf))) From a119eddd5358119a2ee0375c952641527cdd12fd Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 26 Sep 2023 02:27:00 +0200 Subject: [PATCH 03/37] adjust default settings for claw --- src/config.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/config.c b/src/config.c index cb8b656..c736c97 100644 --- a/src/config.c +++ b/src/config.c @@ -167,10 +167,10 @@ static void cfg_create_ini() "\n" "; Override the width/height settings shown above and always stretch to fullscreen\n" "; Note: Can be combined with 'windowed=true' to get windowed-fullscreen aka borderless mode\n" - "fullscreen=false\n" + "fullscreen=true\n" "\n" "; Run in windowed mode rather than going fullscreen\n" - "windowed=false\n" + "windowed=true\n" "\n" "; Maintain aspect ratio\n" "maintas=false\n" @@ -201,7 +201,7 @@ static void cfg_create_ini() "posY=-32000\n" "\n" "; Renderer, possible values: auto, opengl, openglcore, gdi, direct3d9, direct3d9on12 (auto = try direct3d9/opengl, fallback = gdi)\n" - "renderer=auto\n" + "renderer=opengl\n" "\n" "; Developer mode (don't lock the cursor)\n" "devmode=false\n" @@ -227,7 +227,7 @@ static void cfg_create_ini() "screenshotdir=.\\Screenshots\\\n" "\n" "; Switch between windowed/borderless modes with alt+enter rather than windowed/fullscreen modes\n" - "toggle_borderless=false\n" + "toggle_borderless=true\n" "\n" "\n" "\n" @@ -236,7 +236,7 @@ static void cfg_create_ini() "\n" "\n" "; Hide WM_ACTIVATEAPP and WM_NCACTIVATE messages to prevent problems on alt+tab\n" - "noactivateapp=false\n" + "noactivateapp=true\n" "\n" "; Max game ticks per second, possible values: -1 = disabled, -2 = refresh rate, 0 = emulate 60hz vblank, 1-1000 = custom game speed\n" "; Note: Can be used to slow down a too fast running game, fix flickering or too fast animations\n" @@ -249,11 +249,11 @@ static void cfg_create_ini() "\n" "; Disable fullscreen-exclusive mode for the direct3d9*/opengl* renderers\n" "; Note: Can be used in case some GUI elements like buttons/textboxes/videos/etc.. are invisible\n" - "nonexclusive=false\n" + "nonexclusive=true\n" "\n" "; Force CPU0 affinity, avoids crashes/freezing, *might* have a performance impact\n" "; Note: Disable this if the game is not running smooth or there are sound issues\n" - "singlecpu=true\n" + "singlecpu=false\n" "\n" "; Available resolutions, possible values: 0 = Small list, 1 = Very small list, 2 = Full list\n" "; Note: Set this to 2 if your chosen resolution is not working or does not show up in the list\n" From e5fb4a061a81c9c9493dae386a85cd818f97ab90 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 26 Sep 2023 04:49:02 +0200 Subject: [PATCH 04/37] fix upscaling on win10 --- src/winapi_hooks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index 28783e6..3f9da2c 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -1199,6 +1199,7 @@ HWND WINAPI fake_CreateWindowExA( { dwStyle &= ~WS_POPUP; LoadLibraryA("quartz.dll"); + LoadLibraryA("MSVFW32.dll"); hook_init(FALSE); } From e414568af49421252a37c572c1ff2ab1de8430a9 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 26 Sep 2023 04:50:12 +0200 Subject: [PATCH 05/37] fix color issues --- src/hook.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hook.c b/src/hook.c index a1e3407..a73fa41 100644 --- a/src/hook.c +++ b/src/hook.c @@ -124,7 +124,7 @@ HOOKLIST g_hook_hooklist[] = { "StretchBlt", (PROC)fake_StretchBlt, (PROC*)&real_StretchBlt, SKIP_HOOK2 }, { "SetDIBitsToDevice", (PROC)fake_SetDIBitsToDevice, (PROC*)&real_SetDIBitsToDevice, SKIP_HOOK2 }, { "StretchDIBits", (PROC)fake_StretchDIBits, (PROC*)&real_StretchDIBits, SKIP_HOOK2 }, - { "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps, 0 }, + //{ "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps, 0 }, { "CreateFontA", (PROC)fake_CreateFontA, (PROC*)&real_CreateFontA, 0 }, { "CreateFontIndirectA", (PROC)fake_CreateFontIndirectA, (PROC*)&real_CreateFontIndirectA, 0 }, { "", NULL, NULL, 0 } From 2cf14bf2eff52bdde9ac4af383d7adaad18fb25c Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 26 Sep 2023 06:16:45 +0200 Subject: [PATCH 06/37] fix random freezing --- src/utils.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/utils.c b/src/utils.c index 596e0bf..af11859 100644 --- a/src/utils.c +++ b/src/utils.c @@ -481,16 +481,6 @@ BOOL CALLBACK util_enum_child_proc(HWND hwnd, LPARAM lparam) if (!(style & WS_EX_TRANSPARENT)) { real_SetWindowLongA(hwnd, GWL_EXSTYLE, style | WS_EX_TRANSPARENT); - - real_SetWindowPos( - hwnd, - 0, - 0, - 0, - 0, - 0, - SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER - ); } } else From 4d8181099cb4c1361637ddee6176361393bc50ce Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 26 Sep 2023 06:50:48 +0200 Subject: [PATCH 07/37] don't lock on WM_PAINT --- src/wndproc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wndproc.c b/src/wndproc.c index 96cf44e..961f33d 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -854,9 +854,7 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); } - EnterCriticalSection(&g_ddraw->cs); ReleaseSemaphore(g_ddraw->render.sem, 1, NULL); - LeaveCriticalSection(&g_ddraw->cs); break; } case WM_ERASEBKGND: From c8c7ead36ed4d8ed0ac7f0184da0433842e24f2e Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 26 Sep 2023 07:18:41 +0200 Subject: [PATCH 08/37] bump version --- inc/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/version.h b/inc/version.h index 510cf80..5276877 100644 --- a/inc/version.h +++ b/inc/version.h @@ -7,7 +7,7 @@ #define VERSION_MAJOR 5 #define VERSION_MINOR 7 #define VERSION_BUILD 0 -#define VERSION_REVISION 6 +#define VERSION_REVISION 7 #define VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION #define VERSION_STRING ver_str(VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION) From 68bd087cf0e6b58084a365780a500e9f8819021b Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 26 Sep 2023 10:02:01 +0200 Subject: [PATCH 09/37] re-enable hook --- src/hook.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hook.c b/src/hook.c index a73fa41..a1e3407 100644 --- a/src/hook.c +++ b/src/hook.c @@ -124,7 +124,7 @@ HOOKLIST g_hook_hooklist[] = { "StretchBlt", (PROC)fake_StretchBlt, (PROC*)&real_StretchBlt, SKIP_HOOK2 }, { "SetDIBitsToDevice", (PROC)fake_SetDIBitsToDevice, (PROC*)&real_SetDIBitsToDevice, SKIP_HOOK2 }, { "StretchDIBits", (PROC)fake_StretchDIBits, (PROC*)&real_StretchDIBits, SKIP_HOOK2 }, - //{ "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps, 0 }, + { "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps, 0 }, { "CreateFontA", (PROC)fake_CreateFontA, (PROC*)&real_CreateFontA, 0 }, { "CreateFontIndirectA", (PROC)fake_CreateFontIndirectA, (PROC*)&real_CreateFontIndirectA, 0 }, { "", NULL, NULL, 0 } From 3ad8a5bd0e2bd8d8c1414dd34f23974787434782 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 26 Sep 2023 10:41:20 +0200 Subject: [PATCH 10/37] add new hook flag for local hooks --- inc/hook.h | 5 +++-- src/hook.c | 64 +++++++++++++++++++++++++++++++----------------------- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/inc/hook.h b/inc/hook.h index 908c832..1663f99 100644 --- a/inc/hook.h +++ b/inc/hook.h @@ -5,7 +5,8 @@ #include -#define SKIP_HOOK2 0x00000001l +#define HOOK_SKIP_2 0x00000001l +#define HOOK_LOCAL_ONLY 0x00000002l typedef struct HOOKLISTDATA { char function_name[32]; PROC new_function; PROC* function; DWORD flags; } HOOKLISTDATA; typedef struct HOOKLIST { char module_name[32]; HOOKLISTDATA data[30]; } HOOKLIST; @@ -109,7 +110,7 @@ extern HOOKLIST g_hook_hooklist[]; void hook_init(BOOL initial_hook); void hook_exit(); void hook_patch_iat(HMODULE hmod, BOOL unhook, char* module_name, char* function_name, PROC new_function); -void hook_patch_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks); +void hook_patch_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks, BOOL is_local); void hook_create(HOOKLIST* hooks, BOOL initial_hook); void hook_revert(HOOKLIST* hooks); diff --git a/src/hook.c b/src/hook.c index a1e3407..4aa653d 100644 --- a/src/hook.c +++ b/src/hook.c @@ -98,33 +98,33 @@ HOOKLIST g_hook_hooklist[] = { "ole32.dll", { - { "CoCreateInstance", (PROC)fake_CoCreateInstance, (PROC*)&real_CoCreateInstance, SKIP_HOOK2 }, + { "CoCreateInstance", (PROC)fake_CoCreateInstance, (PROC*)&real_CoCreateInstance, HOOK_SKIP_2 }, { "", NULL, NULL, 0 } } }, { "dinput.dll", { - { "DirectInputCreateA", (PROC)fake_DirectInputCreateA, (PROC*)&real_DirectInputCreateA, SKIP_HOOK2 }, - //{ "DirectInputCreateW", (PROC)fake_DirectInputCreateW, (PROC*)&real_DirectInputCreateW, SKIP_HOOK2 }, - { "DirectInputCreateEx", (PROC)fake_DirectInputCreateEx, (PROC*)&real_DirectInputCreateEx, SKIP_HOOK2 }, + { "DirectInputCreateA", (PROC)fake_DirectInputCreateA, (PROC*)&real_DirectInputCreateA, HOOK_SKIP_2 }, + //{ "DirectInputCreateW", (PROC)fake_DirectInputCreateW, (PROC*)&real_DirectInputCreateW, HOOK_SKIP_2 }, + { "DirectInputCreateEx", (PROC)fake_DirectInputCreateEx, (PROC*)&real_DirectInputCreateEx, HOOK_SKIP_2 }, { "", NULL, NULL, 0 } } }, { "dinput8.dll", { - { "DirectInput8Create", (PROC)fake_DirectInput8Create, (PROC*)&real_DirectInput8Create, SKIP_HOOK2 }, + { "DirectInput8Create", (PROC)fake_DirectInput8Create, (PROC*)&real_DirectInput8Create, HOOK_SKIP_2 }, { "", NULL, NULL, 0 } } }, { "gdi32.dll", { - { "StretchBlt", (PROC)fake_StretchBlt, (PROC*)&real_StretchBlt, SKIP_HOOK2 }, - { "SetDIBitsToDevice", (PROC)fake_SetDIBitsToDevice, (PROC*)&real_SetDIBitsToDevice, SKIP_HOOK2 }, - { "StretchDIBits", (PROC)fake_StretchDIBits, (PROC*)&real_StretchDIBits, SKIP_HOOK2 }, - { "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps, 0 }, + { "StretchBlt", (PROC)fake_StretchBlt, (PROC*)&real_StretchBlt, HOOK_SKIP_2 }, + { "SetDIBitsToDevice", (PROC)fake_SetDIBitsToDevice, (PROC*)&real_SetDIBitsToDevice, HOOK_SKIP_2 }, + { "StretchDIBits", (PROC)fake_StretchDIBits, (PROC*)&real_StretchDIBits, HOOK_SKIP_2 }, + { "GetDeviceCaps", (PROC)fake_GetDeviceCaps, (PROC*)&real_GetDeviceCaps, HOOK_LOCAL_ONLY }, { "CreateFontA", (PROC)fake_CreateFontA, (PROC*)&real_CreateFontA, 0 }, { "CreateFontIndirectA", (PROC)fake_CreateFontIndirectA, (PROC*)&real_CreateFontIndirectA, 0 }, { "", NULL, NULL, 0 } @@ -133,12 +133,12 @@ HOOKLIST g_hook_hooklist[] = { "kernel32.dll", { - { "LoadLibraryA", (PROC)fake_LoadLibraryA, (PROC*)&real_LoadLibraryA, SKIP_HOOK2 }, - { "LoadLibraryW", (PROC)fake_LoadLibraryW, (PROC*)&real_LoadLibraryW, SKIP_HOOK2 }, - { "LoadLibraryExA", (PROC)fake_LoadLibraryExA, (PROC*)&real_LoadLibraryExA, SKIP_HOOK2 }, - { "LoadLibraryExW", (PROC)fake_LoadLibraryExW, (PROC*)&real_LoadLibraryExW, SKIP_HOOK2 }, - { "GetProcAddress", (PROC)fake_GetProcAddress, (PROC*)&real_GetProcAddress, SKIP_HOOK2 }, - { "GetDiskFreeSpaceA", (PROC)fake_GetDiskFreeSpaceA, (PROC*)&real_GetDiskFreeSpaceA, SKIP_HOOK2 }, + { "LoadLibraryA", (PROC)fake_LoadLibraryA, (PROC*)&real_LoadLibraryA, HOOK_SKIP_2 }, + { "LoadLibraryW", (PROC)fake_LoadLibraryW, (PROC*)&real_LoadLibraryW, HOOK_SKIP_2 }, + { "LoadLibraryExA", (PROC)fake_LoadLibraryExA, (PROC*)&real_LoadLibraryExA, HOOK_SKIP_2 }, + { "LoadLibraryExW", (PROC)fake_LoadLibraryExW, (PROC*)&real_LoadLibraryExW, HOOK_SKIP_2 }, + { "GetProcAddress", (PROC)fake_GetProcAddress, (PROC*)&real_GetProcAddress, HOOK_SKIP_2 }, + { "GetDiskFreeSpaceA", (PROC)fake_GetDiskFreeSpaceA, (PROC*)&real_GetDiskFreeSpaceA, HOOK_SKIP_2 }, { "", NULL, NULL, 0 } } }, @@ -160,10 +160,10 @@ void hook_patch_iat(HMODULE hmod, BOOL unhook, char* module_name, char* function strncpy(hooks[0].module_name, module_name, sizeof(hooks[0].module_name) - 1); strncpy(hooks[0].data[0].function_name, function_name, sizeof(hooks[0].data[0].function_name) - 1); - hook_patch_iat_list(hmod, unhook, (HOOKLIST*)&hooks); + hook_patch_iat_list(hmod, unhook, (HOOKLIST*)&hooks, FALSE); } -void hook_patch_obfuscated_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks) +void hook_patch_obfuscated_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks, BOOL is_local) { if (!hmod || hmod == INVALID_HANDLE_VALUE || !hooks) return; @@ -212,6 +212,9 @@ void hook_patch_obfuscated_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks) if (!hooks[i].data[x].new_function || !org_function) continue; + if (!is_local && (hooks[i].data[x].flags & HOOK_LOCAL_ONLY)) + continue; + if (unhook) { if (first_thunk->u1.Function == (DWORD)hooks[i].data[x].new_function) @@ -268,9 +271,9 @@ void hook_patch_obfuscated_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks) } } -void hook_patch_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks) +void hook_patch_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks, BOOL is_local) { - hook_patch_obfuscated_iat_list(hmod, unhook, hooks); + hook_patch_obfuscated_iat_list(hmod, unhook, hooks, is_local); if (!hmod || hmod == INVALID_HANDLE_VALUE || !hooks) return; @@ -317,6 +320,9 @@ void hook_patch_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks) if (!unhook && !hooks[i].data[x].new_function) continue; + if (!is_local && (hooks[i].data[x].flags & HOOK_LOCAL_ONLY)) + continue; + if (_stricmp((const char*)import->Name, hooks[i].data[x].function_name) == 0) { DWORD op; @@ -415,7 +421,7 @@ void hook_create(HOOKLIST* hooks, BOOL initial_hook) { for (int x = 0; hooks[i].data[x].function_name[0]; x++) { - if ((hooks[i].data[x].flags & SKIP_HOOK2)) + if ((hooks[i].data[x].flags & HOOK_SKIP_2)) continue; DetourTransactionBegin(); @@ -470,12 +476,14 @@ void hook_create(HOOKLIST* hooks, BOOL initial_hook) _strcmpi(mod_filename, "Shw32") == 0) continue; - if (_strnicmp(game_dir, mod_dir, strlen(game_dir)) == 0 || + BOOL is_local = _strnicmp(game_dir, mod_dir, strlen(game_dir)) == 0; + + if (is_local || _strcmpi(mod_filename, "MSVFW32") == 0 || _strcmpi(mod_filename, "quartz") == 0 || _strcmpi(mod_filename, "winmm") == 0) { - hook_patch_iat_list(hmod, FALSE, hooks); + hook_patch_iat_list(hmod, FALSE, hooks, is_local); } } } @@ -487,7 +495,7 @@ void hook_create(HOOKLIST* hooks, BOOL initial_hook) if (g_config.hook == 1) { - hook_patch_iat_list(GetModuleHandle(NULL), FALSE, hooks); + hook_patch_iat_list(GetModuleHandle(NULL), FALSE, hooks, TRUE); } } @@ -500,7 +508,7 @@ void hook_revert(HOOKLIST* hooks) { for (int x = 0; hooks[i].data[x].function_name[0]; x++) { - if ((hooks[i].data[x].flags & SKIP_HOOK2)) + if ((hooks[i].data[x].flags & HOOK_SKIP_2)) continue; DetourTransactionBegin(); @@ -544,12 +552,14 @@ void hook_revert(HOOKLIST* hooks) { _splitpath(mod_path, NULL, mod_dir, mod_filename, NULL); - if (_strnicmp(game_dir, mod_dir, strlen(game_dir)) == 0 || + BOOL is_local = _strnicmp(game_dir, mod_dir, strlen(game_dir)) == 0; + + if (is_local || _strcmpi(mod_filename, "MSVFW32") == 0 || _strcmpi(mod_filename, "quartz") == 0 || _strcmpi(mod_filename, "winmm") == 0) { - hook_patch_iat_list(hmod, TRUE, hooks); + hook_patch_iat_list(hmod, TRUE, hooks, is_local); } } } @@ -561,7 +571,7 @@ void hook_revert(HOOKLIST* hooks) if (g_config.hook == 1) { - hook_patch_iat_list(GetModuleHandle(NULL), TRUE, hooks); + hook_patch_iat_list(GetModuleHandle(NULL), TRUE, hooks, TRUE); } } From 7b7fefcad182fadbb47cf52533247ae97685dc4c Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 26 Sep 2023 19:35:12 +0200 Subject: [PATCH 11/37] create registry key if it doesn't exist --- src/dllmain.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/dllmain.c b/src/dllmain.c index 945ee6b..42e4f46 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -75,8 +75,16 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) HKEY hkey; LONG status = - RegOpenKeyExA( - HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32", 0L, KEY_WRITE, &hkey); + RegCreateKeyExA( + HKEY_CURRENT_USER, + "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32", + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE | KEY_QUERY_VALUE, + NULL, + &hkey, + NULL); if (status == ERROR_SUCCESS) { From e3142956dc8d030534450a963231ca06f3f5b8c5 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 26 Sep 2023 22:48:30 +0200 Subject: [PATCH 12/37] add support for xvid --- src/dllmain.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dllmain.c b/src/dllmain.c index 42e4f46..d2bbec2 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -88,8 +88,12 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) if (status == ERROR_SUCCESS) { - LPCTSTR data = "x264vfw.dll"; - RegSetValueExA(hkey,"vidc.x264", 0, REG_SZ, data, strlen(data)+1); + LPCTSTR x264 = "x264vfw.dll"; + RegSetValueExA(hkey,"vidc.x264", 0, REG_SZ, x264, strlen(x264) + 1); + + LPCTSTR xvid = "xvidvfw.dll"; + RegSetValueExA(hkey, "vidc.xvid", 0, REG_SZ, xvid, strlen(xvid) + 1); + RegCloseKey(hkey); } From b63410c4449b24973f8d4b53992de5f1b0aeb48f Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Sun, 8 Oct 2023 11:59:09 +0200 Subject: [PATCH 13/37] add fix for custom levels --- src/ddsurface.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ddsurface.c b/src/ddsurface.c index 3ca910d..5aa9fcc 100644 --- a/src/ddsurface.c +++ b/src/ddsurface.c @@ -1442,7 +1442,8 @@ HRESULT dd_CreateSurface( if (InterlockedExchangeAdd(&g_dds_gdi_handles, 0) < 4000 || - (dst_surface->width == g_ddraw->width && dst_surface->height == g_ddraw->height)) + (dst_surface->width == g_ddraw->width && dst_surface->height == g_ddraw->height) || + (dst_surface->width == 128 && dst_surface->height == 128)) { dst_surface->hdc = CreateCompatibleDC(g_ddraw->render.hdc); From 4d7fc88d379471a787d4344498dc91624eec8acc Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Mon, 16 Oct 2023 02:08:38 +0200 Subject: [PATCH 14/37] block all keys except Esc while a dvd video is playing --- inc/dd.h | 1 + src/render_d3d9.c | 2 +- src/render_gdi.c | 2 +- src/render_ogl.c | 2 +- src/utils.c | 2 ++ src/wndproc.c | 12 ++++++++++++ 6 files changed, 18 insertions(+), 3 deletions(-) diff --git a/inc/dd.h b/inc/dd.h index 1d0aa8f..042a258 100644 --- a/inc/dd.h +++ b/inc/dd.h @@ -136,6 +136,7 @@ typedef struct CNCDDRAW void* last_freed_palette; /* Dungeon Keeper hack */ void* last_freed_surface; /* Nox hack */ BOOL child_window_exists; + BOOL video_window_exists; BOOL got_child_windows; DWORD last_set_window_pos_tick; /* WINE hack */ SPEEDLIMITER ticks_limiter; diff --git a/src/render_d3d9.c b/src/render_d3d9.c index 66511ad..0934807 100644 --- a/src/render_d3d9.c +++ b/src/render_d3d9.c @@ -540,7 +540,7 @@ DWORD WINAPI d3d9_render_main(void) if (g_config.fixchilds) { - g_ddraw->child_window_exists = FALSE; + g_ddraw->child_window_exists = g_ddraw->video_window_exists = FALSE; EnumChildWindows(g_ddraw->hwnd, util_enum_child_proc, (LPARAM)g_ddraw->primary); if (g_ddraw->render.width != g_ddraw->width || g_ddraw->render.height != g_ddraw->height) diff --git a/src/render_gdi.c b/src/render_gdi.c index c3f339f..9d14d26 100644 --- a/src/render_gdi.c +++ b/src/render_gdi.c @@ -83,7 +83,7 @@ DWORD WINAPI gdi_render_main(void) if (g_config.fixchilds) { - g_ddraw->child_window_exists = FALSE; + g_ddraw->child_window_exists = g_ddraw->video_window_exists = FALSE; EnumChildWindows(g_ddraw->hwnd, util_enum_child_proc, (LPARAM)g_ddraw->primary); } diff --git a/src/render_ogl.c b/src/render_ogl.c index cc87e92..27420b9 100644 --- a/src/render_ogl.c +++ b/src/render_ogl.c @@ -769,7 +769,7 @@ static void ogl_render() if (g_config.fixchilds) { - g_ddraw->child_window_exists = FALSE; + g_ddraw->child_window_exists = g_ddraw->video_window_exists = FALSE; EnumChildWindows(g_ddraw->hwnd, util_enum_child_proc, (LPARAM)g_ddraw->primary); if (g_ddraw->render.width != g_ddraw->width || g_ddraw->render.height != g_ddraw->height) diff --git a/src/utils.c b/src/utils.c index af11859..a9fee1b 100644 --- a/src/utils.c +++ b/src/utils.c @@ -476,6 +476,8 @@ BOOL CALLBACK util_enum_child_proc(HWND hwnd, LPARAM lparam) strcmp(class_name, "Afx:400000:3") == 0 || strcmp(class_name, "MCIWndClass") == 0) { + g_ddraw->video_window_exists = TRUE; + LONG style = real_GetWindowLongA(hwnd, GWL_EXSTYLE); if (!(style & WS_EX_TRANSPARENT)) diff --git a/src/wndproc.c b/src/wndproc.c index 961f33d..366b8f3 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -709,6 +709,12 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam } case WM_KEYDOWN: { + if (g_ddraw->video_window_exists) + { + if (wParam != VK_ESCAPE) + return 0; + } + if (g_config.hotkeys.unlock_cursor1 && (wParam == VK_CONTROL || wParam == g_config.hotkeys.unlock_cursor1)) { @@ -733,6 +739,12 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam } case WM_KEYUP: { + if (g_ddraw->video_window_exists) + { + if (wParam != VK_ESCAPE) + return 0; + } + if (g_config.hotkeys.screenshot && wParam == g_config.hotkeys.screenshot) ss_take_screenshot(g_ddraw->primary); From e874a7e3059f3495e3ffe8921c6cb26958f8f6a0 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Mon, 16 Oct 2023 02:12:29 +0200 Subject: [PATCH 15/37] ignore mouse input while dvd video is playing --- src/wndproc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/wndproc.c b/src/wndproc.c index 366b8f3..014318a 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -755,6 +755,11 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_RBUTTONUP: case WM_MBUTTONUP: { + if (g_ddraw->video_window_exists) + { + return 0; + } + if (!g_config.devmode && !g_mouse_locked) { int x = GET_X_LPARAM(lParam); @@ -796,6 +801,11 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_MBUTTONDOWN: case WM_MOUSEMOVE: { + if (g_ddraw->video_window_exists) + { + return 0; + } + if (!g_config.devmode && !g_mouse_locked) { return 0; From 743907669ed4239b07bcd4d63b9aaff8358cfd03 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Mon, 16 Oct 2023 02:14:06 +0200 Subject: [PATCH 16/37] allow cursor lock while playing videos --- src/wndproc.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/wndproc.c b/src/wndproc.c index 014318a..f36ef5b 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -755,11 +755,6 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_RBUTTONUP: case WM_MBUTTONUP: { - if (g_ddraw->video_window_exists) - { - return 0; - } - if (!g_config.devmode && !g_mouse_locked) { int x = GET_X_LPARAM(lParam); From 65969de0bdb17deb3de4fb6fea06cfc1847adb10 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Mon, 16 Oct 2023 02:18:22 +0200 Subject: [PATCH 17/37] allow cursor unlock while video is playing --- src/wndproc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/wndproc.c b/src/wndproc.c index f36ef5b..bf0e6a9 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -709,12 +709,6 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam } case WM_KEYDOWN: { - if (g_ddraw->video_window_exists) - { - if (wParam != VK_ESCAPE) - return 0; - } - if (g_config.hotkeys.unlock_cursor1 && (wParam == VK_CONTROL || wParam == g_config.hotkeys.unlock_cursor1)) { @@ -735,19 +729,25 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam } } - break; - } - case WM_KEYUP: - { if (g_ddraw->video_window_exists) { if (wParam != VK_ESCAPE) return 0; } + break; + } + case WM_KEYUP: + { if (g_config.hotkeys.screenshot && wParam == g_config.hotkeys.screenshot) ss_take_screenshot(g_ddraw->primary); + if (g_ddraw->video_window_exists) + { + if (wParam != VK_ESCAPE) + return 0; + } + break; } /* button up messages reactivate cursor lock */ From ddfae6cd6721e1d2b20bb604e50f9a20de6b0b6f Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Mon, 16 Oct 2023 03:08:29 +0200 Subject: [PATCH 18/37] forward all input to video window --- inc/dd.h | 2 +- src/render_d3d9.c | 3 ++- src/render_gdi.c | 3 ++- src/render_ogl.c | 3 ++- src/utils.c | 2 +- src/wndproc.c | 18 +++++++++++------- 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/inc/dd.h b/inc/dd.h index 042a258..1ab5d64 100644 --- a/inc/dd.h +++ b/inc/dd.h @@ -136,7 +136,7 @@ typedef struct CNCDDRAW void* last_freed_palette; /* Dungeon Keeper hack */ void* last_freed_surface; /* Nox hack */ BOOL child_window_exists; - BOOL video_window_exists; + HWND video_window_hwnd; BOOL got_child_windows; DWORD last_set_window_pos_tick; /* WINE hack */ SPEEDLIMITER ticks_limiter; diff --git a/src/render_d3d9.c b/src/render_d3d9.c index 0934807..cae506b 100644 --- a/src/render_d3d9.c +++ b/src/render_d3d9.c @@ -540,7 +540,8 @@ DWORD WINAPI d3d9_render_main(void) if (g_config.fixchilds) { - g_ddraw->child_window_exists = g_ddraw->video_window_exists = FALSE; + g_ddraw->child_window_exists = FALSE; + InterlockedExchangePointer(&g_ddraw->video_window_hwnd, NULL); EnumChildWindows(g_ddraw->hwnd, util_enum_child_proc, (LPARAM)g_ddraw->primary); if (g_ddraw->render.width != g_ddraw->width || g_ddraw->render.height != g_ddraw->height) diff --git a/src/render_gdi.c b/src/render_gdi.c index 9d14d26..4a24747 100644 --- a/src/render_gdi.c +++ b/src/render_gdi.c @@ -83,7 +83,8 @@ DWORD WINAPI gdi_render_main(void) if (g_config.fixchilds) { - g_ddraw->child_window_exists = g_ddraw->video_window_exists = FALSE; + g_ddraw->child_window_exists = FALSE; + InterlockedExchangePointer(&g_ddraw->video_window_hwnd, NULL); EnumChildWindows(g_ddraw->hwnd, util_enum_child_proc, (LPARAM)g_ddraw->primary); } diff --git a/src/render_ogl.c b/src/render_ogl.c index 27420b9..79b1477 100644 --- a/src/render_ogl.c +++ b/src/render_ogl.c @@ -769,7 +769,8 @@ static void ogl_render() if (g_config.fixchilds) { - g_ddraw->child_window_exists = g_ddraw->video_window_exists = FALSE; + g_ddraw->child_window_exists = FALSE; + InterlockedExchangePointer(&g_ddraw->video_window_hwnd, NULL); EnumChildWindows(g_ddraw->hwnd, util_enum_child_proc, (LPARAM)g_ddraw->primary); if (g_ddraw->render.width != g_ddraw->width || g_ddraw->render.height != g_ddraw->height) diff --git a/src/utils.c b/src/utils.c index a9fee1b..617beb8 100644 --- a/src/utils.c +++ b/src/utils.c @@ -476,7 +476,7 @@ BOOL CALLBACK util_enum_child_proc(HWND hwnd, LPARAM lparam) strcmp(class_name, "Afx:400000:3") == 0 || strcmp(class_name, "MCIWndClass") == 0) { - g_ddraw->video_window_exists = TRUE; + InterlockedExchangePointer(&g_ddraw->video_window_hwnd, hwnd); LONG style = real_GetWindowLongA(hwnd, GWL_EXSTYLE); diff --git a/src/wndproc.c b/src/wndproc.c index bf0e6a9..91381cb 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -729,10 +729,11 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam } } - if (g_ddraw->video_window_exists) + HWND video_hwnd = (HWND)InterlockedExchangeAdd((LONG*)&g_ddraw->video_window_hwnd, 0); + if (video_hwnd) { - if (wParam != VK_ESCAPE) - return 0; + PostMessageA(video_hwnd, uMsg, wParam, lParam); + return 0; } break; @@ -742,10 +743,11 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam if (g_config.hotkeys.screenshot && wParam == g_config.hotkeys.screenshot) ss_take_screenshot(g_ddraw->primary); - if (g_ddraw->video_window_exists) + HWND video_hwnd = (HWND)InterlockedExchangeAdd((LONG*)&g_ddraw->video_window_hwnd, 0); + if (video_hwnd) { - if (wParam != VK_ESCAPE) - return 0; + PostMessageA(video_hwnd, uMsg, wParam, lParam); + return 0; } break; @@ -796,8 +798,10 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_MBUTTONDOWN: case WM_MOUSEMOVE: { - if (g_ddraw->video_window_exists) + HWND video_hwnd = (HWND)InterlockedExchangeAdd((LONG*)&g_ddraw->video_window_hwnd, 0); + if (video_hwnd) { + PostMessageA(video_hwnd, uMsg, wParam, lParam); return 0; } From 393627ee39783ac5a52b9031f4846c23da5a21ac Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Mon, 16 Oct 2023 03:19:13 +0200 Subject: [PATCH 19/37] make sure we forward the right mouse coords to video window --- src/wndproc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/wndproc.c b/src/wndproc.c index 91381cb..e812f9b 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -798,13 +798,6 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam case WM_MBUTTONDOWN: case WM_MOUSEMOVE: { - HWND video_hwnd = (HWND)InterlockedExchangeAdd((LONG*)&g_ddraw->video_window_hwnd, 0); - if (video_hwnd) - { - PostMessageA(video_hwnd, uMsg, wParam, lParam); - return 0; - } - if (!g_config.devmode && !g_mouse_locked) { return 0; @@ -838,6 +831,13 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam lParam = MAKELPARAM(x, y); + HWND video_hwnd = (HWND)InterlockedExchangeAdd((LONG*)&g_ddraw->video_window_hwnd, 0); + if (video_hwnd) + { + PostMessageA(video_hwnd, uMsg, wParam, lParam); + return 0; + } + break; } case WM_PARENTNOTIFY: From c8ef48c2c903042bcc864cdf57c671deec7fe7a5 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Sat, 17 Feb 2024 07:59:57 +0100 Subject: [PATCH 20/37] fix wayland bug (linux) --- src/dd.c | 30 ++++++++++++++++++++++++------ src/hook.c | 2 ++ src/utils.c | 1 + src/winapi_hooks.c | 25 +++++++++++++++++++++---- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/dd.c b/src/dd.c index 9027306..54ab14c 100644 --- a/src/dd.c +++ b/src/dd.c @@ -1006,13 +1006,31 @@ HRESULT dd_SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFl } } - if ((!d3d9_active || g_config.nonexclusive) && - ChangeDisplaySettings(&g_ddraw->render.mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) + if (!d3d9_active || g_config.nonexclusive) { - g_ddraw->render.run = FALSE; - g_config.windowed = TRUE; - g_config.fullscreen = TRUE; - return dd_SetDisplayMode(dwWidth, dwHeight, dwBPP, dwFlags); + if (ChangeDisplaySettings(&g_ddraw->render.mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) + { + g_ddraw->render.run = FALSE; + g_config.windowed = TRUE; + g_config.fullscreen = TRUE; + return dd_SetDisplayMode(dwWidth, dwHeight, dwBPP, dwFlags); + } + + /* + Fix wayland bug: + ChangeDisplaySettings fails silently - enable borderless mode in case display resolution was not changed + */ + if (g_ddraw->wine && + (g_ddraw->render.mode.dmPelsWidth != real_GetSystemMetrics(SM_CXSCREEN) || + g_ddraw->render.mode.dmPelsHeight != real_GetSystemMetrics(SM_CYSCREEN))) + { + ChangeDisplaySettings(NULL, 0); + + g_ddraw->render.run = FALSE; + g_config.windowed = TRUE; + g_config.fullscreen = TRUE; + return dd_SetDisplayMode(dwWidth, dwHeight, dwBPP, dwFlags); + } } if (g_ddraw->wine) diff --git a/src/hook.c b/src/hook.c index 4aa653d..1d73afe 100644 --- a/src/hook.c +++ b/src/hook.c @@ -479,6 +479,7 @@ void hook_create(HOOKLIST* hooks, BOOL initial_hook) BOOL is_local = _strnicmp(game_dir, mod_dir, strlen(game_dir)) == 0; if (is_local || + _strcmpi(mod_filename, "mciavi32") == 0 || _strcmpi(mod_filename, "MSVFW32") == 0 || _strcmpi(mod_filename, "quartz") == 0 || _strcmpi(mod_filename, "winmm") == 0) @@ -555,6 +556,7 @@ void hook_revert(HOOKLIST* hooks) BOOL is_local = _strnicmp(game_dir, mod_dir, strlen(game_dir)) == 0; if (is_local || + _strcmpi(mod_filename, "mciavi32") == 0 || _strcmpi(mod_filename, "MSVFW32") == 0 || _strcmpi(mod_filename, "quartz") == 0 || _strcmpi(mod_filename, "winmm") == 0) diff --git a/src/utils.c b/src/utils.c index 617beb8..028b93c 100644 --- a/src/utils.c +++ b/src/utils.c @@ -472,6 +472,7 @@ BOOL CALLBACK util_enum_child_proc(HWND hwnd, LPARAM lparam) if (g_config.fixchilds == FIX_CHILDS_DETECT_HIDE || strcmp(class_name, "VideoRenderer") == 0 || + strcmp(class_name, "MCIAVI") == 0 || strcmp(class_name, "AVIWnd32") == 0 || strcmp(class_name, "Afx:400000:3") == 0 || strcmp(class_name, "MCIWndClass") == 0) diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index 3f9da2c..a165b39 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -840,9 +840,26 @@ int WINAPI fake_StretchDIBits( UINT iUsage, DWORD rop) { - if (g_ddraw && g_ddraw->hwnd && WindowFromDC(hdc) == g_ddraw->hwnd) + HWND hwnd = WindowFromDC(hdc); + + char class_name[MAX_PATH] = { 0 }; + + if (g_ddraw && g_ddraw->hwnd && hwnd && hwnd != g_ddraw->hwnd) { - if (g_ddraw->primary && (g_ddraw->primary->bpp == 16 || g_ddraw->primary->bpp == 32 || g_ddraw->primary->palette)) + GetClassNameA(hwnd, class_name, sizeof(class_name) - 1); + } + + if (g_ddraw && g_ddraw->hwnd && + (hwnd == g_ddraw->hwnd || + (g_config.fixchilds && IsChild(g_ddraw->hwnd, hwnd) && + (g_config.fixchilds == FIX_CHILDS_DETECT_HIDE || + strcmp(class_name, "MCIAVI") == 0 || + strcmp(class_name, "AVIWnd32") == 0 || + strcmp(class_name, "Afx:400000:3") == 0 || + strcmp(class_name, "VideoRenderer") == 0 || + strcmp(class_name, "MCIWndClass") == 0)))) + { + if (0) // g_ddraw->primary && (g_ddraw->primary->bpp == 16 || g_ddraw->primary->bpp == 32 || g_ddraw->primary->palette)) { HDC primary_dc; dds_GetDC(g_ddraw->primary, &primary_dc); @@ -870,11 +887,11 @@ int WINAPI fake_StretchDIBits( return result; } } - else if (g_ddraw->width > 0) + else if (g_ddraw->width > 0 && g_ddraw->render.hdc) { return real_StretchDIBits( - hdc, + g_ddraw->render.hdc, xDest + g_ddraw->render.viewport.x, yDest + g_ddraw->render.viewport.y, (int)(DestWidth * g_ddraw->render.scale_w), From 0100459248db276523477254c970257173091759 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Sat, 1 Jun 2024 22:30:38 +0200 Subject: [PATCH 21/37] fix cutscene playbakc issues on windows 7 --- src/hook.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/hook.c b/src/hook.c index 1d73afe..6fc3abc 100644 --- a/src/hook.c +++ b/src/hook.c @@ -477,9 +477,12 @@ void hook_create(HOOKLIST* hooks, BOOL initial_hook) continue; BOOL is_local = _strnicmp(game_dir, mod_dir, strlen(game_dir)) == 0; + BOOL is_wine = real_GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != 0; + + BOOL wine_hook = is_wine && _strcmpi(mod_filename, "mciavi32") == 0; if (is_local || - _strcmpi(mod_filename, "mciavi32") == 0 || + wine_hook || _strcmpi(mod_filename, "MSVFW32") == 0 || _strcmpi(mod_filename, "quartz") == 0 || _strcmpi(mod_filename, "winmm") == 0) @@ -554,9 +557,12 @@ void hook_revert(HOOKLIST* hooks) _splitpath(mod_path, NULL, mod_dir, mod_filename, NULL); BOOL is_local = _strnicmp(game_dir, mod_dir, strlen(game_dir)) == 0; + BOOL is_wine = real_GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != 0; + + BOOL wine_hook = is_wine && _strcmpi(mod_filename, "mciavi32") == 0; if (is_local || - _strcmpi(mod_filename, "mciavi32") == 0 || + wine_hook || _strcmpi(mod_filename, "MSVFW32") == 0 || _strcmpi(mod_filename, "quartz") == 0 || _strcmpi(mod_filename, "winmm") == 0) From f3e69355e569d2ac616206c9fedb255b7751b583 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Sat, 1 Jun 2024 22:56:17 +0200 Subject: [PATCH 22/37] fix cutscene playback in some games --- inc/hook.h | 5 +++-- inc/winapi_hooks.h | 3 ++- src/IDirectDraw/IDirectDraw.c | 1 + src/hook.c | 9 ++++++++- src/winapi_hooks.c | 31 ++++++++++++++++++++++++++++++- 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/inc/hook.h b/inc/hook.h index 1663f99..7f9c017 100644 --- a/inc/hook.h +++ b/inc/hook.h @@ -1,10 +1,8 @@ #ifndef HOOK_H #define HOOK_H -#define WIN32_LEAN_AND_MEAN #include - #define HOOK_SKIP_2 0x00000001l #define HOOK_LOCAL_ONLY 0x00000002l @@ -59,6 +57,8 @@ typedef HMODULE(WINAPI* LOADLIBRARYEXWPROC)(LPCWSTR, HANDLE, DWORD); typedef FARPROC(WINAPI* GETPROCADDRESSPROC)(HMODULE, LPCSTR); typedef BOOL(WINAPI* GETDISKFREESPACEAPROC)(LPCSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD); typedef HRESULT(WINAPI* COCREATEINSTANCEPROC)(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID*); +typedef MCIERROR(WINAPI* MCISENDCOMMANDAPROC)(MCIDEVICEID, UINT, DWORD_PTR, DWORD_PTR); + typedef LPTOP_LEVEL_EXCEPTION_FILTER(WINAPI* SETUNHANDLEDEXCEPTIONFILTERPROC)(LPTOP_LEVEL_EXCEPTION_FILTER); extern GETCURSORPOSPROC real_GetCursorPos; @@ -102,6 +102,7 @@ extern LOADLIBRARYEXWPROC real_LoadLibraryExW; extern GETPROCADDRESSPROC real_GetProcAddress; extern GETDISKFREESPACEAPROC real_GetDiskFreeSpaceA; extern COCREATEINSTANCEPROC real_CoCreateInstance; +extern MCISENDCOMMANDAPROC real_mciSendCommandA; extern SETUNHANDLEDEXCEPTIONFILTERPROC real_SetUnhandledExceptionFilter; extern BOOL g_hook_active; diff --git a/inc/winapi_hooks.h b/inc/winapi_hooks.h index b2962da..f99fde1 100644 --- a/inc/winapi_hooks.h +++ b/inc/winapi_hooks.h @@ -1,7 +1,6 @@ #ifndef WINAPI_HOOKS_H #define WINAPI_HOOKS_H -#define WIN32_LEAN_AND_MEAN #include @@ -66,6 +65,8 @@ HWND WINAPI fake_CreateWindowExA( HRESULT WINAPI fake_CoCreateInstance( REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv); +MCIERROR WINAPI fake_mciSendCommandA(MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam); + LPTOP_LEVEL_EXCEPTION_FILTER WINAPI fake_SetUnhandledExceptionFilter( LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter); diff --git a/src/IDirectDraw/IDirectDraw.c b/src/IDirectDraw/IDirectDraw.c index 3bf3861..166d388 100644 --- a/src/IDirectDraw/IDirectDraw.c +++ b/src/IDirectDraw/IDirectDraw.c @@ -1,3 +1,4 @@ +#include #include #include "IDirectDraw.h" #include "IDirect3D.h" diff --git a/src/hook.c b/src/hook.c index 6fc3abc..628a5ae 100644 --- a/src/hook.c +++ b/src/hook.c @@ -1,4 +1,3 @@ -#define WIN32_LEAN_AND_MEAN #include #include #include @@ -57,6 +56,7 @@ LOADLIBRARYEXWPROC real_LoadLibraryExW = LoadLibraryExW; GETPROCADDRESSPROC real_GetProcAddress = GetProcAddress; GETDISKFREESPACEAPROC real_GetDiskFreeSpaceA = GetDiskFreeSpaceA; COCREATEINSTANCEPROC real_CoCreateInstance = CoCreateInstance; +MCISENDCOMMANDAPROC real_mciSendCommandA = mciSendCommandA; SETUNHANDLEDEXCEPTIONFILTERPROC real_SetUnhandledExceptionFilter = SetUnhandledExceptionFilter; HOOKLIST g_hook_hooklist[] = @@ -101,6 +101,13 @@ HOOKLIST g_hook_hooklist[] = { "CoCreateInstance", (PROC)fake_CoCreateInstance, (PROC*)&real_CoCreateInstance, HOOK_SKIP_2 }, { "", NULL, NULL, 0 } } + }, + { + "winmm.dll", + { + { "mciSendCommandA", (PROC)fake_mciSendCommandA, (PROC*)&real_mciSendCommandA, HOOK_SKIP_2 }, + { "", NULL, NULL, 0 } + } }, { "dinput.dll", diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index a165b39..3818fb5 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -1324,7 +1324,36 @@ HRESULT WINAPI fake_CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD } } - return real_CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); + /* These dlls must be hooked for cutscene uscaling and windowed mode */ + HMODULE quartz_dll = GetModuleHandleA("quartz"); + HMODULE msvfw32_dll = GetModuleHandleA("msvfw32"); + + HRESULT result = real_CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); + + if ((!quartz_dll && GetModuleHandleA("quartz")) || + (!msvfw32_dll && GetModuleHandleA("msvfw32"))) + { + hook_init(FALSE); + } + + return result; +} + +MCIERROR WINAPI fake_mciSendCommandA(MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam) +{ + /* These dlls must be hooked for cutscene uscaling and windowed mode */ + HMODULE quartz_dll = GetModuleHandleA("quartz"); + HMODULE msvfw32_dll = GetModuleHandleA("msvfw32"); + + MCIERROR result = real_mciSendCommandA(IDDevice, uMsg, fdwCommand, dwParam); + + if ((!quartz_dll && GetModuleHandleA("quartz")) || + (!msvfw32_dll && GetModuleHandleA("msvfw32"))) + { + hook_init(FALSE); + } + + return result; } LPTOP_LEVEL_EXCEPTION_FILTER WINAPI fake_SetUnhandledExceptionFilter( From ef0fff19bdce44fd1fe3efbf89bc7589cab6a323 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 1 Oct 2024 20:57:02 +0200 Subject: [PATCH 23/37] don't emulate 60hz vblank if we are running at 60hz already --- src/dd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/dd.c b/src/dd.c index 54ab14c..7aa729c 100644 --- a/src/dd.c +++ b/src/dd.c @@ -590,6 +590,11 @@ HRESULT dd_SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFl g_config.fullscreen = FALSE; } } + + if (g_config.maxgameticks == 0 && g_ddraw->mode.dmDisplayFrequency == 60) + { + g_config.maxgameticks == -2; + } } g_ddraw->render.width = g_config.window_rect.right; From 5ee245651eb3edf5822e5989cf35849ca834ef6c Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 1 Oct 2024 20:58:00 +0200 Subject: [PATCH 24/37] enable maintain aspect ratio by default --- src/config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config.c b/src/config.c index c736c97..80b9ee4 100644 --- a/src/config.c +++ b/src/config.c @@ -34,7 +34,7 @@ void cfg_load() GET_INT(g_config.window_rect.bottom, "height", 0); GET_BOOL(g_config.fullscreen, "fullscreen", FALSE); GET_BOOL(g_config.windowed, "windowed", FALSE); - GET_BOOL(g_config.maintas, "maintas", FALSE); + GET_BOOL(g_config.maintas, "maintas", TRUE); GET_BOOL(g_config.boxing, "boxing", FALSE); GET_INT(g_config.maxfps, "maxfps", -1); GET_BOOL(g_config.vsync, "vsync", FALSE); @@ -173,7 +173,7 @@ static void cfg_create_ini() "windowed=true\n" "\n" "; Maintain aspect ratio\n" - "maintas=false\n" + "maintas=true\n" "\n" "; Windowboxing / Integer Scaling\n" "boxing=false\n" From 9f58e7925d16112147dfc85491d280821ee90508 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 1 Oct 2024 20:59:42 +0200 Subject: [PATCH 25/37] fix for last commit --- src/dd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dd.c b/src/dd.c index 7aa729c..68dd028 100644 --- a/src/dd.c +++ b/src/dd.c @@ -593,7 +593,7 @@ HRESULT dd_SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFl if (g_config.maxgameticks == 0 && g_ddraw->mode.dmDisplayFrequency == 60) { - g_config.maxgameticks == -2; + g_config.maxgameticks = -2; } } From 0f575b40ea1c0ad5932d82df496b6ffbbc78830e Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 1 Oct 2024 21:02:02 +0200 Subject: [PATCH 26/37] enable singlecpu by default --- src/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 80b9ee4..2b66ab2 100644 --- a/src/config.c +++ b/src/config.c @@ -253,7 +253,7 @@ static void cfg_create_ini() "\n" "; Force CPU0 affinity, avoids crashes/freezing, *might* have a performance impact\n" "; Note: Disable this if the game is not running smooth or there are sound issues\n" - "singlecpu=false\n" + "singlecpu=true\n" "\n" "; Available resolutions, possible values: 0 = Small list, 1 = Very small list, 2 = Full list\n" "; Note: Set this to 2 if your chosen resolution is not working or does not show up in the list\n" From 411f0438274d1c4193aeb6f68dbb17d9ff62dcb8 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 6 Dec 2024 05:35:12 +0100 Subject: [PATCH 27/37] update makefile --- Makefile | 89 ++++++++++++++++++++++++++----------------------------- build.bat | 6 ++-- 2 files changed, 45 insertions(+), 50 deletions(-) diff --git a/Makefile b/Makefile index b10930b..1147210 100644 --- a/Makefile +++ b/Makefile @@ -1,53 +1,48 @@ -include config.mk -WINDRES ?= windres -LDFLAGS = -Iinc -Wall -Wl,--enable-stdcall-fixup -s -CFLAGS = -std=c99 -O2 -march=i486 -LIBS = -lgdi32 -lwinmm -lpsapi -ldbghelp -lole32 +TARGET ?= ddraw.dll -FILES = src/IDirect3D/IDirect3D.c \ - src/IDirect3D/IDirect3D2.c \ - src/IDirect3D/IDirect3D3.c \ - src/IDirect3D/IDirect3D7.c \ - src/IDirectDraw/IDirectDraw.c \ - src/IDirectDraw/IDirectDrawPalette.c \ - src/IDirectDraw/IDirectDrawClipper.c \ - src/IDirectDraw/IDirectDrawSurface.c \ - src/IDirectDraw/IDirectDrawGammaControl.c \ - src/IAMMediaStream/IAMMediaStream.c \ - src/crc32.c \ - src/blt.c \ - src/dd.c \ - src/ddpalette.c \ - src/ddsurface.c \ - src/ddclipper.c \ - src/render_ogl.c \ - src/render_gdi.c \ - src/render_d3d9.c \ - src/debug.c \ - src/mouse.c \ - src/winapi_hooks.c \ - src/screenshot.c \ - src/config.c \ - src/lodepng.c \ - src/directinput.c \ - src/hook.c \ - src/dllmain.c \ - src/wndproc.c \ - src/utils.c \ - src/fps_limiter.c \ - src/opengl_utils.c +LDFLAGS ?= -Wl,--enable-stdcall-fixup -s -static -shared +CFLAGS ?= -Iinc -O2 -Wall -std=c99 -Wno-incompatible-pointer-types +LIBS = -lgdi32 -lwinmm -lole32 -lMsimg32 -lPsapi -all: - $(info ) - $(info **********************************************************************************************) - $(info WARNING: This build is outdated and does not support all cnc-ddraw features [Detours/SEH]) - $(info WARNING: Some games that require hooks may crash or glitch, please use the msvc build instead) - $(info **********************************************************************************************) - $(info ) - $(WINDRES) -J rc ddraw.rc ddraw.rc.o - $(CC) $(CFLAGS) $(LDFLAGS) -shared -o ddraw.dll $(FILES) ddraw.def ddraw.rc.o $(LIBS) -# $(CC) $(CFLAGS) $(LDFLAGS) -nostdlib -shared -o ddraw.dll $(FILES) ddraw.def ddraw.rc.o $(LIBS) -lkernel32 -luser32 -lmsvcrt +COMMIT := $(shell git describe --match=NeVeRmAtCh --always --dirty || echo UNKNOWN) +BRANCH := $(shell git rev-parse --abbrev-ref HEAD || echo UNKNOWN) + +ECHOTEST := $(shell echo \"\") +ifeq ($(ECHOTEST),\"\") + # Windows + HASH := \# + ECOMMIT := $(shell echo $(HASH)define GIT_COMMIT "$(COMMIT)" > inc/git.h) + EBRANCH := $(shell echo $(HASH)define GIT_BRANCH "$(BRANCH)" >> inc/git.h) +else + # Either *nix or Windows with BusyBox (e.g. w64devkit) + ECOMMIT := $(shell echo "#define GIT_COMMIT" \"$(COMMIT)\" > inc/git.h) + EBRANCH := $(shell echo "#define GIT_BRANCH" \"$(BRANCH)\" >> inc/git.h) +endif + +ifdef DEBUG + CFLAGS += -D _DEBUG -D _DEBUG_X +endif + +ifdef _WIN32_WINNT + CFLAGS += -march=i486 -D _WIN32_WINNT=$(_WIN32_WINNT) +endif + +CC = i686-w64-mingw32-gcc +WINDRES ?= i686-w64-mingw32-windres + +SRCS := $(wildcard src/*.c) $(wildcard src/*/*.c) ddraw.rc +OBJS := $(addsuffix .o, $(basename $(SRCS))) + +.PHONY: clean all +all: $(TARGET) + +%.o: %.rc + $(WINDRES) -J rc $< $@ || windres -J rc $< $@ + +$(TARGET): $(OBJS) + $(CC) $(LDFLAGS) -o $@ $^ ddraw.def $(LIBS) clean: - $(RM) ddraw.dll ddraw.rc.o + $(RM) $(TARGET) $(OBJS) || del $(TARGET) $(subst /,\\,$(OBJS)) diff --git a/build.bat b/build.bat index 85a89a6..b3508d8 100644 --- a/build.bat +++ b/build.bat @@ -2,7 +2,7 @@ REM REM cnc-patch environment config REM -set PATH=C:\win-builds-patch-32\bin -gmake clean -gmake +set PATH=C:\w64devkit\bin +make clean +make pause From 0a7f877c8f61377c88f3173622a65b65b5950a00 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 6 Dec 2024 05:58:32 +0100 Subject: [PATCH 28/37] fix build on linux --- Makefile | 25 +------------------------ src/render_d3d9.c | 2 +- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/Makefile b/Makefile index 1147210..ba2ed6d 100644 --- a/Makefile +++ b/Makefile @@ -4,30 +4,7 @@ TARGET ?= ddraw.dll LDFLAGS ?= -Wl,--enable-stdcall-fixup -s -static -shared CFLAGS ?= -Iinc -O2 -Wall -std=c99 -Wno-incompatible-pointer-types -LIBS = -lgdi32 -lwinmm -lole32 -lMsimg32 -lPsapi - -COMMIT := $(shell git describe --match=NeVeRmAtCh --always --dirty || echo UNKNOWN) -BRANCH := $(shell git rev-parse --abbrev-ref HEAD || echo UNKNOWN) - -ECHOTEST := $(shell echo \"\") -ifeq ($(ECHOTEST),\"\") - # Windows - HASH := \# - ECOMMIT := $(shell echo $(HASH)define GIT_COMMIT "$(COMMIT)" > inc/git.h) - EBRANCH := $(shell echo $(HASH)define GIT_BRANCH "$(BRANCH)" >> inc/git.h) -else - # Either *nix or Windows with BusyBox (e.g. w64devkit) - ECOMMIT := $(shell echo "#define GIT_COMMIT" \"$(COMMIT)\" > inc/git.h) - EBRANCH := $(shell echo "#define GIT_BRANCH" \"$(BRANCH)\" >> inc/git.h) -endif - -ifdef DEBUG - CFLAGS += -D _DEBUG -D _DEBUG_X -endif - -ifdef _WIN32_WINNT - CFLAGS += -march=i486 -D _WIN32_WINNT=$(_WIN32_WINNT) -endif +LIBS = -lgdi32 -lwinmm -lole32 -lmsimg32 -lpsapi CC = i686-w64-mingw32-gcc WINDRES ?= i686-w64-mingw32-windres diff --git a/src/render_d3d9.c b/src/render_d3d9.c index cae506b..8898df4 100644 --- a/src/render_d3d9.c +++ b/src/render_d3d9.c @@ -10,7 +10,7 @@ #include "wndproc.h" #include "blt.h" #include "debug.h" -#include "D3d9types.h" +#include "d3d9types.h" #include "hook.h" #include "config.h" From 362400809978360558e7c7289b2fbebbab625784 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 6 Dec 2024 06:19:03 +0100 Subject: [PATCH 29/37] copy IAT hook changes from master branch --- src/hook.c | 55 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/src/hook.c b/src/hook.c index 628a5ae..b40977f 100644 --- a/src/hook.c +++ b/src/hook.c @@ -185,14 +185,22 @@ void hook_patch_obfuscated_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks, if (nt_headers->Signature != IMAGE_NT_SIGNATURE) return; - PIMAGE_IMPORT_DESCRIPTOR import_desc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)dos_header + - (DWORD)(nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)); + DWORD import_desc_rva = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + DWORD import_desc_size = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size; - if (import_desc == (PIMAGE_IMPORT_DESCRIPTOR)nt_headers) + if (import_desc_rva == 0 || import_desc_size == 0) return; + PIMAGE_IMPORT_DESCRIPTOR import_desc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)dos_header + import_desc_rva); + while (import_desc->FirstThunk) { + if (!import_desc->Name) + { + import_desc++; + continue; + } + for (int i = 0; hooks[i].module_name[0]; i++) { char* imp_module_name = (char*)((DWORD)dos_header + (DWORD)(import_desc->Name)); @@ -295,32 +303,43 @@ void hook_patch_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks, BOOL is_loc if (nt_headers->Signature != IMAGE_NT_SIGNATURE) return; - PIMAGE_IMPORT_DESCRIPTOR import_desc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)dos_header + - (DWORD)(nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)); + DWORD import_desc_rva = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + DWORD import_desc_size = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size; - if (import_desc == (PIMAGE_IMPORT_DESCRIPTOR)nt_headers) + if (import_desc_rva == 0 || import_desc_size == 0) return; + PIMAGE_IMPORT_DESCRIPTOR import_desc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)dos_header + import_desc_rva); + while (import_desc->FirstThunk) { + if (!import_desc->OriginalFirstThunk || !import_desc->Name) + { + import_desc++; + continue; + } + for (int i = 0; hooks[i].module_name[0]; i++) { - char* imp_module_name = (char*)((DWORD)dos_header + (DWORD)(import_desc->Name)); + char* imp_module_name = (char*)((DWORD)dos_header + import_desc->Name); if (_stricmp(imp_module_name, hooks[i].module_name) == 0) { - PIMAGE_THUNK_DATA first_thunk = - (PIMAGE_THUNK_DATA)((DWORD)dos_header + (DWORD)import_desc->FirstThunk); + PIMAGE_THUNK_DATA first_thunk = (void*)((DWORD)dos_header + import_desc->FirstThunk); + PIMAGE_THUNK_DATA o_first_thunk = (void*)((DWORD)dos_header + import_desc->OriginalFirstThunk); - PIMAGE_THUNK_DATA original_first_thunk = - (PIMAGE_THUNK_DATA)((DWORD)dos_header + (DWORD)import_desc->OriginalFirstThunk); - - while (first_thunk->u1.Function && original_first_thunk->u1.AddressOfData) + while (first_thunk->u1.Function) { - PIMAGE_IMPORT_BY_NAME import = - (PIMAGE_IMPORT_BY_NAME)((DWORD)dos_header + original_first_thunk->u1.AddressOfData); + if (!o_first_thunk->u1.AddressOfData) + { + first_thunk++; + o_first_thunk++; + continue; + } - if ((original_first_thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0) + PIMAGE_IMPORT_BY_NAME import = (void*)((DWORD)dos_header + o_first_thunk->u1.AddressOfData); + + if ((o_first_thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0) { for (int x = 0; hooks[i].data[x].function_name[0]; x++) { @@ -330,7 +349,7 @@ void hook_patch_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks, BOOL is_loc if (!is_local && (hooks[i].data[x].flags & HOOK_LOCAL_ONLY)) continue; - if (_stricmp((const char*)import->Name, hooks[i].data[x].function_name) == 0) + if (strcmp((const char*)import->Name, hooks[i].data[x].function_name) == 0) { DWORD op; @@ -367,7 +386,7 @@ void hook_patch_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks, BOOL is_loc } first_thunk++; - original_first_thunk++; + o_first_thunk++; } } } From ff9edf3e924f66fd974316cbcf23bdd83cd9b8d2 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 6 Dec 2024 06:21:51 +0100 Subject: [PATCH 30/37] fix some warnings --- src/dllmain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dllmain.c b/src/dllmain.c index d2bbec2..c5ef785 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -89,10 +89,10 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) if (status == ERROR_SUCCESS) { LPCTSTR x264 = "x264vfw.dll"; - RegSetValueExA(hkey,"vidc.x264", 0, REG_SZ, x264, strlen(x264) + 1); + RegSetValueExA(hkey,"vidc.x264", 0, REG_SZ, (const BYTE*)x264, strlen(x264) + 1); LPCTSTR xvid = "xvidvfw.dll"; - RegSetValueExA(hkey, "vidc.xvid", 0, REG_SZ, xvid, strlen(xvid) + 1); + RegSetValueExA(hkey, "vidc.xvid", 0, REG_SZ, (const BYTE*)xvid, strlen(xvid) + 1); RegCloseKey(hkey); } From 1e61ebc099d88a0ea79ab2909b41eb3d66a71513 Mon Sep 17 00:00:00 2001 From: EmoonX Date: Fri, 6 Dec 2024 14:55:50 -0300 Subject: [PATCH 31/37] Fix stretched HQ cutscene videos on Claw --- src/winapi_hooks.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index 3818fb5..929a1ff 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -889,13 +889,19 @@ int WINAPI fake_StretchDIBits( } else if (g_ddraw->width > 0 && g_ddraw->render.hdc) { + int base_width = g_ddraw->height * 4.0/3.0; + double scaling_factor = (double)g_ddraw->render.height / g_ddraw->height; + DestWidth = base_width * scaling_factor; + DestHeight = g_ddraw->render.height; + xDest += (g_ddraw->render.width - DestWidth) / 2; + return real_StretchDIBits( g_ddraw->render.hdc, - xDest + g_ddraw->render.viewport.x, - yDest + g_ddraw->render.viewport.y, - (int)(DestWidth * g_ddraw->render.scale_w), - (int)(DestHeight * g_ddraw->render.scale_h), + xDest, + yDest, + DestWidth, + DestHeight, xSrc, ySrc, SrcWidth, From 896c2f5def950e7e6350735eabd41dc8606fab53 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 6 Dec 2024 20:00:58 +0100 Subject: [PATCH 32/37] keep old maintas setting working for cutscenes --- src/winapi_hooks.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index 929a1ff..641adba 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -889,11 +889,23 @@ int WINAPI fake_StretchDIBits( } else if (g_ddraw->width > 0 && g_ddraw->render.hdc) { - int base_width = g_ddraw->height * 4.0/3.0; - double scaling_factor = (double)g_ddraw->render.height / g_ddraw->height; - DestWidth = base_width * scaling_factor; - DestHeight = g_ddraw->render.height; - xDest += (g_ddraw->render.width - DestWidth) / 2; + // new logic by emoon + // g_ddraw->width check detects new widescreen patch + if (g_ddraw->width > 640 && g_config.maintas) + { + int base_width = g_ddraw->height * 4.0 / 3.0; + double scaling_factor = (double)g_ddraw->render.height / g_ddraw->height; + DestWidth = base_width * scaling_factor; + DestHeight = g_ddraw->render.height; + xDest += (g_ddraw->render.width - DestWidth) / 2; + } + else // original 4:3 logic + { + xDest += g_ddraw->render.viewport.x; + yDest += g_ddraw->render.viewport.y; + DestWidth = (int)(DestWidth * g_ddraw->render.scale_w); + DestHeight = (int)(DestHeight * g_ddraw->render.scale_h); + } return real_StretchDIBits( From 721cf6616ae3529b2ba6e175bf4b462eb459f085 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 6 Dec 2024 20:01:49 +0100 Subject: [PATCH 33/37] make emoon's patch working on windows as well --- src/winapi_hooks.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index 641adba..a1687f9 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -759,6 +759,24 @@ BOOL WINAPI fake_StretchBlt( } else if (g_ddraw->width > 0 && g_ddraw->render.hdc) { + // new logic by emoon + // g_ddraw->width check detects new widescreen patch + if (g_ddraw->width > 640 && g_config.maintas) + { + int base_width = g_ddraw->height * 4.0 / 3.0; + double scaling_factor = (double)g_ddraw->render.height / g_ddraw->height; + wDest = base_width * scaling_factor; + hDest = g_ddraw->render.height; + xDest += (g_ddraw->render.width - wDest) / 2; + } + else // original 4:3 logic + { + xDest += g_ddraw->render.viewport.x; + yDest += g_ddraw->render.viewport.y; + wDest = (int)(wDest * g_ddraw->render.scale_w); + hDest = (int)(hDest * g_ddraw->render.scale_h); + } + return real_StretchBlt( g_ddraw->render.hdc, xDest + g_ddraw->render.viewport.x, From 4b9bd890a474ad3a537dd1f2f31de3b3b10d3470 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 6 Dec 2024 20:02:09 +0100 Subject: [PATCH 34/37] fix for last commit --- src/winapi_hooks.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index a1687f9..bb7da5d 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -779,10 +779,10 @@ BOOL WINAPI fake_StretchBlt( return real_StretchBlt( g_ddraw->render.hdc, - xDest + g_ddraw->render.viewport.x, - yDest + g_ddraw->render.viewport.y, - (int)(wDest * g_ddraw->render.scale_w), - (int)(hDest * g_ddraw->render.scale_h), + xDest, + yDest, + wDest, + hDest, hdcSrc, xSrc, ySrc, From c77a6ce19eec84f48d5fe056982ca291e4d3b2ae Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 6 Dec 2024 22:09:53 +0100 Subject: [PATCH 35/37] use HKLM for wine --- src/dllmain.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dllmain.c b/src/dllmain.c index c5ef785..b6c5f2b 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -73,10 +73,12 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) /* add registry key for x264vfw */ + BOOL is_wine = real_GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != 0; + HKEY hkey; LONG status = RegCreateKeyExA( - HKEY_CURRENT_USER, + is_wine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32", 0, NULL, From 92c0b2a3eddbfb4104f475dd49b8303ccdca11b6 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Mon, 16 Dec 2024 02:33:25 +0100 Subject: [PATCH 36/37] don't use DwmFlush in wine --- inc/fps_limiter.h | 1 + src/fps_limiter.c | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/inc/fps_limiter.h b/inc/fps_limiter.h index 5c8049f..019c3ef 100644 --- a/inc/fps_limiter.h +++ b/inc/fps_limiter.h @@ -48,6 +48,7 @@ typedef struct FPSLIMITER D3DKMTCLOSEADAPTERPROC D3DKMTCloseAdapter; BOOL got_adapter; BOOL initialized; + BOOL is_wine; } FPSLIMITER; extern FPSLIMITER g_fpsl; diff --git a/src/fps_limiter.c b/src/fps_limiter.c index 094f902..2652598 100644 --- a/src/fps_limiter.c +++ b/src/fps_limiter.c @@ -75,6 +75,8 @@ void fpsl_init() (D3DKMTCLOSEADAPTERPROC)real_GetProcAddress(g_fpsl.gdi32_dll, "D3DKMTCloseAdapter"); } + g_fpsl.is_wine = real_GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != 0; + g_fpsl.initialized = TRUE; } @@ -104,7 +106,12 @@ BOOL fpsl_wait_for_vblank(BOOL open_adapter) BOOL fpsl_dwm_flush() { - return g_fpsl.initialized && fpsl_dwm_is_enabled() && g_fpsl.DwmFlush && SUCCEEDED(g_fpsl.DwmFlush()); + return + g_fpsl.initialized && + fpsl_dwm_is_enabled() && + g_fpsl.DwmFlush && + !g_fpsl.is_wine && + SUCCEEDED(g_fpsl.DwmFlush()); } BOOL fpsl_dwm_is_enabled() From 3c3af81cd9f923c4f5dab4c6ac1e4749ac3ccda5 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Mon, 16 Dec 2024 02:34:10 +0100 Subject: [PATCH 37/37] try fpsl_wait_for_vblank first --- src/dd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dd.c b/src/dd.c index 68dd028..14b0874 100644 --- a/src/dd.c +++ b/src/dd.c @@ -1212,7 +1212,7 @@ HRESULT dd_WaitForVerticalBlank(DWORD dwFlags, HANDLE hEvent) { if (g_config.maxgameticks == -2) { - if (fpsl_dwm_flush() || fpsl_wait_for_vblank(g_config.maxfps >= 0 && !g_config.vsync)) + if (fpsl_wait_for_vblank(g_config.maxfps >= 0 && !g_config.vsync) || fpsl_dwm_flush()) return DD_OK; }