diff --git a/inc/IDirectDrawSurface.h b/inc/IDirectDrawSurface.h
index b015fea..b6258be 100644
--- a/inc/IDirectDrawSurface.h
+++ b/inc/IDirectDrawSurface.h
@@ -35,6 +35,8 @@ typedef struct IDirectDrawSurfaceImpl
     DWORD last_flip_tick;
     DWORD last_blt_tick;
 
+    struct IDirectDrawSurfaceImpl *backbuffer;
+
 } IDirectDrawSurfaceImpl;
 
 typedef struct IDirectDrawSurfaceImplVtbl IDirectDrawSurfaceImplVtbl;
diff --git a/inc/dd.h b/inc/dd.h
index c423207..a6e6a2d 100644
--- a/inc/dd.h
+++ b/inc/dd.h
@@ -106,6 +106,7 @@ typedef struct cnc_ddraw
     BOOL nonexclusive;
     BOOL fixchildwindows;
     BOOL d3d9linear;
+    BOOL backbuffer;
     int maxgameticks;
     BOOL alt_key_down;
     BOOL bnet_active;
diff --git a/inc/ddsurface.h b/inc/ddsurface.h
index 5f9f388..87ee368 100644
--- a/inc/ddsurface.h
+++ b/inc/ddsurface.h
@@ -26,6 +26,8 @@ HRESULT dds_Lock(IDirectDrawSurfaceImpl* This, LPRECT lpDestRect, LPDDSURFACEDES
 HRESULT dds_SetColorKey(IDirectDrawSurfaceImpl* This, DWORD flags, LPDDCOLORKEY colorKey);
 HRESULT dds_SetPalette(IDirectDrawSurfaceImpl* This, LPDIRECTDRAWPALETTE lpDDPalette);
 HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPVOID lpRect);
+void* dds_GetBuffer(IDirectDrawSurfaceImpl* This);
+HDC dds_GetHDC(IDirectDrawSurfaceImpl* This);
 HRESULT dd_CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FAR* lpDDSurface, IUnknown FAR* unkOuter);
 
 
diff --git a/src/IDirectDraw/IDirectDrawSurface.c b/src/IDirectDraw/IDirectDrawSurface.c
index 1a6d008..fc90e20 100644
--- a/src/IDirectDraw/IDirectDrawSurface.c
+++ b/src/IDirectDraw/IDirectDrawSurface.c
@@ -86,6 +86,9 @@ ULONG __stdcall IDirectDrawSurface__Release(IDirectDrawSurfaceImpl *This)
         if (This->bmi)
             HeapFree(GetProcessHeap(), 0, This->bmi);
 
+        if (This->backbuffer)
+            IDirectDrawSurface_Release(This->backbuffer);
+
         if(This->palette && (!g_ddraw || (void*)This->palette != g_ddraw->last_freed_palette))
         {
             IDirectDrawPalette_Release(This->palette);
diff --git a/src/config.c b/src/config.c
index a6939f5..108eee4 100644
--- a/src/config.c
+++ b/src/config.c
@@ -50,6 +50,7 @@ void cfg_load()
     g_ddraw->nonexclusive = cfg_get_bool("nonexclusive", FALSE);
     g_ddraw->fixchildwindows = cfg_get_bool("fixchildwindows", TRUE);
     g_ddraw->d3d9linear = cfg_get_bool("d3d9linear", TRUE);
+    g_ddraw->backbuffer = cfg_get_bool("backbuffer", TRUE);
     g_ddraw->sierrahack = cfg_get_bool("sierrahack", FALSE); // Sierra Caesar III, Pharaoh, and Zeus hack
     g_ddraw->dk2hack = cfg_get_bool("dk2hack", FALSE); // Dungeon Keeper 2 hack
 
@@ -552,6 +553,11 @@ static void cfg_create_ini()
             "renderer=opengl\n"
             "nonexclusive=true\n"
             "\n"
+            "; Tzar: The Burden of the Crown\n"
+            "; Note: Must set 'DIRECTXDEVICE=0' in 'Tzar.ini'\n"
+            "[Tzar]\n"
+            "handlemouse=false\n"
+            "\n"
 
             , fh);
         fclose(fh);
