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;
|
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,
|
DWORD dwBPP,
|
||||||
Params... params)
|
Params... params)
|
||||||
{
|
{
|
||||||
TSurfaceDesc desc = {};
|
return setDisplayMode(This, dwWidth, dwHeight, dwBPP, params...);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template CompatDirectDraw<IDirectDraw>;
|
template CompatDirectDraw<IDirectDraw>;
|
||||||
|
@ -565,8 +565,8 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Unlock(TSurface* Th
|
|||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
void CompatDirectDrawSurface<TSurface>::restorePrimaryCaps(TDdsCaps& caps)
|
void CompatDirectDrawSurface<TSurface>::restorePrimaryCaps(TDdsCaps& caps)
|
||||||
{
|
{
|
||||||
caps.dwCaps ^= DDSCAPS_OFFSCREENPLAIN;
|
caps.dwCaps &= ~(DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY);
|
||||||
caps.dwCaps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE;
|
caps.dwCaps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> const IID& CompatDirectDrawSurface<IDirectDrawSurface>::s_iid = IID_IDirectDrawSurface;
|
template <> const IID& CompatDirectDrawSurface<IDirectDrawSurface>::s_iid = IID_IDirectDrawSurface;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user