diff --git a/inc/main.h b/inc/main.h index 430d9d4..cd1da26 100644 --- a/inc/main.h +++ b/inc/main.h @@ -35,6 +35,7 @@ BOOL detect_cutscene(); void LimitGameTicks(BOOL isBltOrFlip); DWORD WINAPI render_main(void); DWORD WINAPI render_soft_main(void); +BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam); struct IDirectDrawImpl; struct IDirectDrawImplVtbl; diff --git a/src/main.c b/src/main.c index 8142443..1d48fc3 100644 --- a/src/main.c +++ b/src/main.c @@ -103,6 +103,27 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) return TRUE; } +BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam) +{ + IDirectDrawSurfaceImpl *this = (IDirectDrawSurfaceImpl *)lParam; + + HDC hDC = GetDC(hWnd); + + RECT size; + GetClientRect(hWnd, &size); + + RECT pos; + GetWindowRect(hWnd, &pos); + + MapWindowPoints(HWND_DESKTOP, ddraw->hWnd, (LPPOINT)&pos, 2); + + BitBlt(hDC, 0, 0, size.right, size.bottom, this->hDC, pos.left, pos.top, SRCCOPY); + + ReleaseDC(hWnd, hDC); + + return FALSE; +} + static unsigned char getPixel(int x, int y) { return ((unsigned char *)ddraw->primary->surface)[y*ddraw->primary->lPitch + x*ddraw->primary->lXPitch]; @@ -709,6 +730,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { RECT rc = { 0, 0, ddraw->render.width, ddraw->render.height }; static BOOL inSizeMove = FALSE; + static int redrawCount = 0; switch(uMsg) { @@ -920,6 +942,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } } + if (!ddraw->hidemouse) + RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); + return DefWindowProc(hWnd, uMsg, wParam, lParam); /* Carmageddon fix */ } @@ -954,6 +979,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) InterlockedExchange(&ddraw->minimized, FALSE); } + + if (!ddraw->hidemouse) + RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); } else if (wParam == WA_INACTIVE) { @@ -1109,19 +1137,34 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; - /* make sure we redraw when WM_PAINT is requested */ + //Workaround for invisible menu on Load/Save/Delete in Tiberian Sun + case WM_PARENTNOTIFY: + { + if (!ddraw->hidemouse && LOWORD(wParam) == WM_DESTROY) + redrawCount = 2; + break; + } case WM_PAINT: - EnterCriticalSection(&ddraw->cs); - ReleaseSemaphore(ddraw->render.sem, 1, NULL); - LeaveCriticalSection(&ddraw->cs); - break; + { + if (!ddraw->hidemouse && redrawCount > 0) + { + redrawCount--; + RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); + } - case WM_ERASEBKGND: EnterCriticalSection(&ddraw->cs); - FillRect(ddraw->render.hDC, &rc, (HBRUSH) GetStockObject(BLACK_BRUSH)); ReleaseSemaphore(ddraw->render.sem, 1, NULL); LeaveCriticalSection(&ddraw->cs); break; + } + case WM_ERASEBKGND: + { + EnterCriticalSection(&ddraw->cs); + FillRect(ddraw->render.hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); + ReleaseSemaphore(ddraw->render.sem, 1, NULL); + LeaveCriticalSection(&ddraw->cs); + break; + } } return ddraw->WndProc(hWnd, uMsg, wParam, lParam); diff --git a/src/mouse.c b/src/mouse.c index c38c378..46eb1dd 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -311,14 +311,21 @@ void mouse_unlock() BOOL WINAPI fake_GetWindowRect(HWND hWnd, LPRECT lpRect) { - if (lpRect && ddraw && ddraw->hWnd == hWnd) + if (lpRect && ddraw) { - lpRect->bottom = ddraw->height; - lpRect->left = 0; - lpRect->right = ddraw->width; - lpRect->top = 0; + if (ddraw->hWnd == hWnd) + { + lpRect->bottom = ddraw->height; + lpRect->left = 0; + lpRect->right = ddraw->width; + lpRect->top = 0; - return TRUE; + return TRUE; + } + else + { + return GetWindowRect(hWnd, lpRect) && MapWindowPoints(HWND_DESKTOP, ddraw->hWnd, (LPPOINT)lpRect, 2); + } } return GetWindowRect(hWnd, lpRect); diff --git a/src/render.c b/src/render.c index 8e895c1..c837549 100644 --- a/src/render.c +++ b/src/render.c @@ -644,6 +644,9 @@ static void Render() if (glGetError() != GL_NO_ERROR) UseOpenGL = FALSE; } + + if (!ddraw->hidemouse) + EnumChildWindows(ddraw->hWnd, EnumChildProc, (LPARAM)ddraw->primary); } LeaveCriticalSection(&ddraw->cs); diff --git a/src/render_d3d9.c b/src/render_d3d9.c index 7dbd53e..9c54866 100644 --- a/src/render_d3d9.c +++ b/src/render_d3d9.c @@ -375,6 +375,9 @@ DWORD WINAPI render_d3d9_main(void) IDirect3DTexture9_UnlockRect(PaletteTex[palIndex], 0); } } + + if (!ddraw->hidemouse) + EnumChildWindows(ddraw->hWnd, EnumChildProc, (LPARAM)ddraw->primary); } LeaveCriticalSection(&ddraw->cs); diff --git a/src/render_soft.c b/src/render_soft.c index dfe0dcf..b1faf42 100644 --- a/src/render_soft.c +++ b/src/render_soft.c @@ -116,6 +116,9 @@ DWORD WINAPI render_soft_main(void) ddraw->primary->bmi, DIB_RGB_COLORS); } + + if (!ddraw->hidemouse) + EnumChildWindows(ddraw->hWnd, EnumChildProc, (LPARAM)ddraw->primary); } LeaveCriticalSection(&ddraw->cs);