diff --git a/src/ddsurface.c b/src/ddsurface.c
index c1681c2..088fd69 100644
--- a/src/ddsurface.c
+++ b/src/ddsurface.c
@@ -75,10 +75,12 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR
     int dst_x = dst_rect.left;
     int dst_y = dst_rect.top;
 
+    void* dst_buf = dds_GetBuffer(This);
+    void* src_buf = dds_GetBuffer(src_surface);
 
-    if (This->surface && (dwFlags & DDBLT_COLORFILL) && dst_w > 0 && dst_h > 0)
+    if (dst_buf && (dwFlags & DDBLT_COLORFILL) && dst_w > 0 && dst_h > 0)
     {
-        unsigned char *dst = (unsigned char *)This->surface + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
+        unsigned char *dst = (unsigned char *)dst_buf + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
         unsigned char *first_row = dst;
         unsigned int dst_pitch = dst_w * This->lx_pitch;
         int x, i;
@@ -151,11 +153,11 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR
 
                         for (x1 = 0; x1 < width; x1++)
                         {
-                            unsigned char c = ((unsigned char *)src_surface->surface)[x1 + src_x + ysrc];
+                            unsigned char c = ((unsigned char *)src_buf)[x1 + src_x + ysrc];
 
                             if (c < color_key.dwColorSpaceLowValue || c > color_key.dwColorSpaceHighValue)
                             {
-                                ((unsigned char *)This->surface)[x1 + dst_x + ydst] = c;
+                                ((unsigned char *)dst_buf)[x1 + dst_x + ydst] = c;
                             }
                         }
                     }
@@ -170,11 +172,11 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR
 
                         for (x1 = 0; x1 < width; x1++)
                         {
-                            unsigned short c = ((unsigned short *)src_surface->surface)[x1 + src_x + ysrc];
+                            unsigned short c = ((unsigned short *)src_buf)[x1 + src_x + ysrc];
 
                             if (c < color_key.dwColorSpaceLowValue || c > color_key.dwColorSpaceHighValue)
                             {
-                                ((unsigned short *)This->surface)[x1 + dst_x + ydst] = c;
+                                ((unsigned short *)dst_buf)[x1 + dst_x + ydst] = c;
                             }
                         }
                     }
@@ -193,10 +195,10 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR
                 int height = dst_h > src_h ? src_h : dst_h;
 
                 unsigned char *src = 
-                    (unsigned char *)src_surface->surface + (src_x * src_surface->lx_pitch) + (src_surface->l_pitch * src_y);
+                    (unsigned char *)src_buf + (src_x * src_surface->lx_pitch) + (src_surface->l_pitch * src_y);
 
                 unsigned char *dst = 
-                    (unsigned char *)This->surface + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
+                    (unsigned char *)dst_buf + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
 
                 unsigned int dst_pitch = width * This->lx_pitch;
 
