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)