diff --git a/DDrawCompat/DDraw/DirectDraw.cpp b/DDrawCompat/DDraw/DirectDraw.cpp index 3675112..1936661 100644 --- a/DDrawCompat/DDraw/DirectDraw.cpp +++ b/DDrawCompat/DDraw/DirectDraw.cpp @@ -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(*This, *lpDDSurfaceDesc, *lplpDDSurface); + return PrimarySurface::create(*This, *lpDDSurfaceDesc, *lplpDDSurface); } else { - result = Surface::create(*This, *lpDDSurfaceDesc, *lplpDDSurface); + return Surface::create(*This, *lpDDSurfaceDesc, *lplpDDSurface); } - - return result; } template diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp index e438c29..8c62e2a 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp @@ -10,6 +10,7 @@ namespace DDSURFACEDESC2 g_primarySurfaceDesc = {}; CompatWeakPtr g_gdiSurface = nullptr; CompatWeakPtr 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 surface1(Compat::queryInterface(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(g_primarySurface.get())); } + bool PrimarySurface::isFlipEmulated() + { + return g_isFlipEmulated; + } + void PrimarySurface::resizeBuffers(CompatRef surface) { DDSCAPS2 flipCaps = {}; diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.h b/DDrawCompat/DDraw/Surfaces/PrimarySurface.h index 9ae577f..37478f0 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurface.h +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.h @@ -20,6 +20,7 @@ namespace DDraw static const DDSURFACEDESC2& getDesc(); static CompatPtr getGdiSurface(); static CompatPtr getPrimary(); + static bool isFlipEmulated(); void updateGdiSurfacePtr(IDirectDrawSurface* flipTargetOverride); diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp index c0b7542..59b1673 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp @@ -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(m_data)->updateGdiSurfacePtr( + CompatPtr::from(lpDDSurfaceTargetOverride)); + return DD_OK; + } + + undoFlip(This, lpDDSurfaceTargetOverride); + + if (SUCCEEDED(result) && PrimarySurface::isFlipEmulated()) + { + if (lpDDSurfaceTargetOverride) { - static_cast(m_data)->updateGdiSurfacePtr( - CompatPtr::from(lpDDSurfaceTargetOverride)); + s_origVtable.BltFast(This, 0, 0, lpDDSurfaceTargetOverride, nullptr, DDBLTFAST_WAIT); } else { - undoFlip(This, lpDDSurfaceTargetOverride); + TDdsCaps caps = {}; + caps.dwCaps = DDSCAPS_BACKBUFFER; + CompatPtr backBuffer; + s_origVtable.GetAttachedSurface(This, &caps, &backBuffer.getRef()); + + s_origVtable.BltFast(This, 0, 0, backBuffer, nullptr, DDBLTFAST_WAIT); } } + return result; } diff --git a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h index fa35f19..9e4d56f 100644 --- a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h +++ b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h @@ -56,6 +56,8 @@ namespace DDraw protected: void undoFlip(TSurface* This, TSurface* targetOverride); + static const Vtable& 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& s_origVtable; }; }