Compare commits
38 commits
master
...
claw-movie
Author | SHA1 | Date | |
---|---|---|---|
|
3c3af81cd9 | ||
|
92c0b2a3ed | ||
|
c77a6ce19e | ||
|
4b9bd890a4 | ||
|
721cf6616a | ||
|
896c2f5def | ||
|
a556262670 | ||
|
1e61ebc099 | ||
|
ff9edf3e92 | ||
|
3624008099 | ||
|
0a7f877c8f | ||
|
411f043827 | ||
|
0f575b40ea | ||
|
9f58e7925d | ||
|
5ee245651e | ||
|
ef0fff19bd | ||
|
f3e69355e5 | ||
|
0100459248 | ||
|
c8ef48c2c9 | ||
|
393627ee39 | ||
|
ddfae6cd67 | ||
|
65969de0bd | ||
|
743907669e | ||
|
e874a7e305 | ||
|
4d7fc88d37 | ||
|
b63410c444 | ||
|
e3142956dc | ||
|
7b7fefcad1 | ||
|
3ad8a5bd0e | ||
|
68bd087cf0 | ||
|
c8c7ead36e | ||
|
4d8181099c | ||
|
2cf14bf2ef | ||
|
e414568af4 | ||
|
e5fb4a061a | ||
|
a119eddd53 | ||
|
453d266d76 | ||
|
b4b3e95832 |
20 changed files with 371 additions and 160 deletions
66
Makefile
66
Makefile
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
1
inc/dd.h
1
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;
|
||||
HWND video_window_hwnd;
|
||||
BOOL got_child_windows;
|
||||
DWORD last_set_window_pos_tick; /* WINE hack */
|
||||
SPEEDLIMITER ticks_limiter;
|
||||
|
|
|
@ -48,6 +48,7 @@ typedef struct FPSLIMITER
|
|||
D3DKMTCLOSEADAPTERPROC D3DKMTCloseAdapter;
|
||||
BOOL got_adapter;
|
||||
BOOL initialized;
|
||||
BOOL is_wine;
|
||||
} FPSLIMITER;
|
||||
|
||||
extern FPSLIMITER g_fpsl;
|
||||
|
|
10
inc/hook.h
10
inc/hook.h
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <windows.h>
|
||||
#include <initguid.h>
|
||||
#include "IDirectDraw.h"
|
||||
#include "IDirect3D.h"
|
||||
|
|
16
src/config.c
16
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);
|
||||
|
@ -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"
|
||||
|
|
37
src/dd.c
37
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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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()
|
||||
|
|
136
src/hook.c
136
src/hook.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
14
src/utils.c
14
src/utils.c
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue