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

Moved CompatPrimarySurface implementation to separate layer

This commit is contained in:
narzoul 2016-09-11 17:34:39 +02:00
parent 19cce6b9d6
commit 0dbd210649
19 changed files with 450 additions and 369 deletions

View File

@ -2,9 +2,9 @@
#include "Common/CompatRef.h"
#include "Common/Log.h"
#include "DDraw/ActivateAppHandler.h"
#include "DDraw/CompatPrimarySurface.h"
#include "DDraw/DirectDraw.h"
#include "DDraw/DisplayMode.h"
#include "DDraw/Surfaces/PrimarySurface.h"
#include "DDraw/Surfaces/SurfaceImpl.h"
#include "Gdi/Gdi.h"
#include "Win32/FontSmoothing.h"
@ -38,7 +38,7 @@ namespace
auto dm = DDraw::DisplayMode::getDisplayMode(dd);
dd->SetDisplayMode(&dd, dm.dwWidth, dm.dwHeight, 32, dm.dwRefreshRate, 0);
auto primary(DDraw::CompatPrimarySurface::getPrimary());
auto primary(DDraw::PrimarySurface::getPrimary());
if (primary && SUCCEEDED(primary->Restore(primary)))
{
DDraw::SurfaceImpl<IDirectDrawSurface7>::fixSurfacePtrs(*primary);

View File

@ -1,85 +0,0 @@
#include <algorithm>
#include <vector>
#include "Common/CompatPtr.h"
#include "DDraw/CompatPrimarySurface.h"
#include "DDraw/DirectDrawSurface.h"
#include "DDraw/IReleaseNotifier.h"
#include "DDraw/RealPrimarySurface.h"
namespace
{
void onRelease();
DDSURFACEDESC2 g_primarySurfaceDesc = {};
CompatWeakPtr<IDirectDrawSurface> g_primarySurface = nullptr;
std::vector<void*> g_primarySurfacePtrs;
DDraw::IReleaseNotifier g_releaseNotifier(onRelease);
void onRelease()
{
Compat::LogEnter("CompatPrimarySurface::onRelease");
g_primarySurfacePtrs.clear();
g_primarySurface = nullptr;
DDraw::CompatPrimarySurface::g_palette = nullptr;
ZeroMemory(&DDraw::CompatPrimarySurface::g_paletteEntries,
sizeof(DDraw::CompatPrimarySurface::g_paletteEntries));
ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
DDraw::RealPrimarySurface::release();
Compat::LogLeave("CompatPrimarySurface::onRelease");
}
}
namespace DDraw
{
namespace CompatPrimarySurface
{
const DDSURFACEDESC2& getDesc()
{
return g_primarySurfaceDesc;
}
CompatPtr<IDirectDrawSurface7> getPrimary()
{
if (!g_primarySurface)
{
return nullptr;
}
return CompatPtr<IDirectDrawSurface7>(
Compat::queryInterface<IDirectDrawSurface7>(g_primarySurface.get()));
}
bool isPrimary(void* surface)
{
return g_primarySurfacePtrs.end() !=
std::find(g_primarySurfacePtrs.begin(), g_primarySurfacePtrs.end(), surface);
}
void setPrimary(CompatRef<IDirectDrawSurface7> surface)
{
CompatPtr<IDirectDrawSurface> surfacePtr(Compat::queryInterface<IDirectDrawSurface>(&surface));
g_primarySurface = surfacePtr;
ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
g_primarySurfaceDesc.dwSize = sizeof(g_primarySurfaceDesc);
surface->GetSurfaceDesc(&surface, &g_primarySurfaceDesc);
g_primarySurfacePtrs.clear();
g_primarySurfacePtrs.push_back(&surface);
g_primarySurfacePtrs.push_back(CompatPtr<IDirectDrawSurface4>(surfacePtr));
g_primarySurfacePtrs.push_back(CompatPtr<IDirectDrawSurface3>(surfacePtr));
g_primarySurfacePtrs.push_back(CompatPtr<IDirectDrawSurface2>(surfacePtr));
g_primarySurfacePtrs.push_back(surfacePtr);
IReleaseNotifier* releaseNotifierPtr = &g_releaseNotifier;
surface->SetPrivateData(&surface, IID_IReleaseNotifier,
releaseNotifierPtr, sizeof(releaseNotifierPtr), DDSPD_IUNKNOWNPOINTER);
}
CompatWeakPtr<IDirectDrawPalette> g_palette;
PALETTEENTRY g_paletteEntries[256] = {};
}
}

View File

@ -1,22 +0,0 @@
#pragma once
#define CINTERFACE
#include <ddraw.h>
#include "Common/CompatPtr.h"
#include "Common/CompatRef.h"
namespace DDraw
{
namespace CompatPrimarySurface
{
const DDSURFACEDESC2& getDesc();
CompatPtr<IDirectDrawSurface7> getPrimary();
bool isPrimary(void* surface);
void setPrimary(CompatRef<IDirectDrawSurface7> surface);
extern CompatWeakPtr<IDirectDrawPalette> g_palette;
extern PALETTEENTRY g_paletteEntries[256];
}
}

View File

@ -5,8 +5,8 @@
#include "DDraw/DirectDrawSurface.h"
#include "DDraw/DisplayMode.h"
#include "DDraw/IReleaseNotifier.h"
#include "DDraw/Surfaces/PrimarySurface.h"
#include "DDraw/Surfaces/Surface.h"
#include "DDraw/Surfaces/SurfaceImpl.h"
namespace
{
@ -119,8 +119,7 @@ namespace DDraw
if (isPrimary)
{
result = SurfaceImpl<TSurface>::createCompatPrimarySurface<TDirectDraw>(
*This, *lpDDSurfaceDesc, *lplpDDSurface);
result = PrimarySurface::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface);
}
else
{

View File

@ -3,9 +3,9 @@
#include "Common/Time.h"
#include "Config/Config.h"
#include "DDraw/CompatPrimarySurface.h"
#include "DDraw/DirectDrawPalette.h"
#include "DDraw/RealPrimarySurface.h"
#include "DDraw/Surfaces/PrimarySurface.h"
namespace DDraw
{
@ -21,11 +21,11 @@ namespace DDraw
DWORD dwCount,
LPPALETTEENTRY lpEntries)
{
if (This == CompatPrimarySurface::g_palette)
if (This == PrimarySurface::s_palette)
{
waitForNextUpdate();
if (lpEntries && dwStartingEntry + dwCount <= 256 &&
0 == std::memcmp(&CompatPrimarySurface::g_paletteEntries[dwStartingEntry],
0 == std::memcmp(&PrimarySurface::s_paletteEntries[dwStartingEntry],
lpEntries, dwCount * sizeof(PALETTEENTRY)))
{
return DD_OK;
@ -33,9 +33,9 @@ namespace DDraw
}
HRESULT result = s_origVtable.SetEntries(This, dwFlags, dwStartingEntry, dwCount, lpEntries);
if (This == CompatPrimarySurface::g_palette && SUCCEEDED(result))
if (This == PrimarySurface::s_palette && SUCCEEDED(result))
{
std::memcpy(&CompatPrimarySurface::g_paletteEntries[dwStartingEntry], lpEntries,
std::memcpy(&PrimarySurface::s_paletteEntries[dwStartingEntry], lpEntries,
dwCount * sizeof(PALETTEENTRY));
RealPrimarySurface::updatePalette(dwStartingEntry, dwCount);
}

View File

@ -4,11 +4,11 @@
#include "Common/CompatPtr.h"
#include "Common/Hook.h"
#include "Common/ScopedCriticalSection.h"
#include "DDraw/CompatPrimarySurface.h"
#include "DDraw/DisplayMode.h"
#include "DDraw/PaletteConverter.h"
#include "DDraw/RealPrimarySurface.h"
#include "DDraw/Repository.h"
#include "DDraw/Surfaces/PrimarySurface.h"
#include "DDraw/Types.h"
namespace
@ -151,10 +151,10 @@ namespace DDraw
void updatePalette(DWORD startingEntry, DWORD count)
{
if (g_dc && CompatPrimarySurface::g_palette)
if (g_dc && PrimarySurface::s_palette)
{
RGBQUAD entries[256] = {};
std::memcpy(entries, &CompatPrimarySurface::g_paletteEntries[startingEntry],
std::memcpy(entries, &PrimarySurface::s_paletteEntries[startingEntry],
count * sizeof(PALETTEENTRY));
convertPaletteEntriesToRgbQuad(entries, count);
SetDIBColorTable(g_dc, startingEntry, count, entries);

View File

@ -4,12 +4,12 @@
#include "Common/Hook.h"
#include "Common/Time.h"
#include "Config/Config.h"
#include "DDraw/CompatPrimarySurface.h"
#include "DDraw/DirectDrawSurface.h"
#include "DDraw/IReleaseNotifier.h"
#include "DDraw/PaletteConverter.h"
#include "DDraw/RealPrimarySurface.h"
#include "DDraw/ScopedThreadLock.h"
#include "DDraw/Surfaces/PrimarySurface.h"
#include "DDraw/Types.h"
#include "Gdi/Gdi.h"
@ -46,8 +46,8 @@ namespace
bool result = false;
auto primary(DDraw::CompatPrimarySurface::getPrimary());
if (DDraw::CompatPrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount <= 8)
auto primary(DDraw::PrimarySurface::getPrimary());
if (DDraw::PrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount <= 8)
{
auto paletteConverter(DDraw::PaletteConverter::getSurface());
paletteConverter->Blt(paletteConverter, &g_updateRect,
@ -291,7 +291,7 @@ namespace DDraw
}
else
{
auto primaryDesc = CompatPrimarySurface::getDesc();
auto primaryDesc = PrimarySurface::getDesc();
SetRect(&g_updateRect, 0, 0, primaryDesc.dwWidth, primaryDesc.dwHeight);
}
}
@ -351,7 +351,7 @@ namespace DDraw
{
if (g_surfaceDesc.ddpfPixelFormat.dwRGBBitCount <= 8)
{
g_frontBuffer->SetPalette(g_frontBuffer, CompatPrimarySurface::g_palette);
g_frontBuffer->SetPalette(g_frontBuffer, PrimarySurface::s_palette);
}
updatePalette(0, 256);
@ -377,7 +377,7 @@ namespace DDraw
{
PaletteConverter::updatePalette(startingEntry, count);
Gdi::updatePalette(startingEntry, count);
if (CompatPrimarySurface::g_palette)
if (PrimarySurface::s_palette)
{
invalidate(nullptr);
update();

View File

@ -0,0 +1,104 @@
#include "Common/CompatPtr.h"
#include "DDraw/DisplayMode.h"
#include "DDraw/RealPrimarySurface.h"
#include "DDraw/Surfaces/PrimarySurface.h"
#include "DDraw/Surfaces/PrimarySurfaceImpl.h"
namespace
{
DDSURFACEDESC2 g_primarySurfaceDesc = {};
CompatWeakPtr<IDirectDrawSurface> g_primarySurface = nullptr;
}
namespace DDraw
{
PrimarySurface::~PrimarySurface()
{
Compat::LogEnter("PrimarySurface::~PrimarySurface");
g_primarySurface = nullptr;
s_palette = nullptr;
ZeroMemory(&s_paletteEntries, sizeof(s_paletteEntries));
ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
DDraw::RealPrimarySurface::release();
Compat::LogLeave("PrimarySurface::~PrimarySurface");
}
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
HRESULT PrimarySurface::create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface)
{
HRESULT result = RealPrimarySurface::create(dd);
if (FAILED(result))
{
return result;
}
CompatPtr<IDirectDraw7> dd7(Compat::queryInterface<IDirectDraw7>(&dd));
const auto& dm = DisplayMode::getDisplayMode(*dd7);
desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
desc.dwWidth = dm.dwWidth;
desc.dwHeight = dm.dwHeight;
desc.ddsCaps.dwCaps &= ~DDSCAPS_PRIMARYSURFACE;
desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
desc.ddpfPixelFormat = dm.ddpfPixelFormat;
result = Surface::create(dd, desc, surface);
if (FAILED(result))
{
Compat::Log() << "Failed to create the compat primary surface!";
RealPrimarySurface::release();
return result;
}
CompatPtr<IDirectDrawSurface7> surface7(Compat::queryInterface<IDirectDrawSurface7>(surface));
std::unique_ptr<Surface> privateData(new PrimarySurface());
attach(*surface7, privateData);
CompatPtr<IDirectDrawSurface> surface1(Compat::queryInterface<IDirectDrawSurface>(surface));
g_primarySurface = surface1;
ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
g_primarySurfaceDesc.dwSize = sizeof(g_primarySurfaceDesc);
CompatVtableBase<IDirectDrawSurface7>::s_origVtable.GetSurfaceDesc(surface7, &g_primarySurfaceDesc);
return DD_OK;
}
template HRESULT PrimarySurface::create(
CompatRef<IDirectDraw> dd, DDSURFACEDESC desc, IDirectDrawSurface*& surface);
template HRESULT PrimarySurface::create(
CompatRef<IDirectDraw2> dd, DDSURFACEDESC desc, IDirectDrawSurface*& surface);
template HRESULT PrimarySurface::create(
CompatRef<IDirectDraw4> dd, DDSURFACEDESC2 desc, IDirectDrawSurface4*& surface);
template HRESULT PrimarySurface::create(
CompatRef<IDirectDraw7> dd, DDSURFACEDESC2 desc, IDirectDrawSurface7*& surface);
void PrimarySurface::createImpl()
{
m_impl.reset(new PrimarySurfaceImpl<IDirectDrawSurface>());
m_impl2.reset(new PrimarySurfaceImpl<IDirectDrawSurface2>());
m_impl3.reset(new PrimarySurfaceImpl<IDirectDrawSurface3>());
m_impl4.reset(new PrimarySurfaceImpl<IDirectDrawSurface4>());
m_impl7.reset(new PrimarySurfaceImpl<IDirectDrawSurface7>());
}
const DDSURFACEDESC2& PrimarySurface::getDesc()
{
return g_primarySurfaceDesc;
}
CompatPtr<IDirectDrawSurface7> PrimarySurface::getPrimary()
{
if (!g_primarySurface)
{
return nullptr;
}
return CompatPtr<IDirectDrawSurface7>(
Compat::queryInterface<IDirectDrawSurface7>(g_primarySurface.get()));
}
CompatWeakPtr<IDirectDrawPalette> PrimarySurface::s_palette;
PALETTEENTRY PrimarySurface::s_paletteEntries[256] = {};
}

View File

@ -0,0 +1,25 @@
#pragma once
#include "Common/CompatPtr.h"
#include "DDraw/Surfaces/Surface.h"
namespace DDraw
{
class PrimarySurface : public Surface
{
public:
virtual ~PrimarySurface();
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
static HRESULT create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface);
static const DDSURFACEDESC2& getDesc();
static CompatPtr<IDirectDrawSurface7> getPrimary();
static CompatWeakPtr<IDirectDrawPalette> s_palette;
static PALETTEENTRY s_paletteEntries[256];
private:
virtual void createImpl() override;
};
}

View File

@ -0,0 +1,230 @@
#include "DDraw/DirectDrawPalette.h"
#include "DDraw/RealPrimarySurface.h"
#include "DDraw/Surfaces/PrimarySurface.h"
#include "DDraw/Surfaces/PrimarySurfaceImpl.h"
#include "Gdi/Gdi.h"
namespace
{
void restorePrimaryCaps(DWORD& caps)
{
caps &= ~DDSCAPS_OFFSCREENPLAIN;
caps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE;
}
}
namespace DDraw
{
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::Blt(
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
DWORD dwFlags, LPDDBLTFX lpDDBltFx)
{
if (RealPrimarySurface::isLost())
{
return DDERR_SURFACELOST;
}
HRESULT result = SurfaceImpl::Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
if (SUCCEEDED(result))
{
RealPrimarySurface::invalidate(lpDestRect);
RealPrimarySurface::update();
}
return result;
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::BltFast(
TSurface* This, DWORD dwX, DWORD dwY, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans)
{
if (RealPrimarySurface::isLost())
{
return DDERR_SURFACELOST;
}
HRESULT result = SurfaceImpl::BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
if (SUCCEEDED(result))
{
const LONG x = dwX;
const LONG y = dwY;
RECT destRect = { x, y, x, y };
if (lpSrcRect)
{
destRect.right += lpSrcRect->right - lpSrcRect->left;
destRect.bottom += lpSrcRect->bottom - lpSrcRect->top;
}
else
{
TSurfaceDesc desc = {};
desc.dwSize = sizeof(desc);
CompatVtableBase<TSurface>::s_origVtable.GetSurfaceDesc(lpDDSrcSurface, &desc);
destRect.right += desc.dwWidth;
destRect.bottom += desc.dwHeight;
}
RealPrimarySurface::invalidate(&destRect);
RealPrimarySurface::update();
}
return result;
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags)
{
if (RealPrimarySurface::isLost())
{
return DDERR_SURFACELOST;
}
HRESULT result = SurfaceImpl::Flip(This, lpDDSurfaceTargetOverride, dwFlags);
if (SUCCEEDED(result))
{
result = RealPrimarySurface::flip(dwFlags);
}
return result;
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
{
HRESULT result = SurfaceImpl::GetCaps(This, lpDDSCaps);
if (SUCCEEDED(result))
{
restorePrimaryCaps(lpDDSCaps->dwCaps);
}
return result;
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc)
{
HRESULT result = SurfaceImpl::GetSurfaceDesc(This, lpDDSurfaceDesc);
if (SUCCEEDED(result))
{
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
}
return result;
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::IsLost(TSurface* This)
{
HRESULT result = SurfaceImpl::IsLost(This);
if (SUCCEEDED(result))
{
result = RealPrimarySurface::isLost() ? DDERR_SURFACELOST : DD_OK;
}
return result;
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::Lock(
TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
DWORD dwFlags, HANDLE hEvent)
{
if (RealPrimarySurface::isLost())
{
return DDERR_SURFACELOST;
}
HRESULT result = SurfaceImpl::Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
if (SUCCEEDED(result))
{
RealPrimarySurface::invalidate(lpDestRect);
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
}
return result;
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::QueryInterface(TSurface* This, REFIID riid, LPVOID* obp)
{
if (riid == IID_IDirectDrawGammaControl)
{
auto realPrimary(RealPrimarySurface::getSurface());
return realPrimary->QueryInterface(realPrimary, riid, obp);
}
return SurfaceImpl::QueryInterface(This, riid, obp);
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::ReleaseDC(TSurface* This, HDC hDC)
{
HRESULT result = SurfaceImpl::ReleaseDC(This, hDC);
if (SUCCEEDED(result))
{
RealPrimarySurface::invalidate(nullptr);
RealPrimarySurface::update();
}
return result;
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::Restore(TSurface* This)
{
HRESULT result = IsLost(This);
if (FAILED(result))
{
result = RealPrimarySurface::restore();
if (SUCCEEDED(result))
{
result = SurfaceImpl::Restore(This);
if (SUCCEEDED(result))
{
fixSurfacePtrs(*This);
Gdi::invalidate(nullptr);
}
}
}
return result;
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper)
{
HRESULT result = SurfaceImpl::SetClipper(This, lpDDClipper);
if (SUCCEEDED(result))
{
RealPrimarySurface::setClipper(lpDDClipper);
}
return result;
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette)
{
if (lpDDPalette)
{
DirectDrawPalette::waitForNextUpdate();
}
if (lpDDPalette == PrimarySurface::s_palette)
{
return DD_OK;
}
HRESULT result = SurfaceImpl::SetPalette(This, lpDDPalette);
if (SUCCEEDED(result))
{
PrimarySurface::s_palette = lpDDPalette;
RealPrimarySurface::setPalette();
}
return result;
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::Unlock(TSurface* This, TUnlockParam lpRect)
{
HRESULT result = SurfaceImpl::Unlock(This, lpRect);
if (SUCCEEDED(result))
{
RealPrimarySurface::update();
}
return result;
}
template PrimarySurfaceImpl<IDirectDrawSurface>;
template PrimarySurfaceImpl<IDirectDrawSurface2>;
template PrimarySurfaceImpl<IDirectDrawSurface3>;
template PrimarySurfaceImpl<IDirectDrawSurface4>;
template PrimarySurfaceImpl<IDirectDrawSurface7>;
}

View File

@ -0,0 +1,35 @@
#pragma once
#define CINTERFACE
#include <ddraw.h>
#include "Common/CompatRef.h"
#include "Common/CompatVtable.h"
#include "DDraw/Surfaces/SurfaceImpl.h"
#include "DDraw/Types.h"
namespace DDraw
{
template <typename TSurface>
class PrimarySurfaceImpl : public SurfaceImpl<TSurface>
{
public:
virtual HRESULT Blt(TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
DWORD dwFlags, LPDDBLTFX lpDDBltFx) override;
virtual HRESULT BltFast(TSurface* This, DWORD dwX, DWORD dwY,
TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) override;
virtual HRESULT Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags) override;
virtual HRESULT GetCaps(TSurface* This, TDdsCaps* lpDDSCaps) override;
virtual HRESULT GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc) override;
virtual HRESULT IsLost(TSurface* This) override;
virtual HRESULT Lock(TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
DWORD dwFlags, HANDLE hEvent) override;
virtual HRESULT QueryInterface(TSurface* This, REFIID riid, LPVOID* obp) override;
virtual HRESULT ReleaseDC(TSurface* This, HDC hDC) override;
virtual HRESULT Restore(TSurface* This) override;
virtual HRESULT SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper) override;
virtual HRESULT SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette) override;
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect) override;
};
}

View File

@ -1,22 +1,15 @@
#include <set>
#include "Common/CompatPtr.h"
#include "DDraw/CompatPrimarySurface.h"
#include "DDraw/DirectDrawPalette.h"
#include "DDraw/DisplayMode.h"
#include "DDraw/RealPrimarySurface.h"
#include "DDraw/Repository.h"
#include "DDraw/Surfaces/Surface.h"
#include "DDraw/Surfaces/SurfaceImpl.h"
#include "Gdi/Gdi.h"
namespace
{
bool mirrorBlt(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src,
RECT srcRect, DWORD mirrorFx);
bool g_lockingPrimary = false;
void fixSurfacePtr(CompatRef<IDirectDrawSurface7> surface, const DDSURFACEDESC2& desc)
{
if ((desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) || 0 == desc.dwWidth || 0 == desc.dwHeight)
@ -153,42 +146,6 @@ namespace
namespace DDraw
{
template <typename TSurface>
template <typename TDirectDraw>
HRESULT SurfaceImpl<TSurface>::createCompatPrimarySurface(
CompatRef<TDirectDraw> dd,
TSurfaceDesc compatDesc,
TSurface*& compatSurface)
{
HRESULT result = RealPrimarySurface::create(dd);
if (FAILED(result))
{
return result;
}
CompatPtr<IDirectDraw7> dd7(Compat::queryInterface<IDirectDraw7>(&dd));
const auto& dm = DisplayMode::getDisplayMode(*dd7);
compatDesc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
compatDesc.dwWidth = dm.dwWidth;
compatDesc.dwHeight = dm.dwHeight;
compatDesc.ddsCaps.dwCaps &= ~DDSCAPS_PRIMARYSURFACE;
compatDesc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
compatDesc.ddpfPixelFormat = dm.ddpfPixelFormat;
result = Surface::create(dd, compatDesc, compatSurface);
if (FAILED(result))
{
Compat::Log() << "Failed to create the compat primary surface!";
RealPrimarySurface::release();
return result;
}
CompatPtr<IDirectDrawSurface7> primary(Compat::queryInterface<IDirectDrawSurface7>(compatSurface));
CompatPrimarySurface::setPrimary(*primary);
return DD_OK;
}
template <typename TSurface>
SurfaceImpl<TSurface>::~SurfaceImpl()
{
@ -206,13 +163,6 @@ namespace DDraw
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
DWORD dwFlags, LPDDBLTFX lpDDBltFx)
{
const bool isPrimaryDest = CompatPrimarySurface::isPrimary(This);
if ((isPrimaryDest || CompatPrimarySurface::isPrimary(lpDDSrcSurface)) &&
RealPrimarySurface::isLost())
{
return DDERR_SURFACELOST;
}
HRESULT result = DD_OK;
CompatPtr<TSurface> mirroredSrcSurface;
@ -261,12 +211,6 @@ namespace DDraw
result = s_origVtable.Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
}
if (isPrimaryDest && SUCCEEDED(result))
{
RealPrimarySurface::invalidate(lpDestRect);
RealPrimarySurface::update();
}
return result;
}
@ -274,80 +218,31 @@ namespace DDraw
HRESULT SurfaceImpl<TSurface>::BltFast(
TSurface* This, DWORD dwX, DWORD dwY, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans)
{
const bool isPrimaryDest = CompatPrimarySurface::isPrimary(This);
if ((isPrimaryDest || CompatPrimarySurface::isPrimary(lpDDSrcSurface)) &&
RealPrimarySurface::isLost())
{
return DDERR_SURFACELOST;
}
HRESULT result = s_origVtable.BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
if (isPrimaryDest && SUCCEEDED(result))
{
const LONG x = dwX;
const LONG y = dwY;
RECT destRect = { x, y, x, y };
if (lpSrcRect)
{
destRect.right += lpSrcRect->right - lpSrcRect->left;
destRect.bottom += lpSrcRect->bottom - lpSrcRect->top;
}
else
{
TSurfaceDesc desc = {};
desc.dwSize = sizeof(desc);
s_origVtable.GetSurfaceDesc(lpDDSrcSurface, &desc);
destRect.right += desc.dwWidth;
destRect.bottom += desc.dwHeight;
}
RealPrimarySurface::invalidate(&destRect);
RealPrimarySurface::update();
}
return result;
return s_origVtable.BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags)
{
HRESULT result = s_origVtable.Flip(This, lpDDSurfaceTargetOverride, dwFlags);
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
{
result = RealPrimarySurface::flip(dwFlags);
}
return result;
return s_origVtable.Flip(This, lpDDSurfaceTargetOverride, dwFlags);
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
{
HRESULT result = s_origVtable.GetCaps(This, lpDDSCaps);
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
{
restorePrimaryCaps(*lpDDSCaps);
}
return result;
return s_origVtable.GetCaps(This, lpDDSCaps);
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc)
{
HRESULT result = s_origVtable.GetSurfaceDesc(This, lpDDSurfaceDesc);
if (SUCCEEDED(result) && !g_lockingPrimary && CompatPrimarySurface::isPrimary(This))
{
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps);
}
return result;
return s_origVtable.GetSurfaceDesc(This, lpDDSurfaceDesc);
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::IsLost(TSurface* This)
{
HRESULT result = s_origVtable.IsLost(This);
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
{
result = RealPrimarySurface::isLost() ? DDERR_SURFACELOST : DD_OK;
}
return result;
return s_origVtable.IsLost(This);
}
template <typename TSurface>
@ -355,22 +250,8 @@ namespace DDraw
TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
DWORD dwFlags, HANDLE hEvent)
{
if (CompatPrimarySurface::isPrimary(This))
{
if (RealPrimarySurface::isLost())
{
return DDERR_SURFACELOST;
}
g_lockingPrimary = true;
}
HRESULT result = s_origVtable.Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
if (SUCCEEDED(result) && g_lockingPrimary && lpDDSurfaceDesc)
{
RealPrimarySurface::invalidate(lpDestRect);
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps);
}
else if (DDERR_SURFACELOST == result)
if (DDERR_SURFACELOST == result)
{
TSurfaceDesc desc = {};
desc.dwSize = sizeof(desc);
@ -382,114 +263,43 @@ namespace DDraw
}
}
g_lockingPrimary = false;
return result;
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::QueryInterface(TSurface* This, REFIID riid, LPVOID* obp)
{
if (riid == IID_IDirectDrawGammaControl && CompatPrimarySurface::isPrimary(This))
{
auto realPrimary(RealPrimarySurface::getSurface());
return realPrimary->QueryInterface(realPrimary, riid, obp);
}
return s_origVtable.QueryInterface(This, riid, obp);
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::ReleaseDC(TSurface* This, HDC hDC)
{
const bool isPrimary = CompatPrimarySurface::isPrimary(This);
if (isPrimary && RealPrimarySurface::isLost())
{
return DDERR_SURFACELOST;
}
HRESULT result = s_origVtable.ReleaseDC(This, hDC);
if (isPrimary && SUCCEEDED(result))
{
RealPrimarySurface::invalidate(nullptr);
RealPrimarySurface::update();
}
return result;
return s_origVtable.ReleaseDC(This, hDC);
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::Restore(TSurface* This)
{
const bool wasLost = DDERR_SURFACELOST == s_origVtable.IsLost(This);
HRESULT result = s_origVtable.Restore(This);
if (SUCCEEDED(result))
{
if (wasLost)
{
fixSurfacePtrs(*This);
}
if (CompatPrimarySurface::isPrimary(This))
{
result = RealPrimarySurface::restore();
if (wasLost)
{
Gdi::invalidate(nullptr);
}
}
}
return result;
return s_origVtable.Restore(This);
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper)
{
HRESULT result = s_origVtable.SetClipper(This, lpDDClipper);
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
{
RealPrimarySurface::setClipper(lpDDClipper);
}
return result;
return s_origVtable.SetClipper(This, lpDDClipper);
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette)
{
const bool isPrimary = CompatPrimarySurface::isPrimary(This);
if (isPrimary)
{
if (lpDDPalette)
{
DirectDrawPalette::waitForNextUpdate();
}
if (lpDDPalette == CompatPrimarySurface::g_palette)
{
return DD_OK;
}
}
HRESULT result = s_origVtable.SetPalette(This, lpDDPalette);
if (isPrimary && SUCCEEDED(result))
{
CompatPrimarySurface::g_palette = lpDDPalette;
RealPrimarySurface::setPalette();
}
return result;
return s_origVtable.SetPalette(This, lpDDPalette);
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::Unlock(TSurface* This, TUnlockParam lpRect)
{
HRESULT result = s_origVtable.Unlock(This, lpRect);
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
{
RealPrimarySurface::update();
}
return result;
}
template <typename TSurface>
void SurfaceImpl<TSurface>::restorePrimaryCaps(TDdsCaps& caps)
{
caps.dwCaps &= ~(DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY);
caps.dwCaps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
return s_origVtable.Unlock(This, lpRect);
}
template <typename TSurface>
@ -500,21 +310,4 @@ namespace DDraw
template SurfaceImpl<IDirectDrawSurface3>;
template SurfaceImpl<IDirectDrawSurface4>;
template SurfaceImpl<IDirectDrawSurface7>;
template HRESULT SurfaceImpl<IDirectDrawSurface>::createCompatPrimarySurface(
CompatRef<IDirectDraw> dd,
TSurfaceDesc compatDesc,
IDirectDrawSurface*& compatSurface);
template HRESULT SurfaceImpl<IDirectDrawSurface>::createCompatPrimarySurface(
CompatRef<IDirectDraw2> dd,
TSurfaceDesc compatDesc,
IDirectDrawSurface*& compatSurface);
template HRESULT SurfaceImpl<IDirectDrawSurface4>::createCompatPrimarySurface(
CompatRef<IDirectDraw4> dd,
TSurfaceDesc compatDesc,
IDirectDrawSurface4*& compatSurface);
template HRESULT SurfaceImpl<IDirectDrawSurface7>::createCompatPrimarySurface(
CompatRef<IDirectDraw7> dd,
TSurfaceDesc compatDesc,
IDirectDrawSurface7*& compatSurface);
}

View File

@ -20,9 +20,6 @@ namespace DDraw
virtual ~SurfaceImpl();
template <typename TDirectDraw>
static HRESULT createCompatPrimarySurface(
CompatRef<TDirectDraw> dd, TSurfaceDesc compatDesc, TSurface*& compatSurface);
static void fixSurfacePtrs(CompatRef<TSurface> surface);
virtual HRESULT Blt(TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
@ -43,8 +40,6 @@ namespace DDraw
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect);
private:
static void restorePrimaryCaps(TDdsCaps& caps);
static const Vtable<TSurface>& s_origVtable;
};
}

View File

@ -175,10 +175,11 @@
<ClInclude Include="DDraw\DirectDrawSurface.h" />
<ClInclude Include="DDraw\DisplayMode.h" />
<ClInclude Include="DDraw\PaletteConverter.h" />
<ClInclude Include="DDraw\CompatPrimarySurface.h" />
<ClInclude Include="DDraw\Hooks.h" />
<ClInclude Include="DDraw\Repository.h" />
<ClInclude Include="DDraw\ScopedThreadLock.h" />
<ClInclude Include="DDraw\Surfaces\PrimarySurface.h" />
<ClInclude Include="DDraw\Surfaces\PrimarySurfaceImpl.h" />
<ClInclude Include="DDraw\Surfaces\Surface.h" />
<ClInclude Include="DDraw\Surfaces\SurfaceImpl.h" />
<ClInclude Include="DDraw\Types.h" />
@ -224,11 +225,12 @@
<ClCompile Include="DDraw\DirectDrawSurface.cpp" />
<ClCompile Include="DDraw\DisplayMode.cpp" />
<ClCompile Include="DDraw\PaletteConverter.cpp" />
<ClCompile Include="DDraw\CompatPrimarySurface.cpp" />
<ClCompile Include="DDraw\Hooks.cpp" />
<ClCompile Include="DDraw\Repository.cpp" />
<ClCompile Include="DDraw\IReleaseNotifier.cpp" />
<ClCompile Include="DDraw\RealPrimarySurface.cpp" />
<ClCompile Include="DDraw\Surfaces\PrimarySurface.cpp" />
<ClCompile Include="DDraw\Surfaces\PrimarySurfaceImpl.cpp" />
<ClCompile Include="DDraw\Surfaces\Surface.cpp" />
<ClCompile Include="DDraw\Surfaces\SurfaceImpl.cpp" />
<ClCompile Include="Direct3d\DepthBuffer.cpp" />

View File

@ -105,9 +105,6 @@
<ClInclude Include="Gdi\WinProc.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
<ClInclude Include="DDraw\CompatPrimarySurface.h">
<Filter>Header Files\DDraw</Filter>
</ClInclude>
<ClInclude Include="DDraw\IReleaseNotifier.h">
<Filter>Header Files\DDraw</Filter>
</ClInclude>
@ -252,6 +249,12 @@
<ClInclude Include="DDraw\Surfaces\SurfaceImpl.h">
<Filter>Header Files\DDraw\Surfaces</Filter>
</ClInclude>
<ClInclude Include="DDraw\Surfaces\PrimarySurface.h">
<Filter>Header Files\DDraw\Surfaces</Filter>
</ClInclude>
<ClInclude Include="DDraw\Surfaces\PrimarySurfaceImpl.h">
<Filter>Header Files\DDraw\Surfaces</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Gdi\Gdi.cpp">
@ -284,9 +287,6 @@
<ClCompile Include="Gdi\WinProc.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="DDraw\CompatPrimarySurface.cpp">
<Filter>Source Files\DDraw</Filter>
</ClCompile>
<ClCompile Include="DDraw\IReleaseNotifier.cpp">
<Filter>Source Files\DDraw</Filter>
</ClCompile>
@ -377,6 +377,12 @@
<ClCompile Include="DDraw\Surfaces\SurfaceImpl.cpp">
<Filter>Source Files\DDraw\Surfaces</Filter>
</ClCompile>
<ClCompile Include="DDraw\Surfaces\PrimarySurface.cpp">
<Filter>Source Files\DDraw\Surfaces</Filter>
</ClCompile>
<ClCompile Include="DDraw\Surfaces\PrimarySurfaceImpl.cpp">
<Filter>Source Files\DDraw\Surfaces</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="Dll\DDrawCompat.def">

View File

@ -4,8 +4,8 @@
#include "Common/CompatPtr.h"
#include "Common/Log.h"
#include "Config/Config.h"
#include "DDraw/CompatPrimarySurface.h"
#include "DDraw/Repository.h"
#include "DDraw/Surfaces/PrimarySurface.h"
#include "Dll/Procs.h"
#include "Gdi/DcCache.h"
@ -55,7 +55,7 @@ namespace
CompatPtr<IDirectDrawSurface7> createGdiSurface()
{
DDSURFACEDESC2 desc = DDraw::CompatPrimarySurface::getDesc();
DDSURFACEDESC2 desc = DDraw::PrimarySurface::getDesc();
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_PITCH | DDSD_LPSURFACE;
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
desc.lPitch = g_pitch;
@ -202,15 +202,15 @@ namespace Gdi
{
PALETTEENTRY entries[256] = {};
std::memcpy(&entries[startingEntry],
&DDraw::CompatPrimarySurface::g_paletteEntries[startingEntry],
&DDraw::PrimarySurface::s_paletteEntries[startingEntry],
count * sizeof(PALETTEENTRY));
for (DWORD i = startingEntry; i < startingEntry + count; ++i)
{
if (entries[i].peFlags & PC_RESERVED)
{
entries[i] = DDraw::CompatPrimarySurface::g_paletteEntries[0];
entries[i].peFlags = DDraw::CompatPrimarySurface::g_paletteEntries[i].peFlags;
entries[i] = DDraw::PrimarySurface::s_paletteEntries[0];
entries[i].peFlags = DDraw::PrimarySurface::s_paletteEntries[i].peFlags;
}
}

View File

@ -1,9 +1,9 @@
#include <atomic>
#include "Common/ScopedCriticalSection.h"
#include "DDraw/CompatPrimarySurface.h"
#include "DDraw/PaletteConverter.h"
#include "DDraw/RealPrimarySurface.h"
#include "DDraw/Surfaces/PrimarySurface.h"
#include "Dll/Procs.h"
#include "Gdi/Caret.h"
#include "Gdi/DcCache.h"
@ -58,7 +58,7 @@ namespace
{
DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc);
auto primary(DDraw::CompatPrimarySurface::getPrimary());
auto primary(DDraw::PrimarySurface::getPrimary());
if (FAILED(primary->Lock(primary, nullptr, &desc, lockFlags | DDLOCK_WAIT, nullptr)))
{
return false;
@ -79,7 +79,7 @@ namespace
void unlockPrimarySurface()
{
GdiFlush();
auto primary(DDraw::CompatPrimarySurface::getPrimary());
auto primary(DDraw::PrimarySurface::getPrimary());
primary->Unlock(primary, nullptr);
if (DDLOCK_READONLY != g_ddLockFlags)
{
@ -239,7 +239,7 @@ namespace Gdi
void updatePalette(DWORD startingEntry, DWORD count)
{
if (isEmulationEnabled() && DDraw::CompatPrimarySurface::g_palette)
if (isEmulationEnabled() && DDraw::PrimarySurface::s_palette)
{
Gdi::DcCache::updatePalette(startingEntry, count);
}

View File

@ -1,6 +1,5 @@
#include "Common/Hook.h"
#include "Common/Log.h"
#include "DDraw/CompatPrimarySurface.h"
#include "DDraw/RealPrimarySurface.h"
#include "Gdi/Dc.h"
#include "Gdi/Gdi.h"

View File

@ -1,5 +1,5 @@
#include "Common/Hook.h"
#include "DDraw/CompatPrimarySurface.h"
#include "DDraw/Surfaces/PrimarySurface.h"
#include "Gdi/Gdi.h"
#include "Gdi/TitleBar.h"
@ -96,7 +96,7 @@ namespace Gdi
{
flags |= DC_ACTIVE;
}
if (DDraw::CompatPrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount > 8)
if (DDraw::PrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount > 8)
{
flags |= DC_GRADIENT;
}