From 8b4f94dcd8c83a2ed12b3d9d817171e94c4c53f3 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 26 Jul 2024 08:24:49 +0200 Subject: [PATCH 1/9] reduce delay for new zoom feature --- src/render_d3d9.c | 2 +- src/render_ogl.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/render_d3d9.c b/src/render_d3d9.c index c8e911e..9109f96 100644 --- a/src/render_d3d9.c +++ b/src/render_d3d9.c @@ -540,7 +540,7 @@ static BOOL d3d9_update_vertices(BOOL upscale_hack, BOOL stretch) DWORD WINAPI d3d9_render_main(void) { - Sleep(250); + //Sleep(250); fpsl_init(); diff --git a/src/render_ogl.c b/src/render_ogl.c index a348ed6..d1c7df2 100644 --- a/src/render_ogl.c +++ b/src/render_ogl.c @@ -52,7 +52,7 @@ BOOL ogl_create() DWORD WINAPI ogl_render_main(void) { - Sleep(250); + //Sleep(250); g_ogl.got_error = g_ogl.use_opengl = FALSE; GLenum err = GL_NO_ERROR; BOOL made_current = FALSE; @@ -91,8 +91,8 @@ DWORD WINAPI ogl_render_main(void) GL_CHECK(ogl_init_shader1_program()); GL_CHECK(ogl_init_shader2_program()); - GL_CHECK(g_ogl.got_error = g_ogl.got_error || !ogl_texture_upload_test()); - GL_CHECK(g_ogl.got_error = g_ogl.got_error || !ogl_shader_test()); + //GL_CHECK(g_ogl.got_error = g_ogl.got_error || !ogl_texture_upload_test()); + //GL_CHECK(g_ogl.got_error = g_ogl.got_error || !ogl_shader_test()); g_ogl.got_error = g_ogl.got_error || (err = glGetError()) != GL_NO_ERROR; g_ogl.use_opengl = (g_ogl.main_program || g_ddraw.bpp == 16 || g_ddraw.bpp == 32) && !g_ogl.got_error; From 72549b96103af9dbe2706dfef5715eab04b7f439 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 26 Jul 2024 08:25:36 +0200 Subject: [PATCH 2/9] disable some hooks to avoid conflicts with voobly patches --- src/hook.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hook.c b/src/hook.c index c9641f4..416125c 100644 --- a/src/hook.c +++ b/src/hook.c @@ -96,8 +96,8 @@ HOOKLIST g_hook_hooklist[] = { "ShowWindow", (PROC)fake_ShowWindow, (PROC*)&real_ShowWindow, 0 }, { "GetTopWindow", (PROC)fake_GetTopWindow, (PROC*)&real_GetTopWindow, 0 }, { "GetForegroundWindow", (PROC)fake_GetForegroundWindow, (PROC*)&real_GetForegroundWindow, 0 }, - { "PeekMessageA", (PROC)fake_PeekMessageA, (PROC*)&real_PeekMessageA, 0 }, - { "GetMessageA", (PROC)fake_GetMessageA, (PROC*)&real_GetMessageA, 0 }, + //{ "PeekMessageA", (PROC)fake_PeekMessageA, (PROC*)&real_PeekMessageA, 0 }, + //{ "GetMessageA", (PROC)fake_GetMessageA, (PROC*)&real_GetMessageA, 0 }, { "GetWindowPlacement", (PROC)fake_GetWindowPlacement, (PROC*)&real_GetWindowPlacement, 0 }, { "EnumDisplaySettingsA", (PROC)fake_EnumDisplaySettingsA, (PROC*)&real_EnumDisplaySettingsA, 0 }, { "GetKeyState", (PROC)fake_GetKeyState, (PROC*)&real_GetKeyState, 0 }, @@ -161,7 +161,7 @@ HOOKLIST g_hook_hooklist[] = { "kernel32.dll", { - { "LoadLibraryA", (PROC)fake_LoadLibraryA, (PROC*)&real_LoadLibraryA, HOOK_SKIP_2 }, + //{ "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 }, From fa14a8b60a21b334263718dfb0c89188021db477 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 26 Jul 2024 08:26:08 +0200 Subject: [PATCH 3/9] fix downscaling with GDI renderer --- src/render_gdi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/render_gdi.c b/src/render_gdi.c index 390fc56..3501bbd 100644 --- a/src/render_gdi.c +++ b/src/render_gdi.c @@ -37,6 +37,7 @@ DWORD WINAPI gdi_render_main(void) Sleep(500); fpsl_init(); + SetStretchBltMode(g_ddraw.render.hdc, COLORONCOLOR); DWORD timeout = g_config.minfps > 0 ? g_ddraw.minfps_tick_len : INFINITE; From 918037dd3e613e722cfb473c9821022409a028f6 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 26 Jul 2024 08:27:42 +0200 Subject: [PATCH 4/9] fix jumping cursor while zooming --- src/dd.c | 4 ++-- src/mouse.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/dd.c b/src/dd.c index 819a0fd..42921db 100644 --- a/src/dd.c +++ b/src/dd.c @@ -642,8 +642,8 @@ HRESULT dd_SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFl g_ddraw.height = dwHeight; g_ddraw.bpp = dwBPP; - InterlockedExchange((LONG*)&g_ddraw.cursor.x, dwWidth / 2); - InterlockedExchange((LONG*)&g_ddraw.cursor.y, dwHeight / 2); + //InterlockedExchange((LONG*)&g_ddraw.cursor.x, dwWidth / 2); + //InterlockedExchange((LONG*)&g_ddraw.cursor.y, dwHeight / 2); BOOL border = g_config.border; BOOL nonexclusive = FALSE; diff --git a/src/mouse.c b/src/mouse.c index c5b25eb..391e985 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -38,12 +38,35 @@ void mouse_lock() real_MapWindowPoints(g_ddraw.hwnd, HWND_DESKTOP, (LPPOINT)&rc, 2); OffsetRect(&rc, g_ddraw.render.viewport.x, g_ddraw.render.viewport.y); - int cur_x = InterlockedExchangeAdd((LONG*)&g_ddraw.cursor.x, 0); - int cur_y = InterlockedExchangeAdd((LONG*)&g_ddraw.cursor.y, 0); + POINT pt; + real_GetCursorPos(&pt); + + if (!g_config.windowed || real_ScreenToClient(g_ddraw.hwnd, &pt)) + { + if (pt.x > g_ddraw.render.viewport.x + g_ddraw.render.viewport.width || + pt.x < g_ddraw.render.viewport.x || + pt.y > g_ddraw.render.viewport.y + g_ddraw.render.viewport.height || + pt.y < g_ddraw.render.viewport.y) + { + pt.x = g_ddraw.width / 2; + pt.y = g_ddraw.height / 2; + } + else + { + pt.x = (DWORD)((pt.x - g_ddraw.render.viewport.x) * g_ddraw.mouse.unscale_x); + pt.y = (DWORD)((pt.y - g_ddraw.render.viewport.y) * g_ddraw.mouse.unscale_y); + } + + pt.x = min(pt.x, g_ddraw.width - 1); + pt.y = min(pt.y, g_ddraw.height - 1); + + InterlockedExchange((LONG*)&g_ddraw.cursor.x, pt.x); + InterlockedExchange((LONG*)&g_ddraw.cursor.y, pt.y); + } real_SetCursorPos( - g_config.adjmouse ? (int)(rc.left + (cur_x * g_ddraw.mouse.scale_x)) : rc.left + cur_x, - g_config.adjmouse ? (int)(rc.top + (cur_y * g_ddraw.mouse.scale_y)) : rc.top + cur_y); + g_config.adjmouse ? (int)(rc.left + (pt.x * g_ddraw.mouse.scale_x)) : rc.left + pt.x, + g_config.adjmouse ? (int)(rc.top + (pt.y * g_ddraw.mouse.scale_y)) : rc.top + pt.y); CopyRect(&rc, &g_ddraw.mouse.rc); real_MapWindowPoints(g_ddraw.hwnd, HWND_DESKTOP, (LPPOINT)&rc, 2); From ec0dbeca6bac5252a717a811c46c049f98290cfe Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 26 Jul 2024 08:29:43 +0200 Subject: [PATCH 5/9] add workaround for flickering (black frames) during zoom --- inc/dd.h | 1 + src/ddsurface.c | 3 +++ src/dllmain.c | 1 + src/render_d3d9.c | 3 +++ src/render_ogl.c | 3 +++ 5 files changed, 11 insertions(+) diff --git a/inc/dd.h b/inc/dd.h index bce317a..31708ff 100644 --- a/inc/dd.h +++ b/inc/dd.h @@ -168,6 +168,7 @@ typedef struct CNCDDRAW struct { + LONG frame_skip; BOOL enabled; } zoom; } CNCDDRAW; diff --git a/src/ddsurface.c b/src/ddsurface.c index 2f6a873..83e05b6 100644 --- a/src/ddsurface.c +++ b/src/ddsurface.c @@ -418,6 +418,9 @@ HRESULT dds_Blt( if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw.ref && g_ddraw.render.run) { + if (!(dwFlags & DDBLT_COLORFILL)) + InterlockedExchange(&g_ddraw.zoom.frame_skip, 0); + InterlockedExchange(&g_ddraw.render.surface_updated, TRUE); if (!(This->flags & DDSD_BACKBUFFERCOUNT) || This->last_flip_tick + FLIP_REDRAW_TIMEOUT < timeGetTime()) diff --git a/src/dllmain.c b/src/dllmain.c index b75c335..3dee497 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -152,6 +152,7 @@ void DDEnableZoom() TRACE("%s [%p]\n", __FUNCTION__, _ReturnAddress()); g_ddraw.zoom.enabled = TRUE; + InterlockedExchange(&g_ddraw.zoom.frame_skip, 20); } BOOL DDIsWindowed() diff --git a/src/render_d3d9.c b/src/render_d3d9.c index 9109f96..876618d 100644 --- a/src/render_d3d9.c +++ b/src/render_d3d9.c @@ -552,6 +552,9 @@ DWORD WINAPI d3d9_render_main(void) (g_config.minfps < 0 || WaitForSingleObject(g_ddraw.render.sem, timeout) != WAIT_FAILED) && g_ddraw.render.run) { + if (InterlockedDecrement(&g_ddraw.zoom.frame_skip) > 0) + continue; + #if _DEBUG dbg_draw_frame_info_start(); #endif diff --git a/src/render_ogl.c b/src/render_ogl.c index d1c7df2..fa4c9d1 100644 --- a/src/render_ogl.c +++ b/src/render_ogl.c @@ -887,6 +887,9 @@ static void ogl_render() (g_config.minfps < 0 || WaitForSingleObject(g_ddraw.render.sem, timeout) != WAIT_FAILED) && g_ddraw.render.run) { + if (InterlockedDecrement(&g_ddraw.zoom.frame_skip) > 0) + continue; + #if _DEBUG dbg_draw_frame_info_start(); #endif From 889cfd92fafd28064a7355cdbe6308a5e764d37d Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Sat, 27 Jul 2024 09:42:18 +0200 Subject: [PATCH 6/9] hook ValidateRect and InvalidateRect --- inc/hook.h | 5 +++++ inc/winapi_hooks.h | 2 ++ src/hook.c | 4 ++++ src/winapi_hooks.c | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+) diff --git a/inc/hook.h b/inc/hook.h index cd1dab8..f6d175f 100644 --- a/inc/hook.h +++ b/inc/hook.h @@ -58,6 +58,9 @@ typedef BOOL(WINAPI* PEEKMESSAGEAPROC)(LPMSG, HWND, UINT, UINT, UINT); typedef BOOL(WINAPI* GETMESSAGEAPROC)(LPMSG, HWND, UINT, UINT); typedef BOOL(WINAPI* GETWINDOWPLACEMENTPROC)(HWND, WINDOWPLACEMENT*); typedef BOOL(WINAPI* ENUMDISPLAYSETTINGSAPROC)(LPCSTR, DWORD, DEVMODEA*); + +typedef BOOL(WINAPI* VALIDATERECTPROC)(HWND, const RECT*); +typedef BOOL(WINAPI* INVALIDATERECTPROC)(HWND, const RECT*, BOOL); typedef SHORT(WINAPI* GETKEYSTATEPROC)(int); typedef SHORT(WINAPI* GETASYNCKEYSTATEPROC)(int); @@ -109,6 +112,8 @@ extern PEEKMESSAGEAPROC real_PeekMessageA; extern GETMESSAGEAPROC real_GetMessageA; extern GETWINDOWPLACEMENTPROC real_GetWindowPlacement; extern ENUMDISPLAYSETTINGSAPROC real_EnumDisplaySettingsA; +extern VALIDATERECTPROC real_ValidateRect; +extern INVALIDATERECTPROC real_InvalidateRect; extern GETKEYSTATEPROC real_GetKeyState; extern GETASYNCKEYSTATEPROC real_GetAsyncKeyState; extern GETDEVICECAPSPROC real_GetDeviceCaps; diff --git a/inc/winapi_hooks.h b/inc/winapi_hooks.h index 6e2965d..4ec75c9 100644 --- a/inc/winapi_hooks.h +++ b/inc/winapi_hooks.h @@ -34,6 +34,8 @@ BOOL WINAPI fake_PeekMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT w BOOL WINAPI fake_GetMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax); BOOL WINAPI fake_GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT* lpwndpl); BOOL WINAPI fake_EnumDisplaySettingsA(LPCSTR lpszDeviceName, DWORD iModeNum, DEVMODEA* lpDevMode); +BOOL WINAPI fake_ValidateRect(HWND hWnd, const RECT* lpRect); +BOOL WINAPI fake_InvalidateRect(HWND hWnd, const RECT* lpRect, BOOL bErase); SHORT WINAPI fake_GetKeyState(int nVirtKey); SHORT WINAPI fake_GetAsyncKeyState(int vKey); int WINAPI fake_GetDeviceCaps(HDC hdc, int index); diff --git a/src/hook.c b/src/hook.c index 416125c..bab3648 100644 --- a/src/hook.c +++ b/src/hook.c @@ -51,6 +51,8 @@ PEEKMESSAGEAPROC real_PeekMessageA = PeekMessageA; GETMESSAGEAPROC real_GetMessageA = GetMessageA; GETWINDOWPLACEMENTPROC real_GetWindowPlacement = GetWindowPlacement; ENUMDISPLAYSETTINGSAPROC real_EnumDisplaySettingsA = EnumDisplaySettingsA; +VALIDATERECTPROC real_ValidateRect = ValidateRect; +INVALIDATERECTPROC real_InvalidateRect = InvalidateRect; GETKEYSTATEPROC real_GetKeyState = GetKeyState; GETASYNCKEYSTATEPROC real_GetAsyncKeyState = GetAsyncKeyState; GETDEVICECAPSPROC real_GetDeviceCaps = GetDeviceCaps; @@ -100,6 +102,8 @@ HOOKLIST g_hook_hooklist[] = //{ "GetMessageA", (PROC)fake_GetMessageA, (PROC*)&real_GetMessageA, 0 }, { "GetWindowPlacement", (PROC)fake_GetWindowPlacement, (PROC*)&real_GetWindowPlacement, 0 }, { "EnumDisplaySettingsA", (PROC)fake_EnumDisplaySettingsA, (PROC*)&real_EnumDisplaySettingsA, 0 }, + { "ValidateRect", (PROC)fake_ValidateRect, (PROC*)&real_ValidateRect, 0 }, + { "InvalidateRect", (PROC)fake_InvalidateRect, (PROC*)&real_InvalidateRect, 0 }, { "GetKeyState", (PROC)fake_GetKeyState, (PROC*)&real_GetKeyState, 0 }, { "GetAsyncKeyState", (PROC)fake_GetAsyncKeyState, (PROC*)&real_GetAsyncKeyState, 0 }, { "SetForegroundWindow", (PROC)fake_SetForegroundWindow, (PROC*)&real_SetForegroundWindow, 0 }, diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index b856f0e..f6bd9e8 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -822,6 +822,46 @@ BOOL WINAPI fake_EnumDisplaySettingsA(LPCSTR lpszDeviceName, DWORD iModeNum, DEV return result; } +BOOL WINAPI fake_ValidateRect(HWND hWnd, const RECT* lpRect) +{ + if (!g_ddraw.ref || !g_ddraw.width || !g_ddraw.hwnd || hWnd != g_ddraw.hwnd || !lpRect) + return real_ValidateRect(hWnd, lpRect); + + RECT dst_rc; + + dst_rc.left = (LONG)(roundf(lpRect->left * g_ddraw.render.scale_w)); + dst_rc.top = (LONG)(roundf(lpRect->top * g_ddraw.render.scale_h)); + dst_rc.bottom = (LONG)(roundf(lpRect->bottom * g_ddraw.render.scale_h)); + dst_rc.right = (LONG)(roundf(lpRect->right * g_ddraw.render.scale_w)); + + OffsetRect( + &dst_rc, + g_ddraw.render.viewport.x, + g_ddraw.render.viewport.y); + + return real_ValidateRect(hWnd, lpRect); +} + +BOOL WINAPI fake_InvalidateRect(HWND hWnd, const RECT* lpRect, BOOL bErase) +{ + if (!g_ddraw.ref || !g_ddraw.width || !g_ddraw.hwnd || hWnd != g_ddraw.hwnd || !lpRect) + return real_InvalidateRect(hWnd, lpRect, bErase); + + RECT dst_rc; + + dst_rc.left = (LONG)(roundf(lpRect->left * g_ddraw.render.scale_w)); + dst_rc.top = (LONG)(roundf(lpRect->top * g_ddraw.render.scale_h)); + dst_rc.bottom = (LONG)(roundf(lpRect->bottom * g_ddraw.render.scale_h)); + dst_rc.right = (LONG)(roundf(lpRect->right * g_ddraw.render.scale_w)); + + OffsetRect( + &dst_rc, + g_ddraw.render.viewport.x, + g_ddraw.render.viewport.y); + + return real_InvalidateRect(hWnd, &dst_rc, bErase); +} + SHORT WINAPI fake_GetKeyState(int nVirtKey) { if (g_config.windowed && g_ddraw.ref && g_ddraw.hwnd && !util_in_foreground()) From 5919c0e1506cdfdc078d0e4daf5e72598725748b Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Sat, 27 Jul 2024 09:52:08 +0200 Subject: [PATCH 7/9] fix ValidateRect hook --- src/winapi_hooks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index f6bd9e8..7e5a688 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -839,7 +839,7 @@ BOOL WINAPI fake_ValidateRect(HWND hWnd, const RECT* lpRect) g_ddraw.render.viewport.x, g_ddraw.render.viewport.y); - return real_ValidateRect(hWnd, lpRect); + return real_ValidateRect(hWnd, &dst_rc); } BOOL WINAPI fake_InvalidateRect(HWND hWnd, const RECT* lpRect, BOOL bErase) From bb08a08af0825498dc87211f3e91261a0e1a9153 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Sun, 28 Jul 2024 04:39:22 +0200 Subject: [PATCH 8/9] adjust preset --- src/config.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/config.c b/src/config.c index 4d030de..0ca96a5 100644 --- a/src/config.c +++ b/src/config.c @@ -795,6 +795,7 @@ static void cfg_create_ini() "; Emperor: Rise of the Middle Kingdom\n" "[Emperor]\n" "nonexclusive=true\n" + "adjmouse=true\n" "\n" "; Enemy Infestation\n" "[EI]\n" From 798c281453e0b954a0880a399c2b2872209739c6 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Sat, 3 Aug 2024 08:22:50 +0200 Subject: [PATCH 9/9] only create opengl core context once --- src/render_ogl.c | 55 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/src/render_ogl.c b/src/render_ogl.c index fa4c9d1..e5befb2 100644 --- a/src/render_ogl.c +++ b/src/render_ogl.c @@ -41,6 +41,44 @@ BOOL ogl_create() g_ogl.hwnd = g_ddraw.hwnd; g_ogl.hdc = g_ddraw.render.hdc; + GLenum err = GL_NO_ERROR; + BOOL made_current = FALSE; + + for (int i = 0; i < 5; i++) + { + if ((made_current = xwglMakeCurrent(g_ogl.hdc, g_ogl.context))) + break; + + Sleep(50); + } + + if (made_current && (err = glGetError()) == GL_NO_ERROR) + { + GL_CHECK(oglu_init()); + + TRACE("+--OpenGL-----------------------------------------\n"); + TRACE("| GL_VERSION: %s\n", glGetString(GL_VERSION)); + TRACE("| GL_VENDOR: %s\n", glGetString(GL_VENDOR)); + TRACE("| GL_RENDERER: %s\n", glGetString(GL_RENDERER)); + TRACE("| GL_SHADING_LANGUAGE_VERSION: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); + TRACE("+------------------------------------------------\n"); + + GL_CHECK(g_ogl.context = ogl_create_core_context(g_ogl.hdc)); + } + else + { + TRACE("OpenGL error %08x, GetLastError %lu (xwglMakeCurrent())\n", err, GetLastError()); + ogl_check_error("xwglMakeCurrent()"); + } + + for (int i = 0; i < 5; i++) + { + if (xwglMakeCurrent(NULL, NULL)) + break; + + Sleep(50); + } + return TRUE; } @@ -69,15 +107,6 @@ DWORD WINAPI ogl_render_main(void) { GL_CHECK(oglu_init()); - TRACE("+--OpenGL-----------------------------------------\n"); - TRACE("| GL_VERSION: %s\n", glGetString(GL_VERSION)); - TRACE("| GL_VENDOR: %s\n", glGetString(GL_VENDOR)); - TRACE("| GL_RENDERER: %s\n", glGetString(GL_RENDERER)); - TRACE("| GL_SHADING_LANGUAGE_VERSION: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); - TRACE("+------------------------------------------------\n"); - - GL_CHECK(g_ogl.context = ogl_create_core_context(g_ogl.hdc)); - BOOL got_swap_ctrl; GL_CHECK(got_swap_ctrl = oglu_ext_exists("WGL_EXT_swap_control", g_ogl.hdc)); @@ -108,7 +137,13 @@ DWORD WINAPI ogl_render_main(void) ogl_check_error("xwglMakeCurrent()"); } - xwglMakeCurrent(NULL, NULL); + for (int i = 0; i < 5; i++) + { + if (xwglMakeCurrent(NULL, NULL)) + break; + + Sleep(50); + } if (!g_ogl.use_opengl) {