diff --git a/ddraw.dll b/ddraw.dll index a54de68..fd2497f 100644 Binary files a/ddraw.dll and b/ddraw.dll differ diff --git a/main.c b/main.c index 7fa3abf..7f144cb 100644 --- a/main.c +++ b/main.c @@ -231,6 +231,16 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD } This->render.run = TRUE; + + if (This->renderer == render_dummy_main) + { + 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); + } + return DD_OK; + } mouse_unlock(); @@ -289,6 +299,12 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD return DDERR_INVALIDMODE; } } + + 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); + } return DD_OK; } @@ -374,6 +390,8 @@ void ToggleFullscreen() LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + RECT rc = { 0, 0, ddraw->render.width, ddraw->render.height }; + switch(uMsg) { case WM_MOVE: @@ -519,6 +537,19 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; + /* make sure we redraw when WM_PAINT is requested */ + case WM_PAINT: + EnterCriticalSection(&ddraw->cs); + 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); @@ -621,6 +652,17 @@ ULONG __stdcall ddraw_Release(IDirectDrawImpl *This) { PostMessage(This->hWnd, WM_USER, 0, 0); } + + if (This->render.thread) + { + EnterCriticalSection(&This->cs); + HANDLE thread = This->render.thread; + This->render.thread = NULL; + ReleaseSemaphore(This->render.sem, 1, NULL); + LeaveCriticalSection(&This->cs); + + WaitForSingleObject(thread, INFINITE); + } if(This->render.hDC) { @@ -729,6 +771,7 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk } InitializeCriticalSection(&This->cs); + This->render.sem = CreateSemaphore(NULL, 0, 1, NULL); /* load configuration options from ddraw.ini */ char cwd[MAX_PATH]; diff --git a/palette.c b/palette.c index d50814c..efdfffe 100644 --- a/palette.c +++ b/palette.c @@ -58,6 +58,12 @@ HRESULT __stdcall ddraw_palette_SetEntries(IDirectDrawPaletteImpl *This, DWORD d This->data_rgb[i].rgbReserved = 0; } } + + /* FIXME: only refresh the screen when the primary palette is changed */ + if(ddraw->primary) + { + ReleaseSemaphore(ddraw->render.sem, 1, NULL); + } return DD_OK; } diff --git a/render.c b/render.c index 37869a0..5cc2180 100644 --- a/render.c +++ b/render.c @@ -89,7 +89,7 @@ DWORD WINAPI render_main(void) glEnable(GL_TEXTURE_2D); - while(ddraw->render.thread) + while(ddraw->render.thread && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED) { scale_w = (float)ddraw->width/tex_width; scale_h = (float)ddraw->height/tex_height; diff --git a/render_soft.c b/render_soft.c index d036c16..71dc188 100644 --- a/render_soft.c +++ b/render_soft.c @@ -95,7 +95,7 @@ DWORD WINAPI render_soft_main(void) frame_len = 1000.0f / ddraw->render.maxfps; } - while (ddraw->render.thread) + while (ddraw->render.thread && WaitForSingleObject(ddraw->render.sem, INFINITE) != WAIT_FAILED) { if(ddraw->render.maxfps > 0) { diff --git a/surface.c b/surface.c index 70db93b..ead1812 100644 --- a/surface.c +++ b/surface.c @@ -44,13 +44,6 @@ ULONG __stdcall ddraw_surface_Release(IDirectDrawSurfaceImpl *This) if(This->Ref == 0) { - if (ddraw->render.thread) - { - HANDLE thread = ddraw->render.thread; - ddraw->render.thread = NULL; - WaitForSingleObject(thread, INFINITE); - } - if(This->caps == DDSCAPS_PRIMARYSURFACE) { EnterCriticalSection(&ddraw->cs); @@ -129,6 +122,8 @@ HRESULT __stdcall ddraw_surface_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestR memcpy(to, from, s); LeaveCriticalSection(&ddraw->cs); + + ReleaseSemaphore(ddraw->render.sem, 1, NULL); } else { @@ -212,6 +207,11 @@ HRESULT __stdcall ddraw_surface_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWS printf("IDirectDrawSurface::Flip(This=%p, ...)\n", This); #endif + if(This->caps & DDSCAPS_PRIMARYSURFACE) + { + ReleaseSemaphore(ddraw->render.sem, 1, NULL); + } + return DD_OK; } @@ -320,11 +320,7 @@ HRESULT __stdcall ddraw_surface_Lock(IDirectDrawSurfaceImpl *This, LPRECT lpDest } #endif - HRESULT ret = ddraw_surface_GetSurfaceDesc(This, lpDDSurfaceDesc); - - //EnterCriticalSection(&ddraw->cs); - - return ret; + return ddraw_surface_GetSurfaceDesc(This, lpDDSurfaceDesc); } HRESULT __stdcall ddraw_surface_ReleaseDC(IDirectDrawSurfaceImpl *This, HDC a) @@ -379,7 +375,10 @@ HRESULT __stdcall ddraw_surface_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRe printf("DirectDrawSurface::Unlock(This=%p, lpRect=%p)\n", This, lpRect); #endif - //LeaveCriticalSection(&ddraw->cs); + if(This->caps & DDSCAPS_PRIMARYSURFACE && !(This->flags & DDSD_BACKBUFFERCOUNT)) + { + ReleaseSemaphore(ddraw->render.sem, 1, NULL); + } return DD_OK; } @@ -492,12 +491,6 @@ HRESULT __stdcall ddraw_CreateSurface(IDirectDrawImpl *This, LPDDSURFACEDESC lpD Surface->Ref = 0; ddraw_surface_AddRef(Surface); - if(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - { - This->render.thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)This->renderer, NULL, 0, NULL); - SetThreadPriority(This->render.thread, THREAD_PRIORITY_BELOW_NORMAL); - } - return DD_OK; }