diff --git a/ddraw.rc b/ddraw.rc index bf6c152051..62e831b56a 100644 --- a/ddraw.rc +++ b/ddraw.rc @@ -1,6 +1,6 @@ 1 VERSIONINFO -FILEVERSION 1,1,1,0 -PRODUCTVERSION 1,1,1,0 +FILEVERSION 1,1,2,0 +PRODUCTVERSION 1,1,2,0 { BLOCK "StringFileInfo" { @@ -8,13 +8,13 @@ PRODUCTVERSION 1,1,1,0 { VALUE "CompanyName", "cncnet.org" VALUE "FileDescription", "DirectDraw replacement for C&C95 and Red Alert" - VALUE "FileVersion", "1.1.1.0" + VALUE "FileVersion", "1.1.2.0" VALUE "InternalName", "ddraw" VALUE "LegalCopyright", "Copyright (c) 2010-2017" VALUE "LegalTrademarks", "" VALUE "OriginalFileName", "ddraw.dll" VALUE "ProductName", "DirectDraw replacement for C&C95 and Red Alert" - VALUE "ProductVersion", "1.1.1.0" + VALUE "ProductVersion", "1.1.2.0" VALUE "Comments", "https://cncnet.org" } } diff --git a/src/main.c b/src/main.c index a112afbbb6..334d8d839b 100644 --- a/src/main.c +++ b/src/main.c @@ -191,6 +191,18 @@ HRESULT __stdcall ddraw_RestoreDisplayMode(IDirectDrawImpl *This) return DD_OK; } + /* only stop drawing in GL mode when minimized */ + if (This->renderer == render_main) + { + EnterCriticalSection(&This->cs); + This->render.run = FALSE; + ReleaseSemaphore(ddraw->render.sem, 1, NULL); + LeaveCriticalSection(&This->cs); + + WaitForSingleObject(This->render.thread, INFINITE); + This->render.thread = NULL; + } + if(!ddraw->windowed) { ChangeDisplaySettings(&This->mode, 0); @@ -237,7 +249,7 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD if(This->render.thread == NULL) { This->render.thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)This->renderer, NULL, 0, NULL); - SetThreadPriority(This->render.thread, THREAD_PRIORITY_BELOW_NORMAL); + //SetThreadPriority(This->render.thread, THREAD_PRIORITY_BELOW_NORMAL); } return DD_OK; } @@ -303,7 +315,7 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD if(This->render.thread == NULL) { This->render.thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)This->renderer, NULL, 0, NULL); - SetThreadPriority(This->render.thread, THREAD_PRIORITY_BELOW_NORMAL); + //SetThreadPriority(This->render.thread, THREAD_PRIORITY_BELOW_NORMAL); } return DD_OK; @@ -653,15 +665,15 @@ ULONG __stdcall ddraw_Release(IDirectDrawImpl *This) PostMessage(This->hWnd, WM_USER, 0, 0); } - if (This->render.thread) + if(This->render.run) { EnterCriticalSection(&This->cs); - HANDLE thread = This->render.thread; - This->render.thread = NULL; - ReleaseSemaphore(This->render.sem, 1, NULL); + This->render.run = FALSE; + ReleaseSemaphore(ddraw->render.sem, 1, NULL); LeaveCriticalSection(&This->cs); - - WaitForSingleObject(thread, INFINITE); + + WaitForSingleObject(This->render.thread, INFINITE); + This->render.thread = NULL; } if(This->render.hDC) @@ -669,6 +681,12 @@ ULONG __stdcall ddraw_Release(IDirectDrawImpl *This) ReleaseDC(This->hWnd, This->render.hDC); This->render.hDC = NULL; } + + if(This->render.ev) + { + CloseHandle(This->render.ev); + ddraw->render.ev = NULL; + } if(This->real_dll) { @@ -771,6 +789,7 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk } InitializeCriticalSection(&This->cs); + This->render.ev = CreateEvent(NULL, TRUE, FALSE, NULL); This->render.sem = CreateSemaphore(NULL, 0, 1, NULL); /* load configuration options from ddraw.ini */ @@ -795,7 +814,7 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk "; use letter- or windowboxing to make a best fit (GDI only!)\n" "boxing=false\n" "; real rendering rate, -1 = screen rate, 0 = unlimited, n = cap\n" - "max_fps=120\n" + "maxfps=0\n" "; vertical synchronization, enable if you get tearing (OpenGL only)\n" "vsync=false\n" "; scaling filter, nearest = sharp, linear = smooth (OpenGL only)\n" @@ -866,7 +885,7 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk GetPrivateProfileStringA("ddraw", "screenshotKey", "G", tmp, sizeof(tmp), SettingsIniPath); ddraw->screenshotKey = toupper(tmp[0]); - This->render.maxfps = GetPrivateProfileIntA("ddraw", "max_fps", 120, SettingsIniPath); + This->render.maxfps = GetPrivateProfileIntA("ddraw", "maxfps", 0, SettingsIniPath); This->render.width = GetPrivateProfileIntA("ddraw", "width", 0, SettingsIniPath); This->render.height = GetPrivateProfileIntA("ddraw", "height", 0, SettingsIniPath); WindowPosX = GetPrivateProfileIntA("ddraw", "posX", -1, SettingsIniPath); diff --git a/src/palette.c b/src/palette.c index efdfffe4aa..d5734769d9 100644 --- a/src/palette.c +++ b/src/palette.c @@ -60,7 +60,7 @@ HRESULT __stdcall ddraw_palette_SetEntries(IDirectDrawPaletteImpl *This, DWORD d } /* FIXME: only refresh the screen when the primary palette is changed */ - if(ddraw->primary) + if(ddraw->primary && ddraw->render.run) { ReleaseSemaphore(ddraw->render.sem, 1, NULL); } diff --git a/src/render.c b/src/render.c index 480ac051bf..a176ce95f0 100644 --- a/src/render.c +++ b/src/render.c @@ -52,8 +52,6 @@ BOOL detect_cutscene(); DWORD WINAPI render_main(void) { - Sleep(500); - int i,j; HGLRC hRC; @@ -147,7 +145,7 @@ DWORD WINAPI render_main(void) glEnable(GL_TEXTURE_2D); - while(ddraw->render.thread && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED) + while(ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED) { static int index = 0; scale_w = (float)ddraw->width/tex_width; @@ -229,7 +227,6 @@ DWORD WINAPI render_main(void) } } } - } LeaveCriticalSection(&ddraw->cs); @@ -260,6 +257,8 @@ DWORD WINAPI render_main(void) Sleep( frame_len - (tick_end - tick_start)); } } + + SetEvent(ddraw->render.ev); } HeapFree(GetProcessHeap(), 0, tex); diff --git a/src/render_soft.c b/src/render_soft.c index 8ec628a616..5121381354 100644 --- a/src/render_soft.c +++ b/src/render_soft.c @@ -51,8 +51,6 @@ BOOL detect_cutscene() DWORD WINAPI render_soft_main(void) { - Sleep(500); - PBITMAPINFO bmi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256); bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); @@ -97,7 +95,7 @@ DWORD WINAPI render_soft_main(void) frame_len = 1000.0f / ddraw->render.maxfps; } - while (ddraw->render.thread && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED) + while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED) { if(ddraw->render.maxfps > 0) { @@ -159,6 +157,8 @@ DWORD WINAPI render_soft_main(void) Sleep( frame_len - (tick_end - tick_start)); } } + + SetEvent(ddraw->render.ev); } HeapFree(GetProcessHeap(), 0, bmi); diff --git a/src/surface.c b/src/surface.c index 8ff2ea87c7..02090edfba 100644 --- a/src/surface.c +++ b/src/surface.c @@ -113,23 +113,18 @@ HRESULT __stdcall ddraw_surface_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestR unsigned char* from=Source->surface + y0*Source->width + x0; int s = x1-x0; - if((This->caps & DDSCAPS_PRIMARYSURFACE) && !(This->flags & DDSD_BACKBUFFERCOUNT)) - { - EnterCriticalSection(&ddraw->cs); - - int y; - for(y=y0; ywidth, from+=Source->width) - memcpy(to, from, s); - - ReleaseSemaphore(ddraw->render.sem, 1, NULL); - LeaveCriticalSection(&ddraw->cs); - } - else - { - int y; - for(y=y0; ywidth, from+=Source->width) - memcpy(to, from, s); - } + int y; + for(y=y0; ywidth, from+=Source->width) + { + memcpy(to, from, s); + } + } + + if(This->caps & DDSCAPS_PRIMARYSURFACE && !(This->flags & DDSD_BACKBUFFERCOUNT) && ddraw->render.run) + { + ReleaseSemaphore(ddraw->render.sem, 1, NULL); + WaitForSingleObject(ddraw->render.ev, INFINITE); + ResetEvent(ddraw->render.ev); } return DD_OK; @@ -206,9 +201,11 @@ HRESULT __stdcall ddraw_surface_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWS printf("IDirectDrawSurface::Flip(This=%p, ...)\n", This); #endif - if(This->caps & DDSCAPS_PRIMARYSURFACE) + if(This->caps & DDSCAPS_PRIMARYSURFACE && ddraw->render.run) { + ResetEvent(ddraw->render.ev); ReleaseSemaphore(ddraw->render.sem, 1, NULL); + WaitForSingleObject(ddraw->render.ev, INFINITE); } return DD_OK; @@ -374,7 +371,7 @@ HRESULT __stdcall ddraw_surface_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRe printf("DirectDrawSurface::Unlock(This=%p, lpRect=%p)\n", This, lpRect); #endif - if(This->caps & DDSCAPS_PRIMARYSURFACE && !(This->flags & DDSD_BACKBUFFERCOUNT)) + if(This->caps & DDSCAPS_PRIMARYSURFACE && !(This->flags & DDSD_BACKBUFFERCOUNT) && ddraw->render.run) { ReleaseSemaphore(ddraw->render.sem, 1, NULL); }