ddraw: Fix filtering of enumerated display modes
Ričardas Barkauskas
rbarkauskas at codeweavers.com
Sun May 8 09:54:54 CDT 2011
---
dlls/ddraw/ddraw.c | 26 +++----
dlls/ddraw/tests/ddrawmodes.c | 165 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 170 insertions(+), 21 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 9b87b95..a4e09b0 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,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))
@@ -2170,17 +2165,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;
diff --git a/dlls/ddraw/tests/ddrawmodes.c b/dlls/ddraw/tests/ddrawmodes.c
index a103d65..ae090a2 100644
--- a/dlls/ddraw/tests/ddrawmodes.c
+++ b/dlls/ddraw/tests/ddrawmodes.c
@@ -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)
--
1.7.5.1
------=_20110512085508_73188--
More information about the wine-patches
mailing list