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;
 }