diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index e8898156f4f..c23b8bf1b54 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -1328,6 +1328,7 @@ static HRESULT WINAPI ddraw3_GetDisplayMode(IDirectDraw3 *iface, DDSURFACEDESC * TRACE("iface %p, surface_desc %p.\n", iface, surface_desc); + /* FIXME: Test sizes, properly convert surface_desc */ return ddraw7_GetDisplayMode(&This->IDirectDraw7_iface, (DDSURFACEDESC2 *)surface_desc); } @@ -1337,6 +1338,7 @@ static HRESULT WINAPI ddraw2_GetDisplayMode(IDirectDraw2 *iface, DDSURFACEDESC * TRACE("iface %p, surface_desc %p.\n", iface, surface_desc); + /* FIXME: Test sizes, properly convert surface_desc */ return ddraw7_GetDisplayMode(&This->IDirectDraw7_iface, (DDSURFACEDESC2 *)surface_desc); } @@ -1346,6 +1348,7 @@ static HRESULT WINAPI ddraw1_GetDisplayMode(IDirectDraw *iface, DDSURFACEDESC *s TRACE("iface %p, surface_desc %p.\n", iface, surface_desc); + /* FIXME: Test sizes, properly convert surface_desc */ return ddraw7_GetDisplayMode(&This->IDirectDraw7_iface, (DDSURFACEDESC2 *)surface_desc); } @@ -2118,9 +2121,7 @@ static HRESULT CALLBACK EnumDisplayModesCallbackThunk(DDSURFACEDESC2 *surface_de struct displaymodescallback_context *cbcontext = context; DDSURFACEDESC desc; - memcpy(&desc, surface_desc, sizeof(desc)); - desc.dwSize = sizeof(desc); - + DDSD2_to_DDSD(surface_desc, &desc); return cbcontext->func(&desc, cbcontext->context); } diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 0e4fe8d7246..2c3ab8fd009 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -556,6 +556,7 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN; void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in) DECLSPEC_HIDDEN; void DDRAW_dump_cooperativelevel(DWORD cooplevel) DECLSPEC_HIDDEN; void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out) DECLSPEC_HIDDEN; +void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out) DECLSPEC_HIDDEN; /* This only needs to be here as long the processvertices functionality of * IDirect3DExecuteBuffer isn't in WineD3D */ diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index a8142eb9865..c7d52d7e757 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -972,6 +972,8 @@ static HRESULT WINAPI ddraw_surface3_Lock(IDirectDrawSurface3 *iface, RECT *rect TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", iface, wine_dbgstr_rect(rect), surface_desc, flags, h); + /* All versions of Lock() accept both sizeof(DDSURFACEDESC) and + * sizeof(DDSURFACEDESC2) structures and do not touch the dwSize member */ return ddraw_surface7_Lock(&This->IDirectDrawSurface7_iface, rect, (DDSURFACEDESC2 *)surface_desc, flags, h); } @@ -983,6 +985,10 @@ static HRESULT WINAPI ddraw_surface2_Lock(IDirectDrawSurface2 *iface, RECT *rect TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", iface, wine_dbgstr_rect(rect), surface_desc, flags, h); + /* All versions of Lock() accept both sizeof(DDSURFACEDESC) and + * sizeof(DDSURFACEDESC2) structures and do not touch the dwSize member + * + * TODO: Test DDSD_ZBUFFERBITDEPTH behavior */ return ddraw_surface7_Lock(&This->IDirectDrawSurface7_iface, rect, (DDSURFACEDESC2 *)surface_desc, flags, h); } @@ -994,6 +1000,8 @@ static HRESULT WINAPI ddraw_surface1_Lock(IDirectDrawSurface *iface, RECT *rect, TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", iface, wine_dbgstr_rect(rect), surface_desc, flags, h); + /* All versions of Lock() accept both sizeof(DDSURFACEDESC) and + * sizeof(DDSURFACEDESC2) structures and do not touch the dwSize member */ return ddraw_surface7_Lock(&This->IDirectDrawSurface7_iface, rect, (DDSURFACEDESC2 *)surface_desc, flags, h); } @@ -2310,6 +2318,7 @@ static HRESULT CALLBACK EnumCallback(IDirectDrawSurface7 *surface, DDSURFACEDESC ddraw_surface1_AddRef(&surface_impl->IDirectDrawSurface_iface); ddraw_surface7_Release(surface); + /* FIXME: Check surface_test.dwSize */ return info->callback(&surface_impl->IDirectDrawSurface_iface, (DDSURFACEDESC *)surface_desc, info->context); } @@ -2863,7 +2872,7 @@ static HRESULT WINAPI ddraw_surface3_GetSurfaceDesc(IDirectDrawSurface3 *iface, } EnterCriticalSection(&ddraw_cs); - DD_STRUCT_COPY_BYSIZE(surface_desc, (DDSURFACEDESC *)&This->surface_desc); + DDSD2_to_DDSD(&This->surface_desc, surface_desc); TRACE("Returning surface desc:\n"); if (TRACE_ON(ddraw)) { diff --git a/dlls/ddraw/utils.c b/dlls/ddraw/utils.c index ca63461a86c..962a62fef4e 100644 --- a/dlls/ddraw/utils.c +++ b/dlls/ddraw/utils.c @@ -1219,3 +1219,38 @@ void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out) * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE, */ } + +/* Note that this function writes the full sizeof(DDSURFACEDESC) size, don't use it + * for writing into application-provided DDSURFACEDESC structures if the size may + * be different */ +void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out) +{ + memset(out, 0, sizeof(*out)); + out->dwSize = sizeof(*out); + out->dwFlags = in->dwFlags; + if (in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth; + if (in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight; + if (in->dwFlags & DDSD_PIXELFORMAT) out->ddpfPixelFormat = in->u4.ddpfPixelFormat; + /* ddsCaps is read even without DDSD_CAPS set. See dsurface:no_ddsd_caps_test */ + out->ddsCaps.dwCaps = in->ddsCaps.dwCaps; + if (in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch; + if (in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount; + if (in->dwFlags & DDSD_ZBUFFERBITDEPTH) out->u2.dwZBufferBitDepth = in->u2.dwMipMapCount; /* same union */ + if (in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth; + /* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */ + out->lpSurface = in->lpSurface; + if (in->dwFlags & DDSD_CKDESTOVERLAY) out->ddckCKDestOverlay = in->u3.ddckCKDestOverlay; + if (in->dwFlags & DDSD_CKDESTBLT) out->ddckCKDestBlt = in->ddckCKDestBlt; + if (in->dwFlags & DDSD_CKSRCOVERLAY) out->ddckCKSrcOverlay = in->ddckCKSrcOverlay; + if (in->dwFlags & DDSD_CKSRCBLT) out->ddckCKSrcBlt = in->ddckCKSrcBlt; + if (in->dwFlags & DDSD_MIPMAPCOUNT) out->u2.dwMipMapCount = in->u2.dwMipMapCount; + if (in->dwFlags & DDSD_REFRESHRATE) out->u2.dwRefreshRate = in->u2.dwRefreshRate; + if (in->dwFlags & DDSD_LINEARSIZE) out->u1.dwLinearSize = in->u1.dwLinearSize; + /* Does not exist in DDSURFACEDESC: + * DDSD_TEXTURESTAGE, DDSD_FVF, DDSD_SRCVBHANDLE, + */ + if (in->dwFlags & DDSD_TEXTURESTAGE) WARN("Does not exist in DDSURFACEDESC: DDSD_TEXTURESTAGE\n"); + if (in->dwFlags & DDSD_FVF) WARN("Does not exist in DDSURFACEDESC: DDSD_FVF\n"); + if (in->dwFlags & DDSD_SRCVBHANDLE) WARN("Does not exist in DDSURFACEDESC: DDSD_SRCVBHANDLE\n"); + out->dwFlags &= ~(DDSD_TEXTURESTAGE | DDSD_FVF | DDSD_SRCVBHANDLE); +}