Compare commits

...

38 commits

Author SHA1 Message Date
FunkyFr3sh
3c3af81cd9 try fpsl_wait_for_vblank first 2024-12-16 02:34:10 +01:00
FunkyFr3sh
92c0b2a3ed don't use DwmFlush in wine 2024-12-16 02:33:25 +01:00
FunkyFr3sh
c77a6ce19e use HKLM for wine 2024-12-06 22:09:53 +01:00
FunkyFr3sh
4b9bd890a4 fix for last commit 2024-12-06 20:02:09 +01:00
FunkyFr3sh
721cf6616a make emoon's patch working on windows as well 2024-12-06 20:01:49 +01:00
FunkyFr3sh
896c2f5def keep old maintas setting working for cutscenes 2024-12-06 20:00:58 +01:00
FunkyFr3sh
a556262670
Merge pull request #362 from EmoonX/claw-movie-hq-widescreen-fix
Fix stretched HQ cutscene videos on widescreen Claw
2024-12-06 19:57:22 +01:00
EmoonX
1e61ebc099 Fix stretched HQ cutscene videos on Claw 2024-12-06 14:55:50 -03:00
FunkyFr3sh
ff9edf3e92 fix some warnings 2024-12-06 06:21:51 +01:00
FunkyFr3sh
3624008099 copy IAT hook changes from master branch 2024-12-06 06:19:03 +01:00
FunkyFr3sh
0a7f877c8f fix build on linux 2024-12-06 05:58:32 +01:00
FunkyFr3sh
411f043827 update makefile 2024-12-06 05:35:12 +01:00
FunkyFr3sh
0f575b40ea enable singlecpu by default 2024-10-01 21:02:02 +02:00
FunkyFr3sh
9f58e7925d fix for last commit 2024-10-01 20:59:42 +02:00
FunkyFr3sh
5ee245651e enable maintain aspect ratio by default 2024-10-01 20:58:00 +02:00
FunkyFr3sh
ef0fff19bd don't emulate 60hz vblank if we are running at 60hz already 2024-10-01 20:57:02 +02:00
FunkyFr3sh
f3e69355e5 fix cutscene playback in some games 2024-06-01 22:56:17 +02:00
FunkyFr3sh
0100459248 fix cutscene playbakc issues on windows 7 2024-06-01 22:30:38 +02:00
FunkyFr3sh
c8ef48c2c9 fix wayland bug (linux) 2024-02-17 07:59:57 +01:00
FunkyFr3sh
393627ee39 make sure we forward the right mouse coords to video window 2023-10-16 03:19:13 +02:00
FunkyFr3sh
ddfae6cd67 forward all input to video window 2023-10-16 03:08:29 +02:00
FunkyFr3sh
65969de0bd allow cursor unlock while video is playing 2023-10-16 02:18:22 +02:00
FunkyFr3sh
743907669e allow cursor lock while playing videos 2023-10-16 02:14:06 +02:00
FunkyFr3sh
e874a7e305 ignore mouse input while dvd video is playing 2023-10-16 02:12:29 +02:00
FunkyFr3sh
4d7fc88d37 block all keys except Esc while a dvd video is playing 2023-10-16 02:08:38 +02:00
FunkyFr3sh
b63410c444 add fix for custom levels 2023-10-08 11:59:09 +02:00
FunkyFr3sh
e3142956dc add support for xvid 2023-09-26 22:48:30 +02:00
FunkyFr3sh
7b7fefcad1 create registry key if it doesn't exist 2023-09-26 19:35:12 +02:00
FunkyFr3sh
3ad8a5bd0e add new hook flag for local hooks 2023-09-26 10:41:20 +02:00
FunkyFr3sh
68bd087cf0 re-enable hook 2023-09-26 10:02:01 +02:00
FunkyFr3sh
c8c7ead36e bump version 2023-09-26 07:18:41 +02:00
FunkyFr3sh
4d8181099c don't lock on WM_PAINT 2023-09-26 06:50:48 +02:00
FunkyFr3sh
2cf14bf2ef fix random freezing 2023-09-26 06:16:45 +02:00
FunkyFr3sh
e414568af4 fix color issues 2023-09-26 04:50:12 +02:00
FunkyFr3sh
e5fb4a061a fix upscaling on win10 2023-09-26 04:49:02 +02:00
FunkyFr3sh
a119eddd53 adjust default settings for claw 2023-09-26 02:27:00 +02:00
FunkyFr3sh
453d266d76 add temporary game patches for testing 2023-09-26 01:50:58 +02:00
FunkyFr3sh
b4b3e95832 dvd movie tests 2023-09-26 00:51:53 +02:00
20 changed files with 371 additions and 160 deletions

View file

@ -1,53 +1,25 @@
-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
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))

View file

@ -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

View file

@ -136,6 +136,7 @@ typedef struct CNCDDRAW
void* last_freed_palette; /* Dungeon Keeper hack */
void* last_freed_surface; /* Nox hack */
BOOL child_window_exists;
HWND video_window_hwnd;
BOOL got_child_windows;
DWORD last_set_window_pos_tick; /* WINE hack */
SPEEDLIMITER ticks_limiter;

View file

