mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Implemented GetGDISurface and FlipToGDISurface
This commit is contained in:
parent
fbe34c0341
commit
1d14b606c2
@ -9,6 +9,12 @@ template <typename Intf>
|
||||
class CompatPtr : public CompatWeakPtr<Intf>
|
||||
{
|
||||
public:
|
||||
template <typename OtherIntf>
|
||||
static CompatPtr from(OtherIntf* other)
|
||||
{
|
||||
return CompatPtr(Compat::queryInterface<Intf>(other));
|
||||
}
|
||||
|
||||
CompatPtr(std::nullptr_t = nullptr)
|
||||
{
|
||||
}
|
||||
|
@ -40,7 +40,9 @@ namespace DDraw
|
||||
void DirectDraw<TDirectDraw>::setCompatVtable(Vtable<TDirectDraw>& vtable)
|
||||
{
|
||||
vtable.CreateSurface = &CreateSurface;
|
||||
vtable.FlipToGDISurface = &FlipToGDISurface;
|
||||
vtable.GetDisplayMode = &GetDisplayMode;
|
||||
vtable.GetGDISurface = &GetGDISurface;
|
||||
vtable.RestoreDisplayMode = &RestoreDisplayMode;
|
||||
vtable.SetCooperativeLevel = &SetCooperativeLevel;
|
||||
vtable.SetDisplayMode = &SetDisplayMode;
|
||||
@ -74,6 +76,12 @@ namespace DDraw
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::FlipToGDISurface(TDirectDraw* /*This*/)
|
||||
{
|
||||
return PrimarySurface::flipToGdiSurface();
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::GetDisplayMode(
|
||||
TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc)
|
||||
@ -92,6 +100,25 @@ namespace DDraw
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::GetGDISurface(
|
||||
TDirectDraw* /*This*/, TSurface** lplpGDIDDSSurface)
|
||||
{
|
||||
if (!lplpGDIDDSSurface)
|
||||
{
|
||||
return DDERR_INVALIDPARAMS;
|
||||
}
|
||||
|
||||
auto gdiSurface(PrimarySurface::getGdiSurface());
|
||||
if (!gdiSurface)
|
||||
{
|
||||
return DDERR_NOTFOUND;
|
||||
}
|
||||
|
||||
*lplpGDIDDSSurface = CompatPtr<TSurface>::from(gdiSurface.get()).detach();
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::RestoreDisplayMode(TDirectDraw* This)
|
||||
{
|
||||
|
@ -30,7 +30,9 @@ namespace DDraw
|
||||
TSurface** lplpDDSurface,
|
||||
IUnknown* pUnkOuter);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE FlipToGDISurface(TDirectDraw* This);
|
||||
static HRESULT STDMETHODCALLTYPE GetDisplayMode(TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc);
|
||||
static HRESULT STDMETHODCALLTYPE GetGDISurface(TDirectDraw* This, TSurface** lplpGDIDDSSurface);
|
||||
static HRESULT STDMETHODCALLTYPE RestoreDisplayMode(TDirectDraw* This);
|
||||
static HRESULT STDMETHODCALLTYPE SetCooperativeLevel(TDirectDraw* This, HWND hWnd, DWORD dwFlags);
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
namespace
|
||||
{
|
||||
DDSURFACEDESC2 g_primarySurfaceDesc = {};
|
||||
CompatWeakPtr<IDirectDrawSurface> g_gdiSurface = nullptr;
|
||||
CompatWeakPtr<IDirectDrawSurface> g_primarySurface = nullptr;
|
||||
}
|
||||
|
||||
@ -21,6 +22,7 @@ namespace DDraw
|
||||
{
|
||||
Compat::LogEnter("PrimarySurface::~PrimarySurface");
|
||||
|
||||
g_gdiSurface = nullptr;
|
||||
g_primarySurface = nullptr;
|
||||
s_palette = nullptr;
|
||||
ZeroMemory(&s_paletteEntries, sizeof(s_paletteEntries));
|
||||
@ -62,6 +64,7 @@ namespace DDraw
|
||||
attach(*surface7, privateData);
|
||||
|
||||
CompatPtr<IDirectDrawSurface> surface1(Compat::queryInterface<IDirectDrawSurface>(surface));
|
||||
g_gdiSurface = surface1;
|
||||
g_primarySurface = surface1;
|
||||
|
||||
ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
|
||||
@ -89,11 +92,25 @@ namespace DDraw
|
||||
m_impl7.reset(new PrimarySurfaceImpl<IDirectDrawSurface7>(*m_surface->getImpl<IDirectDrawSurface7>()));
|
||||
}
|
||||
|
||||
HRESULT PrimarySurface::flipToGdiSurface()
|
||||
{
|
||||
if (!g_primarySurface)
|
||||
{
|
||||
return DDERR_NOTFOUND;
|
||||
}
|
||||
return g_primarySurface.get()->lpVtbl->Flip(g_primarySurface, g_gdiSurface, DDFLIP_WAIT);
|
||||
}
|
||||
|
||||
const DDSURFACEDESC2& PrimarySurface::getDesc()
|
||||
{
|
||||
return g_primarySurfaceDesc;
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> PrimarySurface::getGdiSurface()
|
||||
{
|
||||
return CompatPtr<IDirectDrawSurface7>::from(g_gdiSurface.get());
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> PrimarySurface::getPrimary()
|
||||
{
|
||||
if (!g_primarySurface)
|
||||
@ -104,6 +121,36 @@ namespace DDraw
|
||||
Compat::queryInterface<IDirectDrawSurface7>(g_primarySurface.get()));
|
||||
}
|
||||
|
||||
void PrimarySurface::updateGdiSurfacePtr(IDirectDrawSurface* flipTargetOverride)
|
||||
{
|
||||
auto primary(CompatPtr<IDirectDrawSurface>::from(m_surface->getDirectDrawSurface().get()));
|
||||
if (flipTargetOverride)
|
||||
{
|
||||
if (g_gdiSurface.get() == flipTargetOverride)
|
||||
{
|
||||
g_gdiSurface = primary;
|
||||
}
|
||||
else if (g_gdiSurface.get() == primary)
|
||||
{
|
||||
g_gdiSurface = flipTargetOverride;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DDSCAPS caps = {};
|
||||
caps.dwCaps = DDSCAPS_FLIP;
|
||||
CompatPtr<IDirectDrawSurface> current(primary);
|
||||
CompatPtr<IDirectDrawSurface> next;
|
||||
HRESULT result = current->GetAttachedSurface(current, &caps, &next.getRef());
|
||||
while (SUCCEEDED(result) && next.get() != g_gdiSurface.get() && next.get() != primary)
|
||||
{
|
||||
current = next;
|
||||
result = current->GetAttachedSurface(current, &caps, &next.getRef());
|
||||
}
|
||||
|
||||
g_gdiSurface = current;
|
||||
}
|
||||
|
||||
CompatWeakPtr<IDirectDrawPalette> PrimarySurface::s_palette;
|
||||
PALETTEENTRY PrimarySurface::s_paletteEntries[256] = {};
|
||||
}
|
||||
|
@ -13,9 +13,13 @@ namespace DDraw
|
||||
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
|
||||
static HRESULT create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface);
|
||||
|
||||
static HRESULT flipToGdiSurface();
|
||||
static const DDSURFACEDESC2& getDesc();
|
||||
static CompatPtr<IDirectDrawSurface7> getGdiSurface();
|
||||
static CompatPtr<IDirectDrawSurface7> getPrimary();
|
||||
|
||||
void updateGdiSurfacePtr(IDirectDrawSurface* flipTargetOverride);
|
||||
|
||||
static CompatWeakPtr<IDirectDrawPalette> s_palette;
|
||||
static PALETTEENTRY s_paletteEntries[256];
|
||||
|
||||
|
@ -85,6 +85,15 @@ namespace DDraw
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = RealPrimarySurface::flip(dwFlags);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
static_cast<PrimarySurface*>(m_data)->updateGdiSurfacePtr(
|
||||
CompatPtr<IDirectDrawSurface>::from(lpDDSurfaceTargetOverride));
|
||||
}
|
||||
else
|
||||
{
|
||||
undoFlip(This, lpDDSurfaceTargetOverride);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -70,6 +70,26 @@ namespace DDraw
|
||||
::fixSurfacePtrs(*surface7);
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
void SurfaceImpl<TSurface>::undoFlip(TSurface* This, TSurface* targetOverride)
|
||||
{
|
||||
if (targetOverride)
|
||||
{
|
||||
SurfaceImpl::Flip(This, targetOverride, DDFLIP_WAIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
TSurfaceDesc desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
s_origVtable.GetSurfaceDesc(This, &desc);
|
||||
|
||||
for (DWORD i = 0; i < desc.dwBackBufferCount; ++i)
|
||||
{
|
||||
SurfaceImpl::Flip(This, nullptr, DDFLIP_WAIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT SurfaceImpl<TSurface>::Blt(
|
||||
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
|
||||
|
@ -55,6 +55,9 @@ namespace DDraw
|
||||
virtual HRESULT SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette);
|
||||
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect);
|
||||
|
||||
protected:
|
||||
void undoFlip(TSurface* This, TSurface* targetOverride);
|
||||
|
||||
private:
|
||||
static const Vtable<TSurface>& s_origVtable;
|
||||
};
|
||||
|
@ -54,12 +54,13 @@ namespace
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool lockPrimarySurface(DWORD lockFlags)
|
||||
bool lockGdiSurface(DWORD lockFlags)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
auto primary(DDraw::PrimarySurface::getPrimary());
|
||||
if (!primary || FAILED(primary->Lock(primary, nullptr, &desc, lockFlags | DDLOCK_WAIT, nullptr)))
|
||||
auto gdiSurface(DDraw::PrimarySurface::getGdiSurface());
|
||||
if (!gdiSurface || FAILED(gdiSurface.get()->lpVtbl->Lock(
|
||||
gdiSurface, nullptr, &desc, lockFlags | DDLOCK_WAIT, nullptr)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -76,13 +77,13 @@ namespace
|
||||
return true;
|
||||
}
|
||||
|
||||
void unlockPrimarySurface()
|
||||
void unlockGdiSurface()
|
||||
{
|
||||
GdiFlush();
|
||||
auto primary(DDraw::PrimarySurface::getPrimary());
|
||||
if (primary)
|
||||
auto gdiSurface(DDraw::PrimarySurface::getGdiSurface());
|
||||
if (gdiSurface)
|
||||
{
|
||||
primary->Unlock(primary, nullptr);
|
||||
gdiSurface.get()->lpVtbl->Unlock(gdiSurface, nullptr);
|
||||
if (DDLOCK_READONLY != g_ddLockFlags)
|
||||
{
|
||||
DDraw::RealPrimarySurface::invalidate(nullptr);
|
||||
@ -118,7 +119,7 @@ namespace Gdi
|
||||
LeaveCriticalSection(&g_gdiCriticalSection);
|
||||
Dll::g_origProcs.AcquireDDThreadLock();
|
||||
EnterCriticalSection(&g_gdiCriticalSection);
|
||||
if (!lockPrimarySurface(lockFlags))
|
||||
if (!lockGdiSurface(lockFlags))
|
||||
{
|
||||
Dll::g_origProcs.ReleaseDDThreadLock();
|
||||
return false;
|
||||
@ -142,7 +143,7 @@ namespace Gdi
|
||||
{
|
||||
if (1 == g_renderingRefCount)
|
||||
{
|
||||
unlockPrimarySurface();
|
||||
unlockGdiSurface();
|
||||
g_ddLockThreadRenderingRefCount = 0;
|
||||
g_renderingRefCount = 0;
|
||||
}
|
||||
@ -151,7 +152,7 @@ namespace Gdi
|
||||
g_isDelayedUnlockPending = true;
|
||||
gdiLock.unlock();
|
||||
WaitForSingleObject(g_ddUnlockBeginEvent, INFINITE);
|
||||
unlockPrimarySurface();
|
||||
unlockGdiSurface();
|
||||
g_ddLockThreadRenderingRefCount = 0;
|
||||
g_renderingRefCount = 0;
|
||||
SetEvent(g_ddUnlockEndEvent);
|
||||
|
Loading…
x
Reference in New Issue
Block a user