1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Fixed issue related to modifying the surface description in CreateSurface

When forcing the emulated pixel format to surfaces in CreateSurface,
the original surface description parameter was being modified, leading to
issues with the mouse cursor in Populous 3. Now a copy is modified instead.

Also avoided unnecessary palette update when the palette is being set to null.
This commit is contained in:
narzoul 2015-12-29 15:40:28 +01:00
parent 6b6d161190
commit 63b3112a58
4 changed files with 38 additions and 16 deletions

View File

@ -53,10 +53,15 @@ HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::CreateSurface(
(lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_3DDEVICE | DDSCAPS_BACKBUFFER | DDSCAPS_FLIP |
DDSCAPS_FRONTBUFFER | DDSCAPS_OFFSCREENPLAIN | DDSCAPS_OVERLAY | DDSCAPS_TEXTURE)))
{
lpDDSurfaceDesc->dwFlags |= DDSD_PIXELFORMAT;
lpDDSurfaceDesc->ddpfPixelFormat = CompatPrimarySurface::displayMode.pixelFormat;
TSurfaceDesc desc = *lpDDSurfaceDesc;
desc.dwFlags |= DDSD_PIXELFORMAT;
desc.ddpfPixelFormat = CompatPrimarySurface::displayMode.pixelFormat;
result = s_origVtable.CreateSurface(This, &desc, lplpDDSurface, pUnkOuter);
}
else
{
result = s_origVtable.CreateSurface(This, lpDDSurfaceDesc, lplpDDSurface, pUnkOuter);
}
result = s_origVtable.CreateSurface(This, lpDDSurfaceDesc, lplpDDSurface, pUnkOuter);
}
if (SUCCEEDED(result))

View File

@ -47,7 +47,8 @@ namespace
DDBLTFX fx = {};
fx.dwSize = sizeof(fx);
surface.lpVtbl->Blt(&surface, nullptr, nullptr, nullptr, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.Blt(
&surface, nullptr, nullptr, nullptr, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
}
HRESULT WINAPI enumSurfacesCallback(
@ -55,16 +56,17 @@ namespace
LPDDSURFACEDESC2 lpDDSurfaceDesc,
LPVOID lpContext)
{
auto visitedSurfaces = *static_cast<std::set<IDirectDrawSurface7*>*>(lpContext);
auto& visitedSurfaces = *static_cast<std::set<IDirectDrawSurface7*>*>(lpContext);
if (visitedSurfaces.find(lpDDSurface) == visitedSurfaces.end())
{
visitedSurfaces.insert(lpDDSurface);
fixSurfacePtr(*lpDDSurface, *lpDDSurfaceDesc);
lpDDSurface->lpVtbl->EnumAttachedSurfaces(lpDDSurface, &visitedSurfaces, &enumSurfacesCallback);
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.EnumAttachedSurfaces(
lpDDSurface, lpContext, &enumSurfacesCallback);
}
lpDDSurface->lpVtbl->Release(lpDDSurface);
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.Release(lpDDSurface);
return DDENUMRET_OK;
}
@ -72,11 +74,12 @@ namespace
{
DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc);
surface.lpVtbl->GetSurfaceDesc(&surface, &desc);
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.GetSurfaceDesc(&surface, &desc);
fixSurfacePtr(surface, desc);
std::set<IDirectDrawSurface7*> visitedSurfaces{ &surface };
surface.lpVtbl->EnumAttachedSurfaces(&surface, &visitedSurfaces, &enumSurfacesCallback);
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.EnumAttachedSurfaces(
&surface, &visitedSurfaces, &enumSurfacesCallback);
}
IDirectDrawSurface7* getMirroredSurface(IDirectDrawSurface7& surface, RECT* srcRect, DWORD mirrorFx)

View File

@ -8,6 +8,8 @@ namespace
{
void onRelease()
{
Compat::LogEnter("CompatPrimarySurface::onRelease");
CompatPrimarySurface::surface = nullptr;
CompatPrimarySurface::palette = nullptr;
CompatPrimarySurface::width = 0;
@ -23,6 +25,8 @@ namespace
CompatDirectDrawSurface<IDirectDrawSurface7>::resetPrimarySurfacePtr();
RealPrimarySurface::release();
Compat::LogLeave("CompatPrimarySurface::onRelease");
}
}

View File

@ -85,13 +85,14 @@ namespace
desc.ddpfPixelFormat = CompatPrimarySurface::displayMode.pixelFormat;
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
typename Types<DirectDraw>::TCreatedSurface* surface = nullptr;
HRESULT result = dd.lpVtbl->CreateSurface(&dd, &desc, &surface, nullptr);
typedef typename Types<DirectDraw>::TCreatedSurface TCreatedSurface;
TCreatedSurface* surface = nullptr;
HRESULT result = CompatDirectDraw<DirectDraw>::s_origVtable.CreateSurface(&dd, &desc, &surface, nullptr);
if (SUCCEEDED(result))
{
surface->lpVtbl->QueryInterface(
CompatDirectDrawSurface<TCreatedSurface>::s_origVtable.QueryInterface(
surface, IID_IDirectDrawSurface7, reinterpret_cast<LPVOID*>(&g_paletteConverterSurface));
surface->lpVtbl->Release(surface);
CompatDirectDrawSurface<TCreatedSurface>::s_origVtable.Release(surface);
}
return result;
@ -106,6 +107,8 @@ namespace
void onRelease()
{
Compat::LogEnter("RealPrimarySurface::onRelease");
g_frontBuffer = nullptr;
g_backBuffer = nullptr;
if (g_paletteConverterSurface)
@ -118,6 +121,8 @@ namespace
g_updateEvent = nullptr;
ZeroMemory(&RealPrimarySurface::s_surfaceDesc, sizeof(RealPrimarySurface::s_surfaceDesc));
Compat::LogLeave("RealPrimarySurface::onRelease");
}
void updateNow()
@ -336,9 +341,11 @@ void RealPrimarySurface::setClipper(LPDIRECTDRAWCLIPPER clipper)
void RealPrimarySurface::setPalette(LPDIRECTDRAWPALETTE palette)
{
auto& origVtable = CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable;
if (g_paletteConverterSurface && CompatPrimarySurface::pixelFormat.dwRGBBitCount <= 8)
{
HRESULT result = g_paletteConverterSurface->lpVtbl->SetPalette(g_paletteConverterSurface, palette);
HRESULT result = origVtable.SetPalette(g_paletteConverterSurface, palette);
if (FAILED(result))
{
LOG_ONCE("Failed to set the palette on the converter surface: " << result);
@ -347,14 +354,17 @@ void RealPrimarySurface::setPalette(LPDIRECTDRAWPALETTE palette)
if (s_surfaceDesc.ddpfPixelFormat.dwRGBBitCount <= 8)
{
HRESULT result = g_frontBuffer->lpVtbl->SetPalette(g_frontBuffer, palette);
HRESULT result = origVtable.SetPalette(g_frontBuffer, palette);
if (FAILED(result) && DDERR_NOPALETTEATTACHED != result)
{
LOG_ONCE("Failed to set the palette on the real primary surface: " << result);
}
}
updatePalette();
if (palette)
{
updatePalette();
}
}
void RealPrimarySurface::update()