mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Emulate flip when the primary surface is requested in system memory
When the primary surface chain is requested to be created in system memory, flip should be emulated (copy from back buffer to front buffer) to be consistent with legacy DirectDraw behavior. Fixes flashing graphical artifacts in Carmageddon (Win95 version) menus when exiting from a race, mentioned in issue #3.
This commit is contained in:
parent
b78446c16f
commit
947bb41bf3
@ -122,20 +122,14 @@ namespace DDraw
|
||||
return s_origVtable.CreateSurface(This, lpDDSurfaceDesc, lplpDDSurface, pUnkOuter);
|
||||
}
|
||||
|
||||
HRESULT result = DD_OK;
|
||||
|
||||
const bool isPrimary = 0 != (lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE);
|
||||
|
||||
if (isPrimary)
|
||||
if (lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
|
||||
{
|
||||
result = PrimarySurface::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface);
|
||||
return PrimarySurface::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = Surface::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface);
|
||||
return Surface::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
|
@ -10,6 +10,7 @@ namespace
|
||||
DDSURFACEDESC2 g_primarySurfaceDesc = {};
|
||||
CompatWeakPtr<IDirectDrawSurface> g_gdiSurface = nullptr;
|
||||
CompatWeakPtr<IDirectDrawSurface> g_primarySurface = nullptr;
|
||||
bool g_isFlipEmulated = false;
|
||||
}
|
||||
|
||||
namespace DDraw
|
||||
@ -25,6 +26,7 @@ namespace DDraw
|
||||
|
||||
g_gdiSurface = nullptr;
|
||||
g_primarySurface = nullptr;
|
||||
g_isFlipEmulated = false;
|
||||
s_palette = nullptr;
|
||||
s_surfaceBuffers.clear();
|
||||
ZeroMemory(&s_paletteEntries, sizeof(s_paletteEntries));
|
||||
@ -67,6 +69,7 @@ namespace DDraw
|
||||
CompatPtr<IDirectDrawSurface> surface1(Compat::queryInterface<IDirectDrawSurface>(surface));
|
||||
g_gdiSurface = surface1;
|
||||
g_primarySurface = surface1;
|
||||
g_isFlipEmulated = 0 != (desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY);
|
||||
|
||||
ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
|
||||
g_primarySurfaceDesc.dwSize = sizeof(g_primarySurfaceDesc);
|
||||
@ -127,6 +130,11 @@ namespace DDraw
|
||||
Compat::queryInterface<IDirectDrawSurface7>(g_primarySurface.get()));
|
||||
}
|
||||
|
||||
bool PrimarySurface::isFlipEmulated()
|
||||
{
|
||||
return g_isFlipEmulated;
|
||||
}
|
||||
|
||||
void PrimarySurface::resizeBuffers(CompatRef<IDirectDrawSurface7> surface)
|
||||
{
|
||||
DDSCAPS2 flipCaps = {};
|
||||
|
@ -20,6 +20,7 @@ namespace DDraw
|
||||
static const DDSURFACEDESC2& getDesc();
|
||||
static CompatPtr<IDirectDrawSurface7> getGdiSurface();
|
||||
static CompatPtr<IDirectDrawSurface7> getPrimary();
|
||||
static bool isFlipEmulated();
|
||||
|
||||
void updateGdiSurfacePtr(IDirectDrawSurface* flipTargetOverride);
|
||||
|
||||
|
@ -80,19 +80,38 @@ namespace DDraw
|
||||
}
|
||||
|
||||
HRESULT result = m_impl.Flip(This, lpDDSurfaceTargetOverride, dwFlags);
|
||||
if (SUCCEEDED(result))
|
||||
if (FAILED(result))
|
||||
{
|
||||
result = RealPrimarySurface::flip(dwFlags);
|
||||
if (SUCCEEDED(result))
|
||||
return result;
|
||||
}
|
||||
|
||||
result = RealPrimarySurface::flip(dwFlags);
|
||||
if (SUCCEEDED(result) && !PrimarySurface::isFlipEmulated())
|
||||
{
|
||||
static_cast<PrimarySurface*>(m_data)->updateGdiSurfacePtr(
|
||||
CompatPtr<IDirectDrawSurface>::from(lpDDSurfaceTargetOverride));
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
undoFlip(This, lpDDSurfaceTargetOverride);
|
||||
|
||||
if (SUCCEEDED(result) && PrimarySurface::isFlipEmulated())
|
||||
{
|
||||
if (lpDDSurfaceTargetOverride)
|
||||
{
|
||||
static_cast<PrimarySurface*>(m_data)->updateGdiSurfacePtr(
|
||||
CompatPtr<IDirectDrawSurface>::from(lpDDSurfaceTargetOverride));
|
||||
s_origVtable.BltFast(This, 0, 0, lpDDSurfaceTargetOverride, nullptr, DDBLTFAST_WAIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
undoFlip(This, lpDDSurfaceTargetOverride);
|
||||
TDdsCaps caps = {};
|
||||
caps.dwCaps = DDSCAPS_BACKBUFFER;
|
||||
CompatPtr<TSurface> backBuffer;
|
||||
s_origVtable.GetAttachedSurface(This, &caps, &backBuffer.getRef());
|
||||
|
||||
s_origVtable.BltFast(This, 0, 0, backBuffer, nullptr, DDBLTFAST_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,8 @@ namespace DDraw
|
||||
protected:
|
||||
void undoFlip(TSurface* This, TSurface* targetOverride);
|
||||
|
||||
static const Vtable<TSurface>& s_origVtable;
|
||||
|
||||
private:
|
||||
bool bltRetry(TSurface*& dstSurface, RECT*& dstRect,
|
||||
TSurface*& srcSurface, RECT*& srcRect, bool isTransparentBlt,
|
||||
@ -63,7 +65,5 @@ namespace DDraw
|
||||
bool prepareBltRetrySurface(TSurface*& surface, RECT*& rect,
|
||||
const TSurfaceDesc& desc, bool isTransparentBlt, bool isCopyNeeded);
|
||||
void replaceWithVidMemSurface(TSurface*& surface, RECT*& rect, const TSurfaceDesc& desc);
|
||||
|
||||
static const Vtable<TSurface>& s_origVtable;
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user