From 8dfb2520d9f12001e617a19ebb8d1341593dab22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ri=C4=8Dardas=20Barkauskas?= Date: Sun, 8 May 2011 17:54:54 +0300 Subject: ddraw: Fix filtering of enumerated display modes by bits per pixel --- dlls/ddraw/ddraw.c | 22 ++++++---------- dlls/ddraw/tests/ddrawmodes.c | 54 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 9b87b95..b2ce0e4 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -2070,7 +2070,8 @@ static HRESULT CALLBACK EnumDisplayModesCallbackThunk(DDSURFACEDESC2 *surface_de * the DDSD parameter. * * Params: - * Flags: can be DDEDM_REFRESHRATES and DDEDM_STANDARDVGAMODES + * Flags: can be DDEDM_REFRESHRATES and DDEDM_STANDARDVGAMODES. For old ddraw + * versions (3 and older?) this is reserved and must be 0. * DDSD: Surface description to filter the modes * Context: Pointer passed back to the callback function * cb: Application-provided callback function @@ -2085,11 +2086,11 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags, { IDirectDrawImpl *This = impl_from_IDirectDraw7(iface); unsigned int modenum, fmt; - enum wined3d_format_id pixelformat = WINED3DFMT_UNKNOWN; WINED3DDISPLAYMODE mode; DDSURFACEDESC2 callback_sd; WINED3DDISPLAYMODE *enum_modes = NULL; unsigned enum_mode_count = 0, enum_mode_array_size = 0; + DDPIXELFORMAT pixelformat; static const enum wined3d_format_id checkFormatList[] = { @@ -2109,12 +2110,6 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags, return DDERR_INVALIDPARAMS; } - if(DDSD) - { - if ((DDSD->dwFlags & DDSD_PIXELFORMAT) && (DDSD->u4.ddpfPixelFormat.dwFlags & DDPF_RGB) ) - pixelformat = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat); - } - if(!(Flags & DDEDM_REFRESHRATES)) { enum_mode_array_size = 16; @@ -2127,21 +2122,20 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags, } } + pixelformat.dwSize = sizeof(pixelformat); for(fmt = 0; fmt < (sizeof(checkFormatList) / sizeof(checkFormatList[0])); fmt++) { - if(pixelformat != WINED3DFMT_UNKNOWN && checkFormatList[fmt] != pixelformat) - { - continue; - } - modenum = 0; while (wined3d_enum_adapter_modes(This->wineD3D, WINED3DADAPTER_DEFAULT, checkFormatList[fmt], modenum++, &mode) == WINED3D_OK) { + PixelFormat_WineD3DtoDD(&pixelformat, mode.Format); if(DDSD) { if(DDSD->dwFlags & DDSD_WIDTH && mode.Width != DDSD->dwWidth) continue; if(DDSD->dwFlags & DDSD_HEIGHT && mode.Height != DDSD->dwHeight) continue; + if ((DDSD->dwFlags & DDSD_PIXELFORMAT) && (DDSD->u4.ddpfPixelFormat.dwFlags & DDPF_RGB) ) + if(pixelformat.u1.dwRGBBitCount != DDSD->u4.ddpfPixelFormat.u1.dwRGBBitCount) continue; } if(!(Flags & DDEDM_REFRESHRATES)) @@ -2180,7 +2174,7 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags, callback_sd.dwWidth = mode.Width; callback_sd.dwHeight = mode.Height; - PixelFormat_WineD3DtoDD(&callback_sd.u4.ddpfPixelFormat, mode.Format); + callback_sd.u4.ddpfPixelFormat=pixelformat; /* Calc pitch and DWORD align like MSDN says */ callback_sd.u1.lPitch = (callback_sd.u4.ddpfPixelFormat.u1.dwRGBBitCount / 8) * mode.Width; diff --git a/dlls/ddraw/tests/ddrawmodes.c b/dlls/ddraw/tests/ddrawmodes.c index a103d65..535a946 100644 --- a/dlls/ddraw/tests/ddrawmodes.c +++ b/dlls/ddraw/tests/ddrawmodes.c @@ -39,6 +39,7 @@ static int modes_size; static LPDDSURFACEDESC modes; static RECT rect_before_create; static RECT rect_after_delete; +static int modes16bpp_cnt; static HRESULT (WINAPI *pDirectDrawEnumerateA)(LPDDENUMCALLBACKA,LPVOID); static HRESULT (WINAPI *pDirectDrawEnumerateW)(LPDDENUMCALLBACKW,LPVOID); @@ -365,6 +366,29 @@ static HRESULT WINAPI enummodescallback(LPDDSURFACEDESC lpddsd, LPVOID lpContext */ adddisplaymode(lpddsd); + if(U1(lpddsd->ddpfPixelFormat).dwRGBBitCount == 16) + modes16bpp_cnt++; + + return DDENUMRET_OK; +} + +static HRESULT WINAPI enummodescallback_16bit(LPDDSURFACEDESC lpddsd, LPVOID lpContext) +{ + trace("Width = %i, Height = %i, Refresh Rate = %i, Pitch = %i, flags =%02X\n", + lpddsd->dwWidth, lpddsd->dwHeight, + U2(*lpddsd).dwRefreshRate, U1(*lpddsd).lPitch, lpddsd->dwFlags); + + ok(lpddsd->dwFlags & DDSD_PIXELFORMAT, "Pixel format not present\n"); + ok(lpddsd->ddpfPixelFormat.dwFlags & DDPF_RGB, "Pixel format doesn't describe RGB\n"); + ok(lpddsd->ddpfPixelFormat.dwRGBBitCount == 16, "Mode filtering doesn't work\n"); + + /* Check that the pitch is valid if applicable */ + if(lpddsd->dwFlags & DDSD_PITCH) + { + ok(U1(*lpddsd).lPitch != 0, "EnumDisplayModes callback with bad pitch\n"); + } + + modes16bpp_cnt++; return DDENUMRET_OK; } @@ -373,15 +397,43 @@ static void enumdisplaymodes(void) { DDSURFACEDESC ddsd; HRESULT rc; + int count; ZeroMemory(&ddsd, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + /* Flags parameter is reserved in very old ddraw versions (3 and older?) and must be 0 */ rc = IDirectDraw_EnumDisplayModes(lpDD, - DDEDM_STANDARDVGAMODES, &ddsd, 0, enummodescallback); + 0, &ddsd, 0, enummodescallback); ok(rc==DD_OK || rc==E_INVALIDARG,"EnumDisplayModes returned: %x\n",rc); + + count = modes16bpp_cnt; + modes16bpp_cnt = 0; + + ddsd.dwFlags ^= DDSD_PIXELFORMAT; + ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); + ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; + U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 16; + U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x7C00; + U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x03E0; + U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x001F; + + rc = IDirectDraw_EnumDisplayModes(lpDD, + 0, &ddsd, 0, enummodescallback_16bit); + ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc); + ok(count == modes16bpp_cnt, "Expected %d modes got %d\n", count, modes16bpp_cnt); + + modes16bpp_cnt = 0; + U2(ddsd.ddpfPixelFormat).dwRBitMask = 0x0000; + U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0000; + U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000; + + rc = IDirectDraw_EnumDisplayModes(lpDD, + 0, &ddsd, 0, enummodescallback_16bit); + ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc); + ok(count == modes16bpp_cnt, "Expected %d modes got %d\n", count, modes16bpp_cnt); } static void setdisplaymode(int i) -- 1.7.5.1