diff --git a/inc/IDirectDrawSurface.h b/inc/IDirectDrawSurface.h
index 704888f..579b7d6 100644
--- a/inc/IDirectDrawSurface.h
+++ b/inc/IDirectDrawSurface.h
@@ -29,6 +29,7 @@ typedef struct IDirectDrawSurfaceImpl
     IDirectDrawPaletteImpl* palette;
 
     void* surface;
+    HANDLE surface_mapping;
     DWORD l_pitch;
     DWORD lx_pitch;
     BOOL custom_surface;
diff --git a/src/IDirectDraw/IDirectDrawSurface.c b/src/IDirectDraw/IDirectDrawSurface.c
index 2f55074..c1b2197 100644
--- a/src/IDirectDraw/IDirectDrawSurface.c
+++ b/src/IDirectDraw/IDirectDrawSurface.c
@@ -96,6 +96,9 @@ ULONG __stdcall IDirectDrawSurface__Release(IDirectDrawSurfaceImpl* This)
         if (This->bmi)
             HeapFree(GetProcessHeap(), 0, This->bmi);
 
+        if (This->surface_mapping)
+            CloseHandle(This->surface_mapping);
+
         if (This->backbuffer)
             IDirectDrawSurface_Release(This->backbuffer);
 
diff --git a/src/ddsurface.c b/src/ddsurface.c
index 81021ca..be89140 100644
--- a/src/ddsurface.c
+++ b/src/ddsurface.c
@@ -1053,9 +1053,10 @@ HRESULT dd_CreateSurface(
 
         DWORD aligned_width = dst_surface->l_pitch / dst_surface->lx_pitch;
 
-        dst_surface->bmi =
-            HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);
+        DWORD bmi_size = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256;
+        DWORD bmp_size = dst_surface->l_pitch * (dst_surface->height + 200);
 
+        dst_surface->bmi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bmi_size);
         dst_surface->bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
         dst_surface->bmi->bmiHeader.biWidth = aligned_width;
         dst_surface->bmi->bmiHeader.biHeight = -((int)dst_surface->height + 200);
@@ -1097,18 +1098,49 @@ HRESULT dd_CreateSurface(
         }
 
         dst_surface->hdc = CreateCompatibleDC(g_ddraw->render.hdc);
+
+        dst_surface->surface_mapping =
+            CreateFileMappingA(
+                INVALID_HANDLE_VALUE,
+                NULL,
+                PAGE_READWRITE | SEC_COMMIT,
+                0,
+                bmp_size + 256,
+                NULL);
+
+        DWORD map_offset = 0;
+
+        if (dst_surface->surface_mapping)
+        {
+            LPVOID data = MapViewOfFile(dst_surface->surface_mapping, FILE_MAP_READ, 0, 0, 0);
+            if (data)
+            {
+                while (((DWORD)data + map_offset) % 128) map_offset++;
+                UnmapViewOfFile(data);
+            }
+
+            if (!data || (map_offset % sizeof(DWORD)))
+            {
+                map_offset = 0;
+                CloseHandle(dst_surface->surface_mapping);
+                dst_surface->surface_mapping = NULL;
+            }
+        }
+
         dst_surface->bitmap =
-            CreateDIBSection(dst_surface->hdc, dst_surface->bmi, DIB_RGB_COLORS, (void**)&dst_surface->surface, NULL, 0);
+            CreateDIBSection(
+                dst_surface->hdc,
+                dst_surface->bmi,
+                DIB_RGB_COLORS,
+                (void**)&dst_surface->surface,
+                dst_surface->surface_mapping,
+                map_offset);
 
         dst_surface->bmi->bmiHeader.biHeight = -((int)dst_surface->height);
 
         if (!dst_surface->bitmap)
         {
-            dst_surface->surface =
-                HeapAlloc(
-                    GetProcessHeap(),
-                    HEAP_ZERO_MEMORY,
-                    dst_surface->l_pitch * (dst_surface->height + 200));
+            dst_surface->surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bmp_size);
         }
 
         if (dst_surface->caps & DDSCAPS_PRIMARYSURFACE)