mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Avoid side effects when method implementations are delegated to higher versions
Some DirectDraw methods are implemented by delegating to the same method in a higher interface version. In this case, the hooking logic could be executed twice, leading to unwanted side effects. This is now avoided.
This commit is contained in:
parent
f7f5348a87
commit
fe8abe9d5a
@ -17,14 +17,69 @@ namespace
|
||||
return DDENUMRET_CANCEL;
|
||||
}
|
||||
|
||||
DWORD getRefreshRate()
|
||||
template <typename TDirectDraw>
|
||||
HRESULT setDisplayMode(TDirectDraw* This, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP,
|
||||
DWORD dwRefreshRate, DWORD dwFlags)
|
||||
{
|
||||
return 0;
|
||||
typename Types<TDirectDraw>::TSurfaceDesc desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
|
||||
desc.dwWidth = dwWidth;
|
||||
desc.dwHeight = dwHeight;
|
||||
desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
|
||||
desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||
desc.ddpfPixelFormat.dwRGBBitCount = dwBPP;
|
||||
|
||||
switch (dwBPP)
|
||||
{
|
||||
case 1: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED1; break;
|
||||
case 2: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED2; break;
|
||||
case 4: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED4; break;
|
||||
case 8: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8; break;
|
||||
}
|
||||
|
||||
DDPIXELFORMAT pf = {};
|
||||
if (dwBPP > 8)
|
||||
{
|
||||
if (FAILED(CompatDirectDraw<TDirectDraw>::s_origVtable.EnumDisplayModes(
|
||||
This, 0, &desc, &pf, &enumDisplayModesCallback)) || 0 == pf.dwSize)
|
||||
{
|
||||
Compat::Log() << "Failed to find the requested display mode: " <<
|
||||
dwWidth << "x" << dwHeight << "x" << dwBPP;
|
||||
return DDERR_INVALIDMODE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pf = desc.ddpfPixelFormat;
|
||||
}
|
||||
|
||||
HRESULT result = CompatDirectDraw<TDirectDraw>::s_origVtable.SetDisplayMode(
|
||||
This, dwWidth, dwHeight, 32, dwRefreshRate, dwFlags);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
CompatPrimarySurface::displayMode.width = dwWidth;
|
||||
CompatPrimarySurface::displayMode.height = dwHeight;
|
||||
CompatPrimarySurface::displayMode.pixelFormat = pf;
|
||||
CompatPrimarySurface::displayMode.refreshRate = dwRefreshRate;
|
||||
CompatPrimarySurface::isDisplayModeChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Compat::Log() << "Failed to set the display mode to " << dwWidth << "x" << dwHeight << "x32";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DWORD getRefreshRate(DWORD dwRefreshRate, DWORD /*dwFlags*/)
|
||||
HRESULT setDisplayMode(IDirectDraw* This, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP)
|
||||
{
|
||||
return dwRefreshRate;
|
||||
IDirectDraw7* dd = nullptr;
|
||||
CompatDirectDraw<IDirectDraw>::s_origVtable.QueryInterface(
|
||||
This, IID_IDirectDraw7, reinterpret_cast<void**>(&dd));
|
||||
HRESULT result = setDisplayMode(dd, dwWidth, dwHeight, dwBPP, 0, 0);
|
||||
CompatDirectDraw<IDirectDraw7>::s_origVtable.Release(dd);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,54 +171,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::SetDisplayMode(
|
||||
DWORD dwBPP,
|
||||
Params... params)
|
||||
{
|
||||
TSurfaceDesc desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
|
||||
desc.dwWidth = dwWidth;
|
||||
desc.dwHeight = dwHeight;
|
||||
desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
|
||||
desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||
desc.ddpfPixelFormat.dwRGBBitCount = dwBPP;
|
||||
|
||||
switch (dwBPP)
|
||||
{
|
||||
case 1: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED1; break;
|
||||
case 2: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED2; break;
|
||||
case 4: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED4; break;
|
||||
case 8: desc.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8; break;
|
||||
}
|
||||
|
||||
DDPIXELFORMAT pf = {};
|
||||
if (dwBPP > 8)
|
||||
{
|
||||
if (FAILED(s_origVtable.EnumDisplayModes(This, 0, &desc, &pf, &enumDisplayModesCallback)) ||
|
||||
0 == pf.dwSize)
|
||||
{
|
||||
Compat::Log() << "Failed to find the requested display mode: " <<
|
||||
dwWidth << "x" << dwHeight << "x" << dwBPP;
|
||||
return DDERR_INVALIDMODE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pf = desc.ddpfPixelFormat;
|
||||
}
|
||||
|
||||
HRESULT result = s_origVtable.SetDisplayMode(This, dwWidth, dwHeight, 32, params...);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
CompatPrimarySurface::displayMode.width = dwWidth;
|
||||
CompatPrimarySurface::displayMode.height = dwHeight;
|
||||
CompatPrimarySurface::displayMode.pixelFormat = pf;
|
||||
CompatPrimarySurface::displayMode.refreshRate = getRefreshRate(params...);
|
||||
CompatPrimarySurface::isDisplayModeChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Compat::Log() << "Failed to set the display mode to " << dwWidth << "x" << dwHeight << "x32";
|
||||
}
|
||||
|
||||
return result;
|
||||
return setDisplayMode(This, dwWidth, dwHeight, dwBPP, params...);
|
||||
}
|
||||
|
||||
template CompatDirectDraw<IDirectDraw>;
|
||||
|
@ -565,8 +565,8 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Unlock(TSurface* Th
|
||||
template <typename TSurface>
|
||||
void CompatDirectDrawSurface<TSurface>::restorePrimaryCaps(TDdsCaps& caps)
|
||||
{
|
||||
caps.dwCaps ^= DDSCAPS_OFFSCREENPLAIN;
|
||||
caps.dwCaps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE;
|
||||
caps.dwCaps &= ~(DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY);
|
||||
caps.dwCaps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
|
||||
}
|
||||
|
||||
template <> const IID& CompatDirectDrawSurface<IDirectDrawSurface>::s_iid = IID_IDirectDrawSurface;
|
||||
|
Loading…
x
Reference in New Issue
Block a user