@@ -316,8 +318,8 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR
                         if (This->bpp == 8)
                         {
                             unsigned char *d, *s, v;
-                            unsigned char *src = (unsigned char *)src_surface->surface;
-                            unsigned char *dst = (unsigned char *)This->surface;
+                            unsigned char *src = (unsigned char *)src_buf;
+                            unsigned char *dst = (unsigned char *)dst_buf;
 
                             do {
                                 switch (current->type)
@@ -355,8 +357,8 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR
                         else if (This->bpp == 16)
                         {
                             unsigned short *d, *s, v;
-                            unsigned short *src = (unsigned short *)src_surface->surface;
-                            unsigned short *dst = (unsigned short *)This->surface;
+                            unsigned short *src = (unsigned short *)src_buf;
+                            unsigned short *dst = (unsigned short *)dst_buf;
 
                             do {
                                 switch (current->type)
@@ -466,6 +468,9 @@ HRESULT dds_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDI
     int dst_w = dst_rect.right - dst_rect.left;
     int dst_h = dst_rect.bottom - dst_rect.top;
 
+    void* dst_buf = dds_GetBuffer(This);
+    void* src_buf = dds_GetBuffer(src_surface);
+
     if (src_surface && dst_w > 0 && dst_h > 0)
     {
         if (flags & DDBLTFAST_SRCCOLORKEY)
@@ -480,11 +485,11 @@ HRESULT dds_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDI
 
                     for (x1 = 0; x1 < dst_w; x1++)
                     {
-                        unsigned char c = ((unsigned char *)src_surface->surface)[x1 + src_x + ysrc];
+                        unsigned char c = ((unsigned char *)src_buf)[x1 + src_x + ysrc];
 
                         if (c < src_surface->color_key.dwColorSpaceLowValue || c > src_surface->color_key.dwColorSpaceHighValue)
                         {
-                            ((unsigned char *)This->surface)[x1 + dst_x + ydst] = c;
+                            ((unsigned char *)dst_buf)[x1 + dst_x + ydst] = c;
                         }
                     }
                 }
@@ -499,11 +504,11 @@ HRESULT dds_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDI
 
                     for (x1 = 0; x1 < dst_w; x1++)
                     {
-                        unsigned short c = ((unsigned short *)src_surface->surface)[x1 + src_x + ysrc];
+                        unsigned short c = ((unsigned short *)src_buf)[x1 + src_x + ysrc];
                         
                         if (c < src_surface->color_key.dwColorSpaceLowValue || c > src_surface->color_key.dwColorSpaceHighValue)
                         {
-                            ((unsigned short *)This->surface)[x1 + dst_x + ydst] = c;
+                            ((unsigned short *)dst_buf)[x1 + dst_x + ydst] = c;
                         }
                     }
                 }
@@ -512,10 +517,10 @@ HRESULT dds_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDI
         else
         {
             unsigned char *src =
-                (unsigned char *)src_surface->surface + (src_x * src_surface->lx_pitch) + (src_surface->l_pitch * src_y);
+                (unsigned char *)src_buf + (src_x * src_surface->lx_pitch) + (src_surface->l_pitch * src_y);
 
             unsigned char *dst =
-                (unsigned char *)This->surface + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
+                (unsigned char *)dst_buf + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
 
             unsigned int dst_pitch = dst_w * This->lx_pitch;
 
@@ -591,7 +596,7 @@ HRESULT dds_GetSurfaceDesc(IDirectDrawSurfaceImpl *This, LPDDSURFACEDESC lpDDSur
         lpDDSurfaceDesc->dwWidth = This->width;
         lpDDSurfaceDesc->dwHeight = This->height;
         lpDDSurfaceDesc->lPitch = This->l_pitch;
-        lpDDSurfaceDesc->lpSurface = This->surface;
+        lpDDSurfaceDesc->lpSurface = dds_GetBuffer(This);
         lpDDSurfaceDesc->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
         lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB;
         lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = This->bpp;
@@ -634,6 +639,19 @@ HRESULT dds_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWSURFACE surface, DWOR
 {
     if(This->caps & DDSCAPS_PRIMARYSURFACE && g_ddraw->render.run)
     {
+        if (This->backbuffer)
+        {
+            EnterCriticalSection(&g_ddraw->cs);
+            void* surface = InterlockedExchangePointer(&This->surface, This->backbuffer->surface);
+            HBITMAP bitmap = (HBITMAP)InterlockedExchangePointer(&This->bitmap, This->backbuffer->bitmap);
+            HDC hdc = (HDC)InterlockedExchangePointer(&This->hdc, This->backbuffer->hdc);
+
+            InterlockedExchangePointer(&This->backbuffer->surface, surface);
+            InterlockedExchangePointer(&This->backbuffer->bitmap, bitmap);
+            InterlockedExchangePointer(&This->backbuffer->hdc, hdc);
+            LeaveCriticalSection(&g_ddraw->cs);
+        }
+
         This->last_flip_tick = timeGetTime();
 
         InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
@@ -659,8 +677,16 @@ HRESULT dds_GetAttachedSurface(IDirectDrawSurfaceImpl *This, LPDDSCAPS lpDdsCaps
 {
     if ((This->caps & DDSCAPS_PRIMARYSURFACE) && (This->caps & DDSCAPS_FLIP) && (lpDdsCaps->dwCaps & DDSCAPS_BACKBUFFER))
     {
-        IDirectDrawSurface_AddRef(This);
-        *surface = (LPDIRECTDRAWSURFACE)This;
+        if (This->backbuffer)
+        {
+            IDirectDrawSurface_AddRef(This->backbuffer);
+            *surface = (LPDIRECTDRAWSURFACE)This->backbuffer;
+        }
+        else
+        {
+            IDirectDrawSurface_AddRef(This);
+            *surface = (LPDIRECTDRAWSURFACE)This;
+        }
     }
 
     return DD_OK;
@@ -696,9 +722,9 @@ HRESULT dds_GetDC(IDirectDrawSurfaceImpl *This, HDC FAR *a)
         NULL;
 
     if (data)
-        SetDIBColorTable(This->hdc, 0, 256, data);
+        SetDIBColorTable(dds_GetHDC(This), 0, 256, data);
 
-    *a = This->hdc;
+    *a = dds_GetHDC(This);
     return DD_OK;
 }
 
@@ -752,7 +778,7 @@ HRESULT dds_Lock(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDDSURFACEDES
     if (lpDestRect && lpDDSurfaceDesc && lpDestRect->left >= 0 && lpDestRect->top >= 0)
     {
         lpDDSurfaceDesc->lpSurface = 
-            (char*)This->surface + (lpDestRect->left * This->lx_pitch) + (lpDestRect->top * This->l_pitch);
+            (char*)dds_GetBuffer(This) + (lpDestRect->left * This->lx_pitch) + (lpDestRect->top * This->l_pitch);
     }
 
     return ret;
@@ -810,12 +836,12 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRect)
     if (hwnd && (This->caps & DDSCAPS_PRIMARYSURFACE))
     {
         if (g_ddraw->primary->palette && g_ddraw->primary->palette->data_rgb)
-            SetDIBColorTable(g_ddraw->primary->hdc, 0, 256, g_ddraw->primary->palette->data_rgb);
+            SetDIBColorTable(dds_GetHDC(g_ddraw->primary), 0, 256, g_ddraw->primary->palette->data_rgb);
 
         //GdiTransparentBlt idea taken from Aqrit's war2 ddraw
 
         RGBQUAD quad;
-        GetDIBColorTable(g_ddraw->primary->hdc, 0xFE, 1, &quad);
+        GetDIBColorTable(dds_GetHDC(g_ddraw->primary), 0xFE, 1, &quad);
         COLORREF color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
         BOOL erase = FALSE;
 
@@ -835,7 +861,7 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRect)
                     0,
                     rc.right - rc.left,
                     rc.bottom - rc.top,
-                    g_ddraw->primary->hdc,
+                    dds_GetHDC(g_ddraw->primary),
                     rc.left,
                     rc.top,
                     rc.right - rc.left,
@@ -878,6 +904,28 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRect)
     return DD_OK;
 }
 
+void* dds_GetBuffer(IDirectDrawSurfaceImpl* This)
+{
+    if (!This)
+        return NULL;
+
+    if (This->backbuffer || (This->caps & DDSCAPS_BACKBUFFER))
+        return (void*)InterlockedExchangeAdd(&This->surface, 0);
+
+    return This->surface;
+}
+
+HDC dds_GetHDC(IDirectDrawSurfaceImpl* This)
+{
+    if (!This)
+        return NULL;
+
+    if (This->backbuffer || (This->caps & DDSCAPS_BACKBUFFER))
+        return (HDC)InterlockedExchangeAdd(&This->hdc, 0);
+
+    return This->hdc;
+}
+
 HRESULT dd_CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FAR *lpDDSurface, IUnknown FAR * unkOuter)
 {
     dbg_dump_dds_flags(lpDDSurfaceDesc->dwFlags);
@@ -980,6 +1028,19 @@ HRESULT dd_CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FA
     if (lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT)
     {
         dprintf("     dwBackBufferCount=%d\n", lpDDSurfaceDesc->dwBackBufferCount);
+
+        if (g_ddraw->backbuffer)
+        {
+            DDSURFACEDESC desc;
+            memset(&desc, 0, sizeof(DDSURFACEDESC));
+
+            desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
+
+            desc.dwWidth = dst_surface->width;
+            desc.dwHeight = dst_surface->height;
+
+            dd_CreateSurface(&desc, &dst_surface->backbuffer, unkOuter);
+        }
     }
 
     dprintf("     surface = %p (%dx%d@%d)\n", dst_surface, (int)dst_surface->width, (int)dst_surface->height, (int)dst_surface->bpp);
diff --git a/src/debug.c b/src/debug.c
index d84c83b..3ca4fb3 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -146,9 +146,9 @@ void dbg_draw_frame_info_start()
     if (g_ddraw->primary)
     {
         if (g_ddraw->primary->palette && g_ddraw->primary->palette->data_rgb)
-            SetDIBColorTable(g_ddraw->primary->hdc, 0, 256, g_ddraw->primary->palette->data_rgb);
-
-        DrawText(g_ddraw->primary->hdc, debug_text, -1, &debugrc, DT_NOCLIP);
+            SetDIBColorTable(dds_GetHDC(g_ddraw->primary), 0, 256, g_ddraw->primary->palette->data_rgb);
+        
+        DrawText(dds_GetHDC(g_ddraw->primary), debug_text, -1, &debugrc, DT_NOCLIP);
     }
         
     DWORD tick_start = timeGetTime();
diff --git a/src/screenshot.c b/src/screenshot.c
index adbe17e..7a2ce10 100644
--- a/src/screenshot.c
+++ b/src/screenshot.c
@@ -9,7 +9,7 @@
 
 BOOL ss_take_screenshot(struct IDirectDrawSurfaceImpl *src)
 {
-    if (!src || !src->palette || !src->surface)
+    if (!src || !src->palette || !dds_GetBuffer(src))
         return FALSE;
 
     int i;
@@ -54,7 +54,7 @@ BOOL ss_take_screenshot(struct IDirectDrawSurfaceImpl *src)
     state.info_raw.bitdepth = 8;
     state.encoder.auto_convert = 0;
 
-    unsigned int error = lodepng_encode(&png, &pngsize, src->surface, src->width, src->height, &state);
+    unsigned int error = lodepng_encode(&png, &pngsize, dds_GetBuffer(src), src->width, src->height, &state);
 
     if (!error) 
         lodepng_save_file(png, pngsize, filename);
diff --git a/src/utils.c b/src/utils.c
index 7b111aa..2b88e57 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -321,7 +321,7 @@ BOOL CALLBACK util_enum_child_proc(HWND hwnd, LPARAM lparam)
 
             MapWindowPoints(HWND_DESKTOP, g_ddraw->hwnd, (LPPOINT)&pos, 2);
 
-            BitBlt(hdc, 0, 0, size.right, size.bottom, this->hdc, pos.left, pos.top, SRCCOPY);
+            BitBlt(hdc, 0, 0, size.right, size.bottom, dds_GetHDC(this), pos.left, pos.top, SRCCOPY);
 
             ReleaseDC(hwnd, hdc);
         }
@@ -332,7 +332,7 @@ BOOL CALLBACK util_enum_child_proc(HWND hwnd, LPARAM lparam)
 
 static unsigned char util_get_pixel(int x, int y)
 {
-    return ((unsigned char*)g_ddraw->primary->surface)[y * g_ddraw->primary->l_pitch + x * g_ddraw->primary->lx_pitch];
+    return ((unsigned char*)dds_GetBuffer(g_ddraw->primary))[y * g_ddraw->primary->l_pitch + x * g_ddraw->primary->lx_pitch];
 }
 
 BOOL util_detect_cutscene()