ddraw: Fix filtering of enumerated display modes.
This commit is contained in:
parent
ebf9f12c29
commit
a7bd11afb0
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue