From fd939bfff4d1170cfda9b7df6f81135acfab326f Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Fri, 18 May 2018 16:18:34 +0200 Subject: [PATCH] choose best renderer automatically --- inc/main.h | 1 + src/main.c | 12 +++++++++--- src/render.c | 48 +++++++++++++++++++++++++++++++++-------------- src/render_soft.c | 17 +++++++++-------- 4 files changed, 53 insertions(+), 25 deletions(-) diff --git a/inc/main.h b/inc/main.h index da98fea..be838f6 100644 --- a/inc/main.h +++ b/inc/main.h @@ -91,6 +91,7 @@ typedef struct IDirectDrawImpl BOOL fakecursorpos; BOOL noactivateapp; char shader[MAX_PATH]; + BOOL autorenderer; } IDirectDrawImpl; diff --git a/src/main.c b/src/main.c index 100f5cc..b7c7a1c 100644 --- a/src/main.c +++ b/src/main.c @@ -978,8 +978,8 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk "adjmouse=false\n" "; enable C&C video resize hack, auto = auto-detect game, true = forced, false = disabled\n" "vhack=false\n" - "; switch between OpenGL (opengl) and software (gdi) renderers\n" - "renderer=gdi\n" + "; switch between OpenGL (opengl) and software (gdi) renderers, (auto) = try opengl, fallback = gdi\n" + "renderer=auto\n" "; force CPU0 affinity, avoids crashes with RA, *might* have a performance impact\n" "singlecpu=true\n" "; Window position, -1 = center to screen\n" @@ -1131,7 +1131,7 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk This->vhack = 0; } - GetPrivateProfileStringA("ddraw", "renderer", "gdi", tmp, sizeof(tmp), SettingsIniPath); + GetPrivateProfileStringA("ddraw", "renderer", "auto", tmp, sizeof(tmp), SettingsIniPath); if(tolower(tmp[0]) == 'd' || tolower(tmp[0]) == 'd') { printf("DirectDrawCreate: Using dummy renderer\n"); @@ -1142,6 +1142,12 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk printf("DirectDrawCreate: Using software renderer\n"); This->renderer = render_soft_main; } + else if (tolower(tmp[0]) == 'a') + { + printf("DirectDrawCreate: Using automatic renderer\n"); + This->renderer = render_main; + This->autorenderer = TRUE; + } else { printf("DirectDrawCreate: Using OpenGL renderer\n"); diff --git a/src/render.c b/src/render.c index d5119d9..b7722f7 100644 --- a/src/render.c +++ b/src/render.c @@ -46,13 +46,26 @@ const GLchar *PaletteFragShaderSrc = BOOL detect_cutscene(); +DWORD WINAPI render_soft_main(void); DWORD WINAPI render_main(void) { Sleep(500); HGLRC hRC = wglCreateContext(ddraw->render.hDC); - wglMakeCurrent(ddraw->render.hDC, hRC); + BOOL madeCurrent = hRC && wglMakeCurrent(ddraw->render.hDC, hRC); + + if (!madeCurrent || (ddraw->autorenderer && glGetError() != GL_NO_ERROR)) + { + if (madeCurrent) + { + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hRC); + } + + ddraw->renderer = render_soft_main; + return render_soft_main(); + } OpenGL_Init(); @@ -71,18 +84,19 @@ DWORD WINAPI render_main(void) DWORD tick_start = 0; DWORD tick_end = 0; DWORD frame_len = 0; + int maxfps = ddraw->render.maxfps; - if (ddraw->render.maxfps < 0) - ddraw->render.maxfps = ddraw->mode.dmDisplayFrequency; + if (maxfps < 0) + maxfps = ddraw->mode.dmDisplayFrequency; - if (ddraw->render.maxfps == 0) - ddraw->render.maxfps = 125; + if (maxfps == 0) + maxfps = 125; - if (ddraw->render.maxfps >= 1000) - ddraw->render.maxfps = 0; + if (maxfps >= 1000) + maxfps = 0; - if (ddraw->render.maxfps > 0) - frame_len = 1000.0f / ddraw->render.maxfps; + if (maxfps > 0) + frame_len = 1000.0f / maxfps; int tex_width = ddraw->width <= 1024 ? 1024 : ddraw->width <= 2048 ? 2048 : ddraw->width <= 4096 ? 4096 : ddraw->width; @@ -247,11 +261,11 @@ DWORD WINAPI render_main(void) } glBindTexture(GL_TEXTURE_2D, 0); - - glEnable(GL_TEXTURE_2D); - while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED) + BOOL useOpenGL = !(ddraw->autorenderer && (!paletteConvProgram || glGetError() != GL_NO_ERROR)); + + while (useOpenGL && ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED) { #if _DEBUG static DWORD tick_fps = 0; @@ -269,7 +283,7 @@ DWORD WINAPI render_main(void) float scale_w = (float)ddraw->width / tex_width; float scale_h = (float)ddraw->height / tex_height; - if (ddraw->render.maxfps > 0) + if (maxfps > 0) tick_start = timeGetTime(); EnterCriticalSection(&ddraw->cs); @@ -414,7 +428,7 @@ DWORD WINAPI render_main(void) SwapBuffers(ddraw->render.hDC); - if (ddraw->render.maxfps > 0) + if (maxfps > 0) { tick_end = timeGetTime(); @@ -453,5 +467,11 @@ DWORD WINAPI render_main(void) wglMakeCurrent(NULL, NULL); wglDeleteContext(hRC); + if (!useOpenGL) + { + ddraw->renderer = render_soft_main; + render_soft_main(); + } + return 0; } diff --git a/src/render_soft.c b/src/render_soft.c index fed76c1..7927f31 100644 --- a/src/render_soft.c +++ b/src/render_soft.c @@ -70,15 +70,16 @@ DWORD WINAPI render_soft_main(void) DWORD tick_start = 0; DWORD tick_end = 0; DWORD frame_len = 0; + int maxfps = ddraw->render.maxfps; - if(ddraw->render.maxfps < 0) - ddraw->render.maxfps = ddraw->mode.dmDisplayFrequency; + if(maxfps < 0) + maxfps = ddraw->mode.dmDisplayFrequency; - if (ddraw->render.maxfps >= 1000) - ddraw->render.maxfps = 0; + if (maxfps >= 1000) + maxfps = 0; - if(ddraw->render.maxfps > 0) - frame_len = 1000.0f / ddraw->render.maxfps; + if(maxfps > 0) + frame_len = 1000.0f / maxfps; while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED) { @@ -95,7 +96,7 @@ DWORD WINAPI render_soft_main(void) frame_count++; #endif - if(ddraw->render.maxfps > 0) + if(maxfps > 0) { tick_start = timeGetTime(); } @@ -151,7 +152,7 @@ DWORD WINAPI render_soft_main(void) LeaveCriticalSection(&ddraw->cs); - if(ddraw->render.maxfps > 0) + if(maxfps > 0) { tick_end = timeGetTime();