From 14605cc479c00ea7cd489bc3bd462721f39dd67a Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Sun, 9 Jun 2024 15:54:39 +0200 Subject: [PATCH] port WinVidGameWindowProc --- docs/progress.svg | 16 ++-- docs/progress.txt | 3 +- src/decomp/decomp.c | 181 ++++++++++++++++++++++++++++++++++++++++++++ src/decomp/decomp.h | 2 + src/global/funcs.h | 1 - src/global/vars.h | 1 + src/inject_exec.c | 1 + 7 files changed, 195 insertions(+), 10 deletions(-) diff --git a/docs/progress.svg b/docs/progress.svg index 99e0f92..8ae8d4c 100644 --- a/docs/progress.svg +++ b/docs/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -41.63% (507) · 55.91% (681) · 0% (0) · 2.46% (30) +41.71% (508) · 55.83% (680) · 0% (0) · 2.46% (30) - - + + @@ -938,7 +938,7 @@ BOOL __stdcall EnumDisplayAdaptersCallback(GUID *lpGUID, LPTSTR lpDriverDescription, LPTSTR lpDriverName, LPVOID lpContext); void __thiscall S_FlaggedString_InitAdapter(DISPLAY_ADAPTER *adapter); bool __cdecl WinVidRegisterGameWindowClass(void); -LRESULT __stdcall WinVidGameWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +LRESULT __stdcall WinVidGameWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); void __cdecl WinVidResizeGameWindow(HWND hWnd, int32_t edge, LPRECT rect); bool __cdecl WinVidCheckGameWindowPalette(HWND hWnd); bool __cdecl WinVidCreateGameWindow(void); @@ -1298,10 +1298,10 @@ Tomb2.exe progress according to the function sizes: -38.48% · 61.19% · 0% · 0.33% +38.83% · 60.84% · 0% · 0.33% - - + + @@ -1348,7 +1348,7 @@ void __cdecl Camera_Update(void); void __cdecl Output_InsertTrans8(const PHD_VBUF *vbuf, int16_t shade); void __cdecl MonkControl(int16_t item_num); -LRESULT __stdcall WinVidGameWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +LRESULT __stdcall WinVidGameWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); int32_t __cdecl SkidooDynamics(ITEM_INFO *skidoo); void __cdecl do_sound_option(INVENTORY_ITEM *item); void __cdecl Sound_Effect(int32_t sample_id, const XYZ_32 *pos, uint32_t flags); diff --git a/docs/progress.txt b/docs/progress.txt index e13765f..f8dd2fe 100644 --- a/docs/progress.txt +++ b/docs/progress.txt @@ -3050,7 +3050,7 @@ typedef struct { 0x00445F40 0x01BE -R BOOL __stdcall EnumDisplayAdaptersCallback(GUID *lpGUID, LPTSTR lpDriverDescription, LPTSTR lpDriverName, LPVOID lpContext); 0x00446100 0x0035 + void __thiscall S_FlaggedString_InitAdapter(DISPLAY_ADAPTER *adapter); 0x00446140 0x006A +R bool __cdecl WinVidRegisterGameWindowClass(void); -0x004461B0 0x049F -R LRESULT __stdcall WinVidGameWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +0x004461B0 0x049F +R LRESULT __stdcall WinVidGameWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); 0x004467C0 0x01C0 -R void __cdecl WinVidResizeGameWindow(HWND hWnd, int32_t edge, LPRECT rect); 0x004469A0 0x00BC -R bool __cdecl WinVidCheckGameWindowPalette(HWND hWnd); 0x00446A60 0x00C6 -R bool __cdecl WinVidCreateGameWindow(void); @@ -3757,3 +3757,4 @@ typedef struct { 0x004D7EC8 - LPDIRECT3DMATERIAL2 g_D3DMaterial; 0x004D7ED4 - LPDIRECTDRAW g_DDrawInterface; 0x00466448 - const char g_GameClassName[]; +0x004D7ED8 - bool g_IsGameWindowChanging; diff --git a/src/decomp/decomp.c b/src/decomp/decomp.c index 4861778..a15af0d 100644 --- a/src/decomp/decomp.c +++ b/src/decomp/decomp.c @@ -2473,3 +2473,184 @@ bool __cdecl WinVidRegisterGameWindowClass(void) }; return RegisterClassExA(&wnd_class) != 0; } + +LRESULT CALLBACK +WinVidGameWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + if (g_IsFMVPlaying) { + switch (Msg) { + case WM_DESTROY: + g_IsGameWindowCreated = false; + g_GameWindowHandle = NULL; + PostQuitMessage(0); + break; + + case WM_MOVE: + g_GameWindowPositionX = (int)(short)LOWORD(lParam); + g_GameWindowPositionY = (int)(short)HIWORD(lParam); + break; + + case WM_ACTIVATEAPP: + g_IsGameWindowActive = (wParam != 0); + break; + + case WM_SYSCOMMAND: + if (wParam == SC_KEYMENU) { + return 0; + } + break; + } + return DefWindowProc(hWnd, Msg, wParam, lParam); + } + + switch (Msg) { + case WM_CREATE: + g_IsGameWindowCreated = true; + break; + + case WM_DESTROY: + g_IsGameWindowCreated = false; + g_GameWindowHandle = NULL; + PostQuitMessage(0); + break; + + case WM_MOVE: + g_GameWindowPositionX = (int)(short)LOWORD(lParam); + g_GameWindowPositionY = (int)(short)HIWORD(lParam); + break; + + case WM_SIZE: + switch (wParam) { + case SIZE_RESTORED: + g_IsGameWindowMinimized = false; + g_IsGameWindowMaximized = false; + break; + + case SIZE_MAXIMIZED: + g_IsGameWindowMinimized = false; + g_IsGameWindowMaximized = true; + break; + + case SIZE_MINIMIZED: + g_IsGameWindowMinimized = true; + g_IsGameWindowMaximized = false; + return DefWindowProc(hWnd, Msg, wParam, lParam); + + default: + return DefWindowProc(hWnd, Msg, wParam, lParam); + } + + if (g_IsGameFullScreen + || ((int)(short)LOWORD(lParam) == g_GameWindowWidth + && (int)(short)HIWORD(lParam) == g_GameWindowHeight)) { + break; + } + + g_GameWindowWidth = (int)(short)LOWORD(lParam); + g_GameWindowHeight = (int)(short)HIWORD(lParam); + if (g_IsGameWindowUpdating) { + break; + } + + UpdateGameResolution(); + break; + + case WM_PAINT: { + PAINTSTRUCT paint; + HDC hdc = BeginPaint(hWnd, &paint); + LPDDS surface = (g_SavedAppSettings.render_mode == RM_SOFTWARE) + ? g_RenderBufferSurface + : g_BackBufferSurface; + if (g_IsGameFullScreen || !g_PrimaryBufferSurface || !surface) { + HBRUSH brush = (HBRUSH)GetStockObject(BLACK_BRUSH); + FillRect(hdc, &paint.rcPaint, brush); + } else { + if (g_SavedAppSettings.render_mode == RM_SOFTWARE + && !WinVidCheckGameWindowPalette(hWnd) + && g_RenderBufferSurface) { + WinVidClearBuffer(g_RenderBufferSurface, NULL, 0); + } + UpdateFrame(false, NULL); + } + EndPaint(hWnd, &paint); + return 0; + } + + case WM_ACTIVATE: + if (LOWORD(wParam) && g_DDrawPalette != NULL + && g_PrimaryBufferSurface != NULL) { + g_PrimaryBufferSurface->lpVtbl->SetPalette( + g_PrimaryBufferSurface, g_DDrawPalette); + } + break; + + case WM_ERASEBKGND: + return 1; + + case WM_ACTIVATEAPP: + if (wParam && !g_IsGameWindowActive && g_IsGameFullScreen + && g_SavedAppSettings.render_mode == RM_HARDWARE) { + g_WinVidNeedToResetBuffers = true; + } + g_IsGameWindowActive = (wParam != 0); + break; + + case WM_SETCURSOR: + if (g_IsGameFullScreen) { + SetCursor(NULL); + return 1; + } + break; + + case WM_GETMINMAXINFO: + if (WinVidGetMinMaxInfo((LPMINMAXINFO)lParam)) { + return 0; + } + break; + + case WM_NCPAINT: + case WM_NCLBUTTONDOWN: + case WM_NCLBUTTONDBLCLK: + case WM_NCRBUTTONDOWN: + case WM_NCRBUTTONDBLCLK: + case WM_NCMBUTTONDOWN: + case WM_NCMBUTTONDBLCLK: + if (g_IsGameFullScreen) { + return 0; + } + break; + + case WM_SYSCOMMAND: + if (wParam == SC_KEYMENU) { + return 0; + } + break; + + case WM_SIZING: + WinVidResizeGameWindow(hWnd, wParam, (LPRECT)lParam); + break; + + case WM_MOVING: + if (g_IsGameFullScreen || g_IsGameWindowMaximized) { + GetWindowRect(hWnd, (LPRECT)lParam); + return 1; + } + break; + + case WM_ENTERSIZEMOVE: + g_IsGameWindowChanging = true; + break; + + case WM_EXITSIZEMOVE: + g_IsGameWindowChanging = false; + break; + + case WM_PALETTECHANGED: + if (hWnd != (HWND)wParam && !g_IsGameFullScreen && g_DDrawPalette) { + InvalidateRect(hWnd, NULL, FALSE); + } + break; + } + + return DefWindowProc(hWnd, Msg, wParam, lParam); +} diff --git a/src/decomp/decomp.h b/src/decomp/decomp.h index 4f6cb14..285eca8 100644 --- a/src/decomp/decomp.h +++ b/src/decomp/decomp.h @@ -114,3 +114,5 @@ bool __cdecl WinVidGetDisplayAdapters(void); bool __cdecl EnumerateDisplayAdapters( DISPLAY_ADAPTER_LIST *display_adapter_list); bool __cdecl WinVidRegisterGameWindowClass(void); +LRESULT CALLBACK +WinVidGameWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); diff --git a/src/global/funcs.h b/src/global/funcs.h index 079f806..f6842f3 100644 --- a/src/global/funcs.h +++ b/src/global/funcs.h @@ -444,7 +444,6 @@ #define GiantYetiControl ((void __cdecl (*)(int16_t item_num))0x00443050) #define YetiControl ((void __cdecl (*)(int16_t item_num))0x00443350) #define EnumDisplayAdaptersCallback ((BOOL __stdcall (*)(GUID *lpGUID, LPTSTR lpDriverDescription, LPTSTR lpDriverName, LPVOID lpContext))0x00445F40) -#define WinVidGameWindowProc ((LRESULT __stdcall (*)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam))0x004461B0) #define WinVidResizeGameWindow ((void __cdecl (*)(HWND hWnd, int32_t edge, LPRECT rect))0x004467C0) #define WinVidCheckGameWindowPalette ((bool __cdecl (*)(HWND hWnd))0x004469A0) #define WinVidCreateGameWindow ((bool __cdecl (*)(void))0x00446A60) diff --git a/src/global/vars.h b/src/global/vars.h index 0332e41..29ab66b 100644 --- a/src/global/vars.h +++ b/src/global/vars.h @@ -179,6 +179,7 @@ extern const char *g_TR2XVersion; #define g_D3DMaterial (*(LPDIRECT3DMATERIAL2*)0x004D7EC8) #define g_MinWindowClientHeight (*(int32_t*)0x004D7ED0) #define g_DDrawInterface (*(LPDIRECTDRAW*)0x004D7ED4) +#define g_IsGameWindowChanging (*(bool*)0x004D7ED8) #define g_MaxWindowHeight (*(int32_t*)0x004D7EDC) #define g_DDraw (*(LPDIRECTDRAW3*)0x004D7EE0) #define g_IsGameWindowCreated (*(bool*)0x004D7EE4) diff --git a/src/inject_exec.c b/src/inject_exec.c index 16a9cb5..192a85b 100644 --- a/src/inject_exec.c +++ b/src/inject_exec.c @@ -156,6 +156,7 @@ static void Inject_Decomp(const bool enable) INJECT(enable, 0x00445E50, WinVidGetDisplayAdapters); INJECT(enable, 0x00445F20, EnumerateDisplayAdapters); INJECT(enable, 0x00446140, WinVidRegisterGameWindowClass); + INJECT(enable, 0x004461B0, WinVidGameWindowProc); } static void Inject_Background(const bool enable)