Commit a7bd11af authored by Ričardas Barkauskas's avatar Ričardas Barkauskas Committed by Alexandre Julliard

ddraw: Fix filtering of enumerated display modes.

parent ebf9f12c
......@@ -2088,7 +2088,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
......@@ -2103,11 +2104,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[] =
{
......@@ -2127,12 +2128,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;
......@@ -2145,21 +2140,21 @@ 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_REFRESHRATE && mode.RefreshRate != DDSD->u2.dwRefreshRate) continue;
if (DDSD->dwFlags & DDSD_PIXELFORMAT &&
pixelformat.u1.dwRGBBitCount != DDSD->u4.ddpfPixelFormat.u1.dwRGBBitCount) continue;
}
if(!(Flags & DDEDM_REFRESHRATES))
......@@ -2188,17 +2183,16 @@ static HRESULT WINAPI ddraw7_EnumDisplayModes(IDirectDraw7 *iface, DWORD Flags,
callback_sd.dwSize = sizeof(callback_sd);
callback_sd.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH;
callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_REFRESHRATE;
if(Flags & DDEDM_REFRESHRATES)
{
callback_sd.dwFlags |= DDSD_REFRESHRATE;
callback_sd.u2.dwRefreshRate = mode.RefreshRate;
}
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;
......
......@@ -39,6 +39,9 @@ static int modes_size;
static LPDDSURFACEDESC modes;
static RECT rect_before_create;
static RECT rect_after_delete;
static int modes16bpp_cnt;
static int refresh_rate;
static int refresh_rate_cnt;
static HRESULT (WINAPI *pDirectDrawEnumerateA)(LPDDENUMCALLBACKA,LPVOID);
static HRESULT (WINAPI *pDirectDrawEnumerateW)(LPDDENUMCALLBACKW,LPVOID);
......@@ -344,8 +347,8 @@ static void flushdisplaymodes(void)
static HRESULT WINAPI enummodescallback(LPDDSURFACEDESC lpddsd, LPVOID lpContext)
{
trace("Width = %i, Height = %i, Refresh Rate = %i, Pitch = %i, flags =%02X\n",
lpddsd->dwWidth, lpddsd->dwHeight,
trace("Width = %i, Height = %i, bpp = %i, Refresh Rate = %i, Pitch = %i, flags =%02X\n",
lpddsd->dwWidth, lpddsd->dwHeight, U1(lpddsd->ddpfPixelFormat).dwRGBBitCount,
U2(*lpddsd).dwRefreshRate, U1(*lpddsd).lPitch, lpddsd->dwFlags);
/* Check that the pitch is valid if applicable */
......@@ -365,6 +368,56 @@ 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, bpp = %i, Refresh Rate = %i, Pitch = %i, flags =%02X\n",
lpddsd->dwWidth, lpddsd->dwHeight, U1(lpddsd->ddpfPixelFormat).dwRGBBitCount,
U2(*lpddsd).dwRefreshRate, U1(*lpddsd).lPitch, lpddsd->dwFlags);
ok(lpddsd->dwFlags == (DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_REFRESHRATE),
"Wrong surface description flags %02X\n", lpddsd->dwFlags);
ok(lpddsd->ddpfPixelFormat.dwFlags == DDPF_RGB, "Wrong pixel format flag %02X\n",
lpddsd->ddpfPixelFormat.dwFlags);
ok(U1(lpddsd->ddpfPixelFormat).dwRGBBitCount == 16, "Expected 16 bpp got %i\n",
U1(lpddsd->ddpfPixelFormat).dwRGBBitCount);
/* Check that the pitch is valid if applicable */
if(lpddsd->dwFlags & DDSD_PITCH)
{
ok(U1(*lpddsd).lPitch != 0, "EnumDisplayModes callback with bad pitch\n");
}
if(!refresh_rate)
{
if(U2(*lpddsd).dwRefreshRate )
{
refresh_rate = U2(*lpddsd).dwRefreshRate;
refresh_rate_cnt++;
}
}
else
{
if(refresh_rate == U2(*lpddsd).dwRefreshRate)
refresh_rate_cnt++;
}
modes16bpp_cnt++;
return DDENUMRET_OK;
}
static HRESULT WINAPI enummodescallback_count(LPDDSURFACEDESC lpddsd, LPVOID lpContext)
{
ok(lpddsd->dwFlags == (DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_REFRESHRATE),
"Wrong surface description flags %02X\n", lpddsd->dwFlags);
modes16bpp_cnt++;
return DDENUMRET_OK;
}
......@@ -373,15 +426,117 @@ static void enumdisplaymodes(void)
{
DDSURFACEDESC ddsd;
HRESULT rc;
int count, refresh_count;
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC));
ddsd.dwSize = sizeof(DDSURFACEDESC);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
rc = IDirectDraw_EnumDisplayModes(lpDD,
DDEDM_STANDARDVGAMODES, &ddsd, 0, enummodescallback);
ok(rc==DD_OK || rc==E_INVALIDARG,"EnumDisplayModes returned: %x\n",rc);
/* Flags parameter is reserved in very old ddraw versions (3 and older?) and must be 0 */
rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback);
ok(rc==DD_OK, "EnumDisplayModes returned: %x\n",rc);
count = modes16bpp_cnt;
modes16bpp_cnt = 0;
ddsd.dwFlags = DDSD_PIXELFORMAT;
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(modes16bpp_cnt == count, "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(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
modes16bpp_cnt = 0;
U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xF0F0;
U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x0F00;
U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x000F;
rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
ok(rc==DD_OK, "EnumDisplayModes returned: %x\n",rc);
ok(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
modes16bpp_cnt = 0;
ddsd.ddpfPixelFormat.dwFlags = DDPF_YUV;
rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
ok(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
modes16bpp_cnt = 0;
ddsd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
ok(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
modes16bpp_cnt = 0;
ddsd.dwFlags = DDSD_PIXELFORMAT;
ddsd.ddpfPixelFormat.dwFlags = 0;
rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
ok(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
modes16bpp_cnt = 0;
ddsd.dwFlags = 0;
rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_count);
ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
ok(modes16bpp_cnt == modes_cnt, "Expected %d modes got %d\n", modes_cnt, modes16bpp_cnt);
modes16bpp_cnt = 0;
ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_PITCH;
ddsd.lPitch = 123;
rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
ok(modes16bpp_cnt == count, "Expected %d modes got %d\n", count, modes16bpp_cnt);
modes16bpp_cnt = 0;
ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_REFRESHRATE;
ddsd.dwRefreshRate = 1;
rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
ok(modes16bpp_cnt == 0, "Expected 0 modes got %d\n", modes16bpp_cnt);
modes16bpp_cnt = 0;
ddsd.dwFlags = DDSD_PIXELFORMAT;
rc = IDirectDraw_EnumDisplayModes(lpDD, DDEDM_REFRESHRATES, &ddsd, 0, enummodescallback_16bit);
if(rc == DDERR_INVALIDPARAMS)
{
skip("Ddraw version too old. Skipping.\n");
return;
}
ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
refresh_count = refresh_rate_cnt;
if(refresh_rate)
{
modes16bpp_cnt = 0;
ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_REFRESHRATE;
ddsd.dwRefreshRate = refresh_rate;
rc = IDirectDraw_EnumDisplayModes(lpDD, 0, &ddsd, 0, enummodescallback_16bit);
ok(rc==DD_OK,"EnumDisplayModes returned: %x\n",rc);
ok(modes16bpp_cnt == refresh_count, "Expected %d modes got %d\n", refresh_count, modes16bpp_cnt);
}
}
static void setdisplaymode(int i)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment