diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 46240f485bf..854ec3c0abb 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -4033,6 +4033,19 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, return DDERR_INVALIDPARAMS; } + /* Tests show that only LPSURFACE and PIXELFORMAT can be set, and LPSURFACE is required + * for PIXELFORMAT to work */ + if (DDSD->dwFlags & ~(DDSD_LPSURFACE | DDSD_PIXELFORMAT)) + { + WARN("Invalid flags (0x%08x) set, returning DDERR_INVALIDPARAMS\n", DDSD->dwFlags); + return DDERR_INVALIDPARAMS; + } + if (!(DDSD->dwFlags & DDSD_LPSURFACE)) + { + WARN("DDSD_LPSURFACE is not set, returning DDERR_INVALIDPARAMS\n"); + return DDERR_INVALIDPARAMS; + } + wined3d_mutex_lock(); if (DDSD->dwFlags & DDSD_PIXELFORMAT) { @@ -4052,28 +4065,9 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, wined3d_mutex_unlock(); return hr; } + This->surface_desc.u4.ddpfPixelFormat = DDSD->u4.ddpfPixelFormat; } } - if (DDSD->dwFlags & DDSD_CKDESTOVERLAY) - { - wined3d_surface_set_color_key(This->wined3d_surface, DDCKEY_DESTOVERLAY, - (WINEDDCOLORKEY *)&DDSD->u3.ddckCKDestOverlay); - } - if (DDSD->dwFlags & DDSD_CKDESTBLT) - { - wined3d_surface_set_color_key(This->wined3d_surface, DDCKEY_DESTBLT, - (WINEDDCOLORKEY *)&DDSD->ddckCKDestBlt); - } - if (DDSD->dwFlags & DDSD_CKSRCOVERLAY) - { - wined3d_surface_set_color_key(This->wined3d_surface, DDCKEY_SRCOVERLAY, - (WINEDDCOLORKEY *)&DDSD->ddckCKSrcOverlay); - } - if (DDSD->dwFlags & DDSD_CKSRCBLT) - { - wined3d_surface_set_color_key(This->wined3d_surface, DDCKEY_SRCBLT, - (WINEDDCOLORKEY *)&DDSD->ddckCKSrcBlt); - } if (DDSD->dwFlags & DDSD_LPSURFACE && DDSD->lpSurface) { hr = wined3d_surface_set_mem(This->wined3d_surface, DDSD->lpSurface); @@ -4089,10 +4083,9 @@ static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, break; /* Go on */ } } + /* DDSD->lpSurface is set by Lock() */ } - This->surface_desc = *DDSD; - wined3d_mutex_unlock(); return DD_OK; diff --git a/dlls/ddraw/tests/dsurface.c b/dlls/ddraw/tests/dsurface.c index 987801f10e3..ca9d3b75309 100644 --- a/dlls/ddraw/tests/dsurface.c +++ b/dlls/ddraw/tests/dsurface.c @@ -4483,6 +4483,7 @@ static void set_surface_desc_test(void) IDirectDrawSurface *surface; IDirectDrawSurface3 *surface3; BYTE data[8*8*4]; + DWORD old_pitch; hr = IDirectDraw_CreateSurface(lpDD, NULL, &surface, NULL); ok(hr == DDERR_INVALIDPARAMS, "CreateSurface with a NULL DDSD returned %#x," @@ -4526,6 +4527,85 @@ static void set_surface_desc_test(void) " DDERR_INVALIDPARAMS(%#x)\n", hr, DDERR_INVALIDPARAMS); IDirectDrawSurface_Release(surface3); + + reset_ddsd(&ddsd); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; + ddsd.dwWidth = 8; + ddsd.dwHeight = 8; + ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); + ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; + U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32; + U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000; + U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00; + U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff; + ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY; + + hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL); + ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr); + hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface3, (void **) &surface3); + ok(SUCCEEDED(hr), "IDirectDrawSurface_QueryInterface failed, hr %#x.\n", hr); + IDirectDrawSurface_Release(surface); + hr = IDirectDrawSurface3_GetSurfaceDesc(surface3, &ddsd); + ok(SUCCEEDED(hr), "IDirectDrawSurface3_GetSurfaceDesc failed, hr %#x.\n", hr); + old_pitch = ddsd.lPitch; + + /* Setting width and height is an error */ + reset_ddsd(&ddsd); + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 16; + ddsd.dwHeight = 16; + hr = IDirectDrawSurface3_SetSurfaceDesc(surface3, &ddsd, 0); + ok(hr == DDERR_INVALIDPARAMS, "SetSurfaceDesc returned %#x, expected %#x\n", hr, DDERR_INVALIDPARAMS); + ddsd.lpSurface = data; + ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_LPSURFACE; + hr = IDirectDrawSurface3_SetSurfaceDesc(surface3, &ddsd, 0); + ok(hr == DDERR_INVALIDPARAMS, "SetSurfaceDesc returned %#x, expected %#x\n", hr, DDERR_INVALIDPARAMS); + + reset_ddsd(&ddsd); + hr = IDirectDrawSurface3_GetSurfaceDesc(surface3, &ddsd); + ok(SUCCEEDED(hr), "IDirectDrawSurface3_GetSurfaceDesc failed, hr %#x.\n", hr); + ok(ddsd.dwWidth == 8, "SetSurfaceDesc: Expected width 8, got %u\n", ddsd.dwWidth); + ok(ddsd.dwHeight == 8, "SetSurfaceDesc: Expected height 8, got %u\n", ddsd.dwHeight); + + /* Setting the pitch is an error */ + reset_ddsd(&ddsd); + ddsd.dwFlags = DDSD_PITCH; + ddsd.lPitch = 1024; + hr = IDirectDrawSurface3_SetSurfaceDesc(surface3, &ddsd, 0); + ok(hr == DDERR_INVALIDPARAMS, "SetSurfaceDesc returned %#x, expected %#x\n", hr, DDERR_INVALIDPARAMS); + ddsd.dwFlags = DDSD_PITCH | DDSD_LPSURFACE; + ddsd.lpSurface = data; + hr = IDirectDrawSurface3_SetSurfaceDesc(surface3, &ddsd, 0); + ok(hr == DDERR_INVALIDPARAMS, "SetSurfaceDesc returned %#x, expected %#x\n", hr, DDERR_INVALIDPARAMS); + ddsd.lPitch = old_pitch; + hr = IDirectDrawSurface3_SetSurfaceDesc(surface3, &ddsd, 0); + ok(hr == DDERR_INVALIDPARAMS, "SetSurfaceDesc returned %#x, expected %#x\n", hr, DDERR_INVALIDPARAMS); + + /* Setting the pixelformat without lpsurface is an error, but with LPSURFACE it works */ + reset_ddsd(&ddsd); + ddsd.dwFlags = DDSD_PIXELFORMAT; + ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); + ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; + U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32; + U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x00ff0000; + U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000ff00; + U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000000ff; + hr = IDirectDrawSurface3_SetSurfaceDesc(surface3, &ddsd, 0); + ok(hr == DDERR_INVALIDPARAMS, "SetSurfaceDesc returned %#x, expected %#x\n", hr, DDERR_INVALIDPARAMS); + ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_LPSURFACE; + ddsd.lpSurface = data; + hr = IDirectDrawSurface3_SetSurfaceDesc(surface3, &ddsd, 0); + ok(hr == DD_OK, "SetSurfaceDesc returned %#x, expected %#x\n", hr, DD_OK); + + /* Can't set color keys */ + reset_ddsd(&ddsd); + ddsd.dwFlags = DDSD_CKSRCBLT; + ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00ff0000; + ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00ff0000; + hr = IDirectDrawSurface3_SetSurfaceDesc(surface3, &ddsd, 0); + ok(hr == DDERR_INVALIDPARAMS, "SetSurfaceDesc returned %#x, expected %#x\n", hr, DDERR_INVALIDPARAMS); + + IDirectDrawSurface_Release(surface3); } static BOOL fourcc_supported(DWORD fourcc, DWORD caps)