@ -48,6 +48,7 @@ typedef struct FPSLIMITER
D3DKMTCLOSEADAPTERPROC D3DKMTCloseAdapter;
BOOL got_adapter;
BOOL initialized;
BOOL is_wine;
} FPSLIMITER;
extern FPSLIMITER g_fpsl;

View file

@ -1,11 +1,10 @@
#ifndef HOOK_H
#define HOOK_H
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#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;
@ -58,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;
@ -101,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;
@ -109,7 +111,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);

View file

@ -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)

View file

@ -1,7 +1,6 @@
#ifndef WINAPI_HOOKS_H
#define WINAPI_HOOKS_H
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@ -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);

View file

@ -1,3 +1,4 @@
#include <windows.h>
#include <initguid.h>
#include "IDirectDraw.h"
#include "IDirect3D.h"

View file

@ -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);
@ -167,13 +167,13 @@ 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"
"maintas=true\n"
"\n"
"; Windowboxing / Integer Scaling\n"
"boxing=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,7 +249,7 @@ 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"

View file

@ -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;
@ -1006,13 +1011,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)
@ -1189,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;
}

View file

@ -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);

View file

@ -9,6 +9,7 @@
#include "debug.h"
#include "config.h"
#include "hook.h"
#include "patch.h"
/* export for cncnet cnc games */
@ -38,6 +39,70 @@ 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 */
BOOL is_wine = real_GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_version") != 0;
HKEY hkey;
LONG status =
RegCreateKeyExA(
is_wine ? HKEY_LOCAL_MACHINE : 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)
{
LPCTSTR x264 = "x264vfw.dll";
RegSetValueExA(hkey,"vidc.x264", 0, REG_SZ, (const BYTE*)x264, strlen(x264) + 1);
LPCTSTR xvid = "xvidvfw.dll";
RegSetValueExA(hkey, "vidc.xvid", 0, REG_SZ, (const BYTE*)xvid, strlen(xvid) + 1);
RegCloseKey(hkey);
}
char buf[1024];
if (GetEnvironmentVariable("__COMPAT_LAYER", buf, sizeof(buf)))

View file

@ -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()

View file

@ -1,4 +1,3 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
@ -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[] =
@ -98,33 +98,40 @@ 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 }
}
},
{
"winmm.dll",
{
{ "mciSendCommandA", (PROC)fake_mciSendCommandA, (PROC*)&real_mciSendCommandA, 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 +140,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 +167,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;
@ -178,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));
@ -212,6 +227,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 +286,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;
@ -285,39 +303,53 @@ void hook_patch_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->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++)
{
if (!unhook && !hooks[i].data[x].new_function)
continue;
if (_stricmp((const char*)import->Name, hooks[i].data[x].function_name) == 0)
if (!is_local && (hooks[i].data[x].flags & HOOK_LOCAL_ONLY))
continue;
if (strcmp((const char*)import->Name, hooks[i].data[x].function_name) == 0)
{
DWORD op;
@ -354,7 +386,7 @@ void hook_patch_iat_list(HMODULE hmod, BOOL unhook, HOOKLIST* hooks)
}
first_thunk++;
original_first_thunk++;
o_first_thunk++;
}
}
}
@ -415,7 +447,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 +502,18 @@ 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;
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 ||
wine_hook ||
_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 +525,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 +538,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 +582,18 @@ 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;
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 ||
wine_hook ||
_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 +605,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);
}
}

View file

@ -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"
@ -541,6 +541,7 @@ DWORD WINAPI d3d9_render_main(void)
if (g_config.fixchilds)
{
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)

View file

@ -84,6 +84,7 @@ DWORD WINAPI gdi_render_main(void)
if (g_config.fixchilds)
{
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);
}

View file

@ -770,6 +770,7 @@ static void ogl_render()
if (g_config.fixchilds)
{
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)

View file

@ -472,24 +472,18 @@ 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)
{
InterlockedExchangePointer(&g_ddraw->video_window_hwnd, hwnd);
LONG style = real_GetWindowLongA(hwnd, GWL_EXSTYLE);
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

View file

@ -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);
@ -757,12 +759,30 @@ 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,
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,
@ -838,9 +858,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);
@ -868,15 +905,33 @@ int WINAPI fake_StretchDIBits(
return result;
}
}
else if (g_ddraw->width > 0)
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;
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(
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),
g_ddraw->render.hdc,
xDest,
yDest,
DestWidth,
DestHeight,
xSrc,
ySrc,
SrcWidth,
@ -1190,22 +1245,15 @@ 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");
LoadLibraryA("MSVFW32.dll");
hook_init(FALSE);
}
/* Fix for SMACKW32.DLL creating another window that steals the focus */
@ -1312,7 +1360,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(

View file

@ -729,6 +729,13 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
}
}
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_KEYUP:
@ -736,6 +743,13 @@ 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);
HWND video_hwnd = (HWND)InterlockedExchangeAdd((LONG*)&g_ddraw->video_window_hwnd, 0);
if (video_hwnd)
{
PostMessageA(video_hwnd, uMsg, wParam, lParam);
return 0;
}
break;
}
/* button up messages reactivate cursor lock */
@ -817,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:
@ -854,9 +875,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: