mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Replaced IDirectDrawSurface raw pointers with smart pointers
This commit is contained in:
parent
70a29c2f12
commit
068cdb8028
@ -2,6 +2,7 @@
|
||||
#include "CompatDirectDraw.h"
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "IReleaseNotifier.h"
|
||||
|
||||
namespace
|
||||
@ -17,13 +18,13 @@ namespace
|
||||
};
|
||||
|
||||
DirectDrawInterface* g_fullScreenDirectDraw = nullptr;
|
||||
IDirectDrawSurface* g_fullScreenTagSurface = nullptr;
|
||||
CompatWeakPtr<IDirectDrawSurface> g_fullScreenTagSurface;
|
||||
|
||||
void onReleaseFullScreenTagSurface();
|
||||
|
||||
IReleaseNotifier g_fullScreenTagSurfaceReleaseNotifier(&onReleaseFullScreenTagSurface);
|
||||
|
||||
IDirectDrawSurface* createFullScreenTagSurface(IDirectDraw& dd)
|
||||
CompatPtr<IDirectDrawSurface> createFullScreenTagSurface(IDirectDraw& dd)
|
||||
{
|
||||
DDSURFACEDESC desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
@ -32,17 +33,14 @@ namespace
|
||||
desc.dwHeight = 1;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
|
||||
IDirectDrawSurface* tagSurface = nullptr;
|
||||
CompatDirectDraw<IDirectDraw>::s_origVtable.CreateSurface(&dd, &desc, &tagSurface, nullptr);
|
||||
CompatPtr<IDirectDrawSurface> tagSurface;
|
||||
CompatDirectDraw<IDirectDraw>::s_origVtable.CreateSurface(&dd, &desc, &tagSurface.getRef(), nullptr);
|
||||
if (tagSurface)
|
||||
{
|
||||
IDirectDrawSurface7* tagSurface7 = nullptr;
|
||||
CompatDirectDrawSurface<IDirectDrawSurface>::s_origVtable.QueryInterface(
|
||||
tagSurface, IID_IDirectDrawSurface7, reinterpret_cast<void**>(&tagSurface7));
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.SetPrivateData(
|
||||
CompatPtr<IDirectDrawSurface7> tagSurface7(tagSurface);
|
||||
tagSurface7->SetPrivateData(
|
||||
tagSurface7, IID_IReleaseNotifier, &g_fullScreenTagSurfaceReleaseNotifier,
|
||||
sizeof(&g_fullScreenTagSurfaceReleaseNotifier), DDSPD_IUNKNOWNPOINTER);
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.Release(tagSurface7);
|
||||
}
|
||||
|
||||
return tagSurface;
|
||||
@ -140,12 +138,8 @@ namespace
|
||||
|
||||
void setFullScreenDirectDraw(IDirectDraw& dd)
|
||||
{
|
||||
if (g_fullScreenTagSurface)
|
||||
{
|
||||
CompatDirectDrawSurface<IDirectDrawSurface>::s_origVtable.Release(g_fullScreenTagSurface);
|
||||
g_fullScreenTagSurface = nullptr;
|
||||
}
|
||||
g_fullScreenTagSurface = createFullScreenTagSurface(dd);
|
||||
g_fullScreenTagSurface.release();
|
||||
g_fullScreenTagSurface = createFullScreenTagSurface(dd).detach();
|
||||
|
||||
/*
|
||||
IDirectDraw interfaces don't conform to the COM rule about object identity:
|
||||
@ -259,7 +253,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::SetCooperativeLevel(
|
||||
}
|
||||
else if (isFullScreenDirectDraw(This) && g_fullScreenTagSurface)
|
||||
{
|
||||
CompatDirectDrawSurface<IDirectDrawSurface>::s_origVtable.Release(g_fullScreenTagSurface);
|
||||
g_fullScreenTagSurface.release();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatGdi.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "DDrawRepository.h"
|
||||
#include "IReleaseNotifier.h"
|
||||
@ -12,11 +13,12 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
bool mirrorBlt(IDirectDrawSurface7& dst, IDirectDrawSurface7& src, RECT srcRect, DWORD mirrorFx);
|
||||
bool mirrorBlt(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src,
|
||||
RECT srcRect, DWORD mirrorFx);
|
||||
|
||||
bool g_lockingPrimary = false;
|
||||
|
||||
void fixSurfacePtr(IDirectDrawSurface7& surface, const DDSURFACEDESC2& desc)
|
||||
void fixSurfacePtr(CompatRef<IDirectDrawSurface7> surface, const DDSURFACEDESC2& desc)
|
||||
{
|
||||
if ((desc.dwFlags & DDSD_CAPS) && (desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) ||
|
||||
0 == desc.dwWidth || 0 == desc.dwHeight)
|
||||
@ -34,48 +36,44 @@ namespace
|
||||
}
|
||||
|
||||
RECT r = { 0, 0, 1, 1 };
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.Blt(
|
||||
&surface, &r, tempSurface.surface, &r, DDBLT_WAIT, nullptr);
|
||||
surface->Blt(&surface, &r, tempSurface.surface, &r, DDBLT_WAIT, nullptr);
|
||||
}
|
||||
|
||||
HRESULT WINAPI enumSurfacesCallback(
|
||||
HRESULT WINAPI fixSurfacePtrEnumCallback(
|
||||
LPDIRECTDRAWSURFACE7 lpDDSurface,
|
||||
LPDDSURFACEDESC2 lpDDSurfaceDesc,
|
||||
LPVOID lpContext)
|
||||
{
|
||||
auto& visitedSurfaces = *static_cast<std::set<IDirectDrawSurface7*>*>(lpContext);
|
||||
|
||||
if (visitedSurfaces.find(lpDDSurface) == visitedSurfaces.end())
|
||||
CompatPtr<IDirectDrawSurface7> surface(lpDDSurface);
|
||||
if (visitedSurfaces.find(surface) == visitedSurfaces.end())
|
||||
{
|
||||
visitedSurfaces.insert(lpDDSurface);
|
||||
fixSurfacePtr(*lpDDSurface, *lpDDSurfaceDesc);
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.EnumAttachedSurfaces(
|
||||
lpDDSurface, lpContext, &enumSurfacesCallback);
|
||||
visitedSurfaces.insert(surface);
|
||||
fixSurfacePtr(*surface, *lpDDSurfaceDesc);
|
||||
surface->EnumAttachedSurfaces(surface, lpContext, &fixSurfacePtrEnumCallback);
|
||||
}
|
||||
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.Release(lpDDSurface);
|
||||
return DDENUMRET_OK;
|
||||
}
|
||||
|
||||
void fixSurfacePtrs(IDirectDrawSurface7& surface)
|
||||
void fixSurfacePtrs(CompatRef<IDirectDrawSurface7> surface)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.GetSurfaceDesc(&surface, &desc);
|
||||
|
||||
surface->GetSurfaceDesc(&surface, &desc);
|
||||
|
||||
fixSurfacePtr(surface, desc);
|
||||
std::set<IDirectDrawSurface7*> visitedSurfaces{ &surface };
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.EnumAttachedSurfaces(
|
||||
&surface, &visitedSurfaces, &enumSurfacesCallback);
|
||||
surface->EnumAttachedSurfaces(&surface, &visitedSurfaces, &fixSurfacePtrEnumCallback);
|
||||
}
|
||||
|
||||
IDirectDrawSurface7* getMirroredSurface(IDirectDrawSurface7& surface, RECT* srcRect, DWORD mirrorFx)
|
||||
CompatWeakPtr<IDirectDrawSurface7> getMirroredSurface(
|
||||
CompatRef<IDirectDrawSurface7> surface, RECT* srcRect, DWORD mirrorFx)
|
||||
{
|
||||
auto& origVtable = CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable;
|
||||
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
HRESULT result = origVtable.GetSurfaceDesc(&surface, &desc);
|
||||
HRESULT result = surface->GetSurfaceDesc(&surface, &desc);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to get surface description for mirroring: " << result);
|
||||
@ -112,34 +110,11 @@ namespace
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
origVtable.AddRef(mirroredSurface.surface);
|
||||
return mirroredSurface.surface;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
TSurface* getMirroredSurface(TSurface& surface, RECT* rect, DWORD mirrorFx)
|
||||
{
|
||||
auto& origVtable = CompatDirectDrawSurface<TSurface>::s_origVtable;
|
||||
|
||||
IDirectDrawSurface7* surface7 = nullptr;
|
||||
origVtable.QueryInterface(&surface, IID_IDirectDrawSurface7, reinterpret_cast<void**>(&surface7));
|
||||
IDirectDrawSurface7* mirroredSurface7 = getMirroredSurface(*surface7, rect, mirrorFx);
|
||||
surface7->lpVtbl->Release(surface7);
|
||||
|
||||
if (!mirroredSurface7)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto& origVtable7 = CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable;
|
||||
TSurface* mirroredSurface = nullptr;
|
||||
origVtable7.QueryInterface(mirroredSurface7,
|
||||
CompatDirectDrawSurface<TSurface>::s_iid, reinterpret_cast<void**>(&mirroredSurface));
|
||||
origVtable7.Release(mirroredSurface7);
|
||||
return mirroredSurface;
|
||||
}
|
||||
|
||||
bool mirrorBlt(IDirectDrawSurface7& dst, IDirectDrawSurface7& src, RECT srcRect, DWORD mirrorFx)
|
||||
bool mirrorBlt(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src,
|
||||
RECT srcRect, DWORD mirrorFx)
|
||||
{
|
||||
if (DDBLTFX_MIRRORLEFTRIGHT == mirrorFx)
|
||||
{
|
||||
@ -147,8 +122,7 @@ namespace
|
||||
srcRect.left = srcRect.right - 1;
|
||||
for (LONG x = 0; x < width; ++x)
|
||||
{
|
||||
HRESULT result = CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.BltFast(
|
||||
&dst, x, 0, &src, &srcRect, DDBLTFAST_WAIT);
|
||||
HRESULT result = dst->BltFast(&dst, x, 0, &src, &srcRect, DDBLTFAST_WAIT);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed BltFast for mirroring: " << result);
|
||||
@ -164,8 +138,7 @@ namespace
|
||||
srcRect.top = srcRect.bottom - 1;
|
||||
for (LONG y = 0; y < height; ++y)
|
||||
{
|
||||
HRESULT result = CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.BltFast(
|
||||
&dst, 0, y, &src, &srcRect, DDBLTFAST_WAIT);
|
||||
HRESULT result = dst->BltFast(&dst, 0, y, &src, &srcRect, DDBLTFAST_WAIT);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed BltFast for mirroring: " << result);
|
||||
@ -243,12 +216,10 @@ HRESULT CompatDirectDrawSurface<TSurface>::createCompatPrimarySurface(
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
void CompatDirectDrawSurface<TSurface>::fixSurfacePtrs(TSurface& surface)
|
||||
void CompatDirectDrawSurface<TSurface>::fixSurfacePtrs(CompatRef<TSurface> surface)
|
||||
{
|
||||
IDirectDrawSurface7* surface7 = nullptr;
|
||||
surface.lpVtbl->QueryInterface(&surface, IID_IDirectDrawSurface7, reinterpret_cast<LPVOID*>(&surface7));
|
||||
CompatPtr<IDirectDrawSurface7> surface7(Compat::queryInterface<IDirectDrawSurface7>(&surface));
|
||||
::fixSurfacePtrs(*surface7);
|
||||
surface7->lpVtbl->Release(surface7);
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
@ -268,12 +239,15 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Blt(
|
||||
}
|
||||
|
||||
HRESULT result = DD_OK;
|
||||
TSurface* mirroredSrcSurface = nullptr;
|
||||
CompatPtr<TSurface> mirroredSrcSurface;
|
||||
|
||||
if (lpDDSrcSurface && (dwFlags & DDBLT_DDFX) && lpDDBltFx &&
|
||||
(lpDDBltFx->dwDDFX & (DDBLTFX_MIRRORLEFTRIGHT | DDBLTFX_MIRRORUPDOWN)))
|
||||
{
|
||||
mirroredSrcSurface = getMirroredSurface(*lpDDSrcSurface, lpSrcRect, lpDDBltFx->dwDDFX);
|
||||
CompatPtr<IDirectDrawSurface7> srcSurface(
|
||||
Compat::queryInterface<IDirectDrawSurface7>(lpDDSrcSurface));
|
||||
mirroredSrcSurface.reset(Compat::queryInterface<TSurface>(
|
||||
getMirroredSurface(*srcSurface, lpSrcRect, lpDDBltFx->dwDDFX).get()));
|
||||
if (!mirroredSrcSurface)
|
||||
{
|
||||
LOG_ONCE("Failed to emulate a mirrored Blt");
|
||||
@ -305,8 +279,6 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Blt(
|
||||
{
|
||||
result = s_origVtable.Blt(This, lpDestRect, mirroredSrcSurface, nullptr, flags, &fx);
|
||||
}
|
||||
|
||||
s_origVtable.Release(mirroredSrcSurface);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -461,8 +433,8 @@ HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::QueryInterface(
|
||||
{
|
||||
if (riid == IID_IDirectDrawGammaControl && CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
return RealPrimarySurface::getSurface()->lpVtbl->QueryInterface(
|
||||
RealPrimarySurface::getSurface(), riid, obp);
|
||||
auto realPrimary(RealPrimarySurface::getSurface());
|
||||
return realPrimary->QueryInterface(realPrimary, riid, obp);
|
||||
}
|
||||
return s_origVtable.QueryInterface(This, riid, obp);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "CompatRef.h"
|
||||
#include "CompatVtable.h"
|
||||
#include "DDrawTypes.h"
|
||||
#include "DirectDrawSurfaceVtblVisitor.h"
|
||||
@ -22,7 +23,7 @@ public:
|
||||
TSurfaceDesc compatDesc,
|
||||
TSurface*& compatSurface);
|
||||
|
||||
static void fixSurfacePtrs(TSurface& surface);
|
||||
static void fixSurfacePtrs(CompatRef<TSurface> surface);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Blt(
|
||||
TSurface* This,
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <atomic>
|
||||
|
||||
#include "CompatDirectDrawPalette.h"
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatGdi.h"
|
||||
#include "CompatGdiCaret.h"
|
||||
#include "CompatGdiDcCache.h"
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
#include "CompatDirectDraw.h"
|
||||
#include "CompatDirectDrawPalette.h"
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatGdiDcCache.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "Config.h"
|
||||
#include "DDrawLog.h"
|
||||
#include "DDrawProcs.h"
|
||||
@ -27,37 +27,36 @@ namespace
|
||||
void* g_surfaceMemory = nullptr;
|
||||
LONG g_pitch = 0;
|
||||
|
||||
IDirectDrawSurface7* createGdiSurface();
|
||||
CompatPtr<IDirectDrawSurface7> createGdiSurface();
|
||||
|
||||
CachedDc createCachedDc()
|
||||
{
|
||||
CachedDc cachedDc = {};
|
||||
|
||||
IDirectDrawSurface7* surface = createGdiSurface();
|
||||
CompatPtr<IDirectDrawSurface7> surface(createGdiSurface());
|
||||
if (!surface)
|
||||
{
|
||||
return cachedDc;
|
||||
}
|
||||
|
||||
HDC dc = nullptr;
|
||||
HRESULT result = surface->lpVtbl->GetDC(surface, &dc);
|
||||
HRESULT result = surface->GetDC(surface, &dc);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to create a GDI DC: " << result);
|
||||
surface->lpVtbl->Release(surface);
|
||||
return cachedDc;
|
||||
}
|
||||
|
||||
// Release DD critical section acquired by IDirectDrawSurface7::GetDC to avoid deadlocks
|
||||
Compat::origProcs.ReleaseDDThreadLock();
|
||||
|
||||
cachedDc.surface = surface;
|
||||
cachedDc.surface = surface.detach();
|
||||
cachedDc.dc = dc;
|
||||
cachedDc.cacheId = g_cacheId;
|
||||
return cachedDc;
|
||||
}
|
||||
|
||||
IDirectDrawSurface7* createGdiSurface()
|
||||
CompatPtr<IDirectDrawSurface7> createGdiSurface()
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
@ -69,9 +68,9 @@ namespace
|
||||
desc.lPitch = g_pitch;
|
||||
desc.lpSurface = g_surfaceMemory;
|
||||
|
||||
IDirectDrawSurface7* surface = nullptr;
|
||||
CompatPtr<IDirectDrawSurface7> surface;
|
||||
HRESULT result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface(
|
||||
g_directDraw, &desc, &surface, nullptr);
|
||||
g_directDraw, &desc, &surface.getRef(), nullptr);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to create a GDI surface: " << result);
|
||||
@ -80,7 +79,7 @@ namespace
|
||||
|
||||
if (CompatPrimarySurface::pixelFormat.dwRGBBitCount <= 8)
|
||||
{
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.SetPalette(surface, g_palette);
|
||||
surface->SetPalette(surface, g_palette);
|
||||
}
|
||||
|
||||
return surface;
|
||||
@ -115,14 +114,13 @@ namespace
|
||||
// Reacquire DD critical section that was temporarily released after IDirectDrawSurface7::GetDC
|
||||
Compat::origProcs.AcquireDDThreadLock();
|
||||
|
||||
HRESULT result = CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.ReleaseDC(
|
||||
cachedDc.surface, cachedDc.dc);
|
||||
HRESULT result = cachedDc.surface->ReleaseDC(cachedDc.surface, cachedDc.dc);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to release a cached DC: " << result);
|
||||
}
|
||||
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.Release(cachedDc.surface);
|
||||
cachedDc.surface.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,11 +6,13 @@
|
||||
#include <ddraw.h>
|
||||
#include <Windows.h>
|
||||
|
||||
#include "CompatWeakPtr.h"
|
||||
|
||||
namespace CompatGdiDcCache
|
||||
{
|
||||
struct CachedDc
|
||||
{
|
||||
IDirectDrawSurface7* surface;
|
||||
CompatWeakPtr<IDirectDrawSurface7> surface;
|
||||
HDC dc;
|
||||
DWORD cacheId;
|
||||
};
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
#include "CompatDirectDraw.h"
|
||||
#include "CompatDirectDrawPalette.h"
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatPaletteConverter.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "DDrawRepository.h"
|
||||
#include "DDrawTypes.h"
|
||||
#include "Hook.h"
|
||||
@ -16,7 +16,7 @@ namespace
|
||||
{
|
||||
HDC g_dc = nullptr;
|
||||
HGDIOBJ g_oldBitmap = nullptr;
|
||||
IDirectDrawSurface7* g_surface = nullptr;
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_surface;
|
||||
|
||||
void convertPaletteEntriesToRgbQuad(RGBQUAD* entries, DWORD count)
|
||||
{
|
||||
@ -27,7 +27,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
HBITMAP createDibSection(void*& bits)
|
||||
HBITMAP createDibSection(const DDSURFACEDESC2& primaryDesc, void*& bits)
|
||||
{
|
||||
struct PalettizedBitmapInfo
|
||||
{
|
||||
@ -37,8 +37,8 @@ namespace
|
||||
|
||||
PalettizedBitmapInfo bmi = {};
|
||||
bmi.header.biSize = sizeof(bmi.header);
|
||||
bmi.header.biWidth = RealPrimarySurface::s_surfaceDesc.dwWidth;
|
||||
bmi.header.biHeight = -static_cast<LONG>(RealPrimarySurface::s_surfaceDesc.dwHeight);
|
||||
bmi.header.biWidth = primaryDesc.dwWidth;
|
||||
bmi.header.biHeight = -static_cast<LONG>(primaryDesc.dwHeight);
|
||||
bmi.header.biPlanes = 1;
|
||||
bmi.header.biBitCount = 8;
|
||||
bmi.header.biCompression = BI_RGB;
|
||||
@ -48,7 +48,7 @@ namespace
|
||||
DIB_RGB_COLORS, &bits, nullptr, 0);
|
||||
}
|
||||
|
||||
IDirectDrawSurface7* createSurface(void* bits)
|
||||
CompatPtr<IDirectDrawSurface7> createSurface(const DDSURFACEDESC2& primaryDesc, void* bits)
|
||||
{
|
||||
IDirectDraw7* dd = DDrawRepository::getDirectDraw();
|
||||
if (!dd)
|
||||
@ -60,38 +60,38 @@ namespace
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS |
|
||||
DDSD_PITCH | DDSD_LPSURFACE;
|
||||
desc.dwWidth = RealPrimarySurface::s_surfaceDesc.dwWidth;
|
||||
desc.dwHeight = RealPrimarySurface::s_surfaceDesc.dwHeight;
|
||||
desc.dwWidth = primaryDesc.dwWidth;
|
||||
desc.dwHeight = primaryDesc.dwHeight;
|
||||
desc.ddpfPixelFormat = CompatPrimarySurface::displayMode.pixelFormat;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
desc.lPitch = (RealPrimarySurface::s_surfaceDesc.dwWidth + 3) & ~3;
|
||||
desc.lPitch = (primaryDesc.dwWidth + 3) & ~3;
|
||||
desc.lpSurface = bits;
|
||||
|
||||
IDirectDrawSurface7* surface = nullptr;
|
||||
CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface(dd, &desc, &surface, nullptr);
|
||||
CompatPtr<IDirectDrawSurface7> surface;
|
||||
CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface(dd, &desc, &surface.getRef(), nullptr);
|
||||
return surface;
|
||||
}
|
||||
}
|
||||
|
||||
namespace CompatPaletteConverter
|
||||
{
|
||||
bool create()
|
||||
bool create(const DDSURFACEDESC2& primaryDesc)
|
||||
{
|
||||
if (CompatPrimarySurface::displayMode.pixelFormat.dwRGBBitCount > 8 &&
|
||||
RealPrimarySurface::s_surfaceDesc.ddpfPixelFormat.dwRGBBitCount > 8)
|
||||
primaryDesc.ddpfPixelFormat.dwRGBBitCount > 8)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void* bits = nullptr;
|
||||
HBITMAP dib = createDibSection(bits);
|
||||
HBITMAP dib = createDibSection(primaryDesc, bits);
|
||||
if (!dib)
|
||||
{
|
||||
Compat::Log() << "Failed to create the palette converter DIB section";
|
||||
return false;
|
||||
}
|
||||
|
||||
IDirectDrawSurface7* surface = createSurface(bits);
|
||||
CompatPtr<IDirectDrawSurface7> surface(createSurface(primaryDesc, bits));
|
||||
if (!surface)
|
||||
{
|
||||
Compat::Log() << "Failed to create the palette converter surface";
|
||||
@ -103,14 +103,13 @@ namespace CompatPaletteConverter
|
||||
if (!dc)
|
||||
{
|
||||
Compat::Log() << "Failed to create the palette converter DC";
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.Release(surface);
|
||||
DeleteObject(dib);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_oldBitmap = SelectObject(dc, dib);
|
||||
g_dc = dc;
|
||||
g_surface = surface;
|
||||
g_surface = surface.detach();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -119,7 +118,7 @@ namespace CompatPaletteConverter
|
||||
return g_dc;
|
||||
}
|
||||
|
||||
IDirectDrawSurface7* getSurface()
|
||||
CompatWeakPtr<IDirectDrawSurface7> getSurface()
|
||||
{
|
||||
return g_surface;
|
||||
}
|
||||
@ -131,8 +130,7 @@ namespace CompatPaletteConverter
|
||||
return;
|
||||
}
|
||||
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.Release(g_surface);
|
||||
g_surface = nullptr;
|
||||
g_surface.release();
|
||||
|
||||
DeleteObject(SelectObject(g_dc, g_oldBitmap));
|
||||
DeleteDC(g_dc);
|
||||
@ -143,8 +141,7 @@ namespace CompatPaletteConverter
|
||||
{
|
||||
if (g_surface)
|
||||
{
|
||||
HRESULT result = CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.SetClipper(
|
||||
g_surface, clipper);
|
||||
HRESULT result = g_surface->SetClipper(g_surface, clipper);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to set a clipper on the palette converter surface: " << result);
|
||||
|
@ -4,11 +4,13 @@
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatWeakPtr.h"
|
||||
|
||||
namespace CompatPaletteConverter
|
||||
{
|
||||
bool create();
|
||||
bool create(const DDSURFACEDESC2& primaryDesc);
|
||||
HDC getDc();
|
||||
IDirectDrawSurface7* getSurface();
|
||||
CompatWeakPtr<IDirectDrawSurface7> getSurface();
|
||||
void release();
|
||||
void setClipper(IDirectDrawClipper* clipper);
|
||||
void updatePalette(DWORD startingEntry, DWORD count);
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "CompatDirectDraw.h"
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "DDrawLog.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "DDrawRepository.h"
|
||||
@ -63,7 +63,7 @@ namespace
|
||||
surface.desc.ddsCaps.dwCaps = caps;
|
||||
|
||||
CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface(
|
||||
dd, &surface.desc, &surface.surface, nullptr);
|
||||
dd, &surface.desc, &surface.surface.getRef(), nullptr);
|
||||
return surface;
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ namespace
|
||||
if (it->desc.dwWidth <= width && it->desc.dwHeight <= height &&
|
||||
0 == memcmp(&it->desc.ddpfPixelFormat, &pf, sizeof(pf)))
|
||||
{
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.Release(it->surface);
|
||||
it->surface.release();
|
||||
it = cachedSurfaces.erase(it);
|
||||
}
|
||||
else
|
||||
@ -89,17 +89,16 @@ namespace
|
||||
std::vector<Surface>::iterator findSurface(DWORD width, DWORD height, const DDPIXELFORMAT& pf,
|
||||
std::vector<Surface>& cachedSurfaces)
|
||||
{
|
||||
auto& origVtable = CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable;
|
||||
|
||||
auto it = cachedSurfaces.begin();
|
||||
while (it != cachedSurfaces.end())
|
||||
{
|
||||
if (it->desc.dwWidth >= width && it->desc.dwHeight >= height &&
|
||||
0 == memcmp(&it->desc.ddpfPixelFormat, &pf, sizeof(pf)))
|
||||
{
|
||||
if (FAILED(origVtable.IsLost(it->surface)) && FAILED(origVtable.Restore(it->surface)))
|
||||
if (FAILED(it->surface->IsLost(it->surface)) &&
|
||||
FAILED(it->surface->Restore(it->surface)))
|
||||
{
|
||||
origVtable.Release(it->surface);
|
||||
it->surface.release();
|
||||
it = cachedSurfaces.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
@ -4,12 +4,14 @@
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatWeakPtr.h"
|
||||
|
||||
namespace DDrawRepository
|
||||
{
|
||||
struct Surface
|
||||
{
|
||||
DDSURFACEDESC2 desc;
|
||||
IDirectDrawSurface7* surface;
|
||||
CompatWeakPtr<IDirectDrawSurface7> surface;
|
||||
};
|
||||
|
||||
class ScopedSurface : public Surface
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "CompatDirectDrawPalette.h"
|
||||
#include "CompatGdi.h"
|
||||
#include "CompatRegistry.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "CompatVtable.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "DDrawRepository.h"
|
||||
@ -35,6 +36,12 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CompatInterface>
|
||||
void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf)
|
||||
{
|
||||
CompatInterface::hookVtable(*intf);
|
||||
}
|
||||
|
||||
void hookDirectDraw(IDirectDraw7& dd)
|
||||
{
|
||||
IUnknown& ddUnk = reinterpret_cast<IUnknown&>(dd);
|
||||
@ -53,17 +60,17 @@ namespace
|
||||
desc.dwHeight = 1;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
|
||||
|
||||
IDirectDrawSurface7* surface = nullptr;
|
||||
HRESULT result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface(&dd, &desc, &surface, nullptr);
|
||||
CompatPtr<IDirectDrawSurface7> surface;
|
||||
HRESULT result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface(
|
||||
&dd, &desc, &surface.getRef(), nullptr);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
IUnknown& surfaceUnk = reinterpret_cast<IUnknown&>(*surface);
|
||||
hookVtable<CompatDirectDrawSurface<IDirectDrawSurface>>(IID_IDirectDrawSurface, surfaceUnk);
|
||||
hookVtable<CompatDirectDrawSurface<IDirectDrawSurface2>>(IID_IDirectDrawSurface2, surfaceUnk);
|
||||
hookVtable<CompatDirectDrawSurface<IDirectDrawSurface3>>(IID_IDirectDrawSurface3, surfaceUnk);
|
||||
hookVtable<CompatDirectDrawSurface<IDirectDrawSurface4>>(IID_IDirectDrawSurface4, surfaceUnk);
|
||||
hookVtable<CompatDirectDrawSurface<IDirectDrawSurface7>>(IID_IDirectDrawSurface7, surfaceUnk);
|
||||
surface->lpVtbl->Release(surface);
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable = *surface.get()->lpVtbl;
|
||||
hookVtable<CompatDirectDrawSurface<IDirectDrawSurface>>(surface);
|
||||
hookVtable<CompatDirectDrawSurface<IDirectDrawSurface2>>(surface);
|
||||
hookVtable<CompatDirectDrawSurface<IDirectDrawSurface3>>(surface);
|
||||
hookVtable<CompatDirectDrawSurface<IDirectDrawSurface4>>(surface);
|
||||
hookVtable<CompatDirectDrawSurface<IDirectDrawSurface7>>(surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "CompatGdi.h"
|
||||
#include "CompatPaletteConverter.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "CompatRef.h"
|
||||
#include "Config.h"
|
||||
#include "DDrawScopedThreadLock.h"
|
||||
#include "DDrawProcs.h"
|
||||
@ -19,9 +21,11 @@ namespace
|
||||
{
|
||||
void onRelease();
|
||||
void updateNow(long long qpcNow);
|
||||
DWORD WINAPI updateThreadProc(LPVOID lpParameter);
|
||||
|
||||
IDirectDrawSurface7* g_frontBuffer = nullptr;
|
||||
IDirectDrawSurface7* g_backBuffer = nullptr;
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_frontBuffer;
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_backBuffer;
|
||||
DDSURFACEDESC2 g_surfaceDesc = {};
|
||||
IReleaseNotifier g_releaseNotifier(onRelease);
|
||||
|
||||
bool g_stopUpdateThread = false;
|
||||
@ -34,7 +38,7 @@ namespace
|
||||
|
||||
std::atomic<bool> g_isFullScreen(false);
|
||||
|
||||
bool compatBlt(IDirectDrawSurface7* dest)
|
||||
bool compatBlt(CompatRef<IDirectDrawSurface7> dest)
|
||||
{
|
||||
Compat::LogEnter("RealPrimarySurface::compatBlt", dest);
|
||||
|
||||
@ -44,12 +48,11 @@ namespace
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
const auto& origVtable = CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable;
|
||||
|
||||
if (!RealPrimarySurface::isFullScreen())
|
||||
{
|
||||
IDirectDrawClipper* clipper = nullptr;
|
||||
if (FAILED(origVtable.GetClipper(g_frontBuffer, &clipper)))
|
||||
if (FAILED(g_frontBuffer->GetClipper(g_frontBuffer, &clipper)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -59,27 +62,27 @@ namespace
|
||||
auto primary(CompatPrimarySurface::getPrimary());
|
||||
if (CompatPrimarySurface::pixelFormat.dwRGBBitCount <= 8)
|
||||
{
|
||||
origVtable.Blt(CompatPaletteConverter::getSurface(), &g_updateRect,
|
||||
auto paletteConverter(CompatPaletteConverter::getSurface());
|
||||
paletteConverter->Blt(paletteConverter, &g_updateRect,
|
||||
primary, &g_updateRect, DDBLT_WAIT, nullptr);
|
||||
|
||||
HDC destDc = nullptr;
|
||||
origVtable.GetDC(dest, &destDc);
|
||||
dest->GetDC(&dest, &destDc);
|
||||
result = TRUE == CALL_ORIG_FUNC(BitBlt)(destDc, g_updateRect.left, g_updateRect.top,
|
||||
g_updateRect.right - g_updateRect.left, g_updateRect.bottom - g_updateRect.top,
|
||||
CompatPaletteConverter::getDc(), g_updateRect.left, g_updateRect.top, SRCCOPY);
|
||||
origVtable.ReleaseDC(dest, destDc);
|
||||
dest->ReleaseDC(&dest, destDc);
|
||||
|
||||
if (dest == g_frontBuffer)
|
||||
if (&dest == g_frontBuffer)
|
||||
{
|
||||
// Force the screen to be updated. It won't refresh from BitBlt alone.
|
||||
RECT r = { 0, 0, 1, 1 };
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.BltFast(
|
||||
g_frontBuffer, 0, 0, g_frontBuffer, &r, DDBLTFAST_WAIT);
|
||||
g_frontBuffer->BltFast(g_frontBuffer, 0, 0, g_frontBuffer, &r, DDBLTFAST_WAIT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = SUCCEEDED(origVtable.Blt(dest, &g_updateRect,
|
||||
result = SUCCEEDED(dest->Blt(&dest, &g_updateRect,
|
||||
primary, &g_updateRect, DDBLT_WAIT, nullptr));
|
||||
}
|
||||
|
||||
@ -99,6 +102,53 @@ namespace
|
||||
return qpcNextUpdate + g_qpcMinUpdateInterval * (missedIntervals + 1);
|
||||
}
|
||||
|
||||
HRESULT init(CompatPtr<IDirectDrawSurface7> surface)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
surface->GetSurfaceDesc(surface, &desc);
|
||||
|
||||
if (!CompatPaletteConverter::create(desc))
|
||||
{
|
||||
return DDERR_GENERIC;
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> backBuffer;
|
||||
const bool isFlippable = 0 != (desc.ddsCaps.dwCaps & DDSCAPS_FLIP);
|
||||
if (isFlippable)
|
||||
{
|
||||
DDSCAPS2 backBufferCaps = {};
|
||||
backBufferCaps.dwCaps = DDSCAPS_BACKBUFFER;
|
||||
surface->GetAttachedSurface(surface, &backBufferCaps, &backBuffer.getRef());
|
||||
}
|
||||
|
||||
g_qpcMinUpdateInterval = Time::g_qpcFrequency / Config::maxPrimaryUpdateRate;
|
||||
g_qpcNextUpdate = Time::queryPerformanceCounter();
|
||||
|
||||
if (!g_updateEvent)
|
||||
{
|
||||
g_updateEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||||
}
|
||||
|
||||
if (!g_updateThread)
|
||||
{
|
||||
g_updateThread = CreateThread(nullptr, 0, &updateThreadProc, nullptr, 0, nullptr);
|
||||
SetThreadPriority(g_updateThread, THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
}
|
||||
|
||||
surface->SetPrivateData(surface, IID_IReleaseNotifier,
|
||||
&g_releaseNotifier, sizeof(&g_releaseNotifier), DDSPD_IUNKNOWNPOINTER);
|
||||
|
||||
timeBeginPeriod(1);
|
||||
|
||||
g_frontBuffer = surface.detach();
|
||||
g_backBuffer = backBuffer.detach();
|
||||
g_surfaceDesc = desc;
|
||||
g_isFullScreen = isFlippable;
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
bool isNextUpdateSignaledAndReady(long long qpcNow)
|
||||
{
|
||||
return Time::qpcToMs(qpcNow - g_qpcNextUpdate) >= 0 &&
|
||||
@ -112,15 +162,11 @@ namespace
|
||||
ResetEvent(g_updateEvent);
|
||||
timeEndPeriod(1);
|
||||
g_frontBuffer = nullptr;
|
||||
if (g_backBuffer)
|
||||
{
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.Release(g_backBuffer);
|
||||
g_backBuffer = nullptr;
|
||||
}
|
||||
g_backBuffer.release();
|
||||
g_isFullScreen = false;
|
||||
CompatPaletteConverter::release();
|
||||
|
||||
ZeroMemory(&RealPrimarySurface::s_surfaceDesc, sizeof(RealPrimarySurface::s_surfaceDesc));
|
||||
ZeroMemory(&g_surfaceDesc, sizeof(g_surfaceDesc));
|
||||
|
||||
Compat::LogLeave("RealPrimarySurface::onRelease");
|
||||
}
|
||||
@ -129,7 +175,7 @@ namespace
|
||||
{
|
||||
ResetEvent(g_updateEvent);
|
||||
|
||||
if (compatBlt(g_frontBuffer))
|
||||
if (compatBlt(*g_frontBuffer))
|
||||
{
|
||||
long long qpcNextUpdate = getNextUpdateQpc(qpcNow);
|
||||
if (Time::qpcToMs(qpcNow - qpcNextUpdate) >= 0)
|
||||
@ -170,8 +216,6 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
DDSURFACEDESC2 RealPrimarySurface::s_surfaceDesc = {};
|
||||
|
||||
template <typename DirectDraw>
|
||||
HRESULT RealPrimarySurface::create(DirectDraw& dd)
|
||||
{
|
||||
@ -181,9 +225,9 @@ HRESULT RealPrimarySurface::create(DirectDraw& dd)
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
|
||||
desc.dwBackBufferCount = 1;
|
||||
|
||||
typename Types<DirectDraw>::TCreatedSurface* surface = nullptr;
|
||||
CompatPtr<typename Types<DirectDraw>::TCreatedSurface> surface;
|
||||
HRESULT result = CompatDirectDraw<DirectDraw>::s_origVtable.CreateSurface(
|
||||
&dd, &desc, &surface, nullptr);
|
||||
&dd, &desc, &surface.getRef(), nullptr);
|
||||
|
||||
bool isFlippable = true;
|
||||
if (DDERR_NOEXCLUSIVEMODE == result)
|
||||
@ -193,7 +237,7 @@ HRESULT RealPrimarySurface::create(DirectDraw& dd)
|
||||
desc.dwBackBufferCount = 0;
|
||||
isFlippable = false;
|
||||
result = CompatDirectDraw<DirectDraw>::s_origVtable.CreateSurface(
|
||||
&dd, &desc, &surface, nullptr);
|
||||
&dd, &desc, &surface.getRef(), nullptr);
|
||||
}
|
||||
|
||||
if (FAILED(result))
|
||||
@ -202,48 +246,7 @@ HRESULT RealPrimarySurface::create(DirectDraw& dd)
|
||||
return result;
|
||||
}
|
||||
|
||||
surface->lpVtbl->QueryInterface(
|
||||
surface, IID_IDirectDrawSurface7, reinterpret_cast<LPVOID*>(&g_frontBuffer));
|
||||
surface->lpVtbl->Release(surface);
|
||||
|
||||
s_surfaceDesc.dwSize = sizeof(s_surfaceDesc);
|
||||
g_frontBuffer->lpVtbl->GetSurfaceDesc(g_frontBuffer, &s_surfaceDesc);
|
||||
|
||||
if (!CompatPaletteConverter::create())
|
||||
{
|
||||
g_frontBuffer->lpVtbl->Release(g_frontBuffer);
|
||||
g_frontBuffer = nullptr;
|
||||
return DDERR_GENERIC;
|
||||
}
|
||||
|
||||
if (isFlippable)
|
||||
{
|
||||
DDSCAPS2 backBufferCaps = {};
|
||||
backBufferCaps.dwCaps = DDSCAPS_BACKBUFFER;
|
||||
g_frontBuffer->lpVtbl->GetAttachedSurface(g_frontBuffer, &backBufferCaps, &g_backBuffer);
|
||||
}
|
||||
|
||||
g_qpcMinUpdateInterval = Time::g_qpcFrequency / Config::maxPrimaryUpdateRate;
|
||||
g_qpcNextUpdate = Time::queryPerformanceCounter();
|
||||
|
||||
if (!g_updateEvent)
|
||||
{
|
||||
g_updateEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||||
}
|
||||
|
||||
if (!g_updateThread)
|
||||
{
|
||||
g_updateThread = CreateThread(nullptr, 0, &updateThreadProc, nullptr, 0, nullptr);
|
||||
SetThreadPriority(g_updateThread, THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
}
|
||||
|
||||
g_frontBuffer->lpVtbl->SetPrivateData(g_frontBuffer,
|
||||
IID_IReleaseNotifier, &g_releaseNotifier, sizeof(&g_releaseNotifier), DDSPD_IUNKNOWNPOINTER);
|
||||
|
||||
g_isFullScreen = isFlippable;
|
||||
timeBeginPeriod(1);
|
||||
|
||||
return DD_OK;
|
||||
return init(surface);
|
||||
}
|
||||
|
||||
template HRESULT RealPrimarySurface::create(IDirectDraw&);
|
||||
@ -267,7 +270,7 @@ void RealPrimarySurface::enableUpdates()
|
||||
|
||||
HRESULT RealPrimarySurface::flip(DWORD flags)
|
||||
{
|
||||
if (!g_backBuffer)
|
||||
if (!g_isFullScreen)
|
||||
{
|
||||
return DDERR_NOTFLIPPABLE;
|
||||
}
|
||||
@ -275,13 +278,13 @@ HRESULT RealPrimarySurface::flip(DWORD flags)
|
||||
ResetEvent(g_updateEvent);
|
||||
|
||||
invalidate(nullptr);
|
||||
compatBlt(g_backBuffer);
|
||||
compatBlt(*g_backBuffer);
|
||||
if (flags & DDFLIP_DONOTWAIT)
|
||||
{
|
||||
flags ^= DDFLIP_DONOTWAIT;
|
||||
}
|
||||
|
||||
HRESULT result = g_frontBuffer->lpVtbl->Flip(g_frontBuffer, nullptr, flags | DDFLIP_WAIT);
|
||||
HRESULT result = g_frontBuffer->Flip(g_frontBuffer, nullptr, flags | DDFLIP_WAIT);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
g_qpcNextUpdate = getNextUpdateQpc(
|
||||
@ -291,7 +294,7 @@ HRESULT RealPrimarySurface::flip(DWORD flags)
|
||||
return result;
|
||||
}
|
||||
|
||||
IDirectDrawSurface7* RealPrimarySurface::getSurface()
|
||||
CompatWeakPtr<IDirectDrawSurface7> RealPrimarySurface::getSurface()
|
||||
{
|
||||
return g_frontBuffer;
|
||||
}
|
||||
@ -316,16 +319,12 @@ bool RealPrimarySurface::isFullScreen()
|
||||
|
||||
bool RealPrimarySurface::isLost()
|
||||
{
|
||||
return g_frontBuffer &&
|
||||
DDERR_SURFACELOST == CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.IsLost(g_frontBuffer);
|
||||
return g_frontBuffer && DDERR_SURFACELOST == g_frontBuffer->IsLost(g_frontBuffer);
|
||||
}
|
||||
|
||||
void RealPrimarySurface::release()
|
||||
{
|
||||
if (g_frontBuffer)
|
||||
{
|
||||
g_frontBuffer->lpVtbl->Release(g_frontBuffer);
|
||||
}
|
||||
g_frontBuffer.release();
|
||||
}
|
||||
|
||||
void RealPrimarySurface::removeUpdateThread()
|
||||
@ -349,15 +348,14 @@ void RealPrimarySurface::removeUpdateThread()
|
||||
|
||||
HRESULT RealPrimarySurface::restore()
|
||||
{
|
||||
return g_frontBuffer->lpVtbl->Restore(g_frontBuffer);
|
||||
return g_frontBuffer->Restore(g_frontBuffer);
|
||||
}
|
||||
|
||||
void RealPrimarySurface::setClipper(LPDIRECTDRAWCLIPPER clipper)
|
||||
{
|
||||
CompatPaletteConverter::setClipper(clipper);
|
||||
|
||||
HRESULT result = CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.SetClipper(
|
||||
g_frontBuffer, clipper);
|
||||
HRESULT result = g_frontBuffer->SetClipper(g_frontBuffer, clipper);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to set clipper on the real primary surface: " << result);
|
||||
@ -366,10 +364,9 @@ void RealPrimarySurface::setClipper(LPDIRECTDRAWCLIPPER clipper)
|
||||
|
||||
void RealPrimarySurface::setPalette()
|
||||
{
|
||||
if (s_surfaceDesc.ddpfPixelFormat.dwRGBBitCount <= 8)
|
||||
if (g_surfaceDesc.ddpfPixelFormat.dwRGBBitCount <= 8)
|
||||
{
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable.SetPalette(
|
||||
g_frontBuffer, CompatPrimarySurface::palette);
|
||||
g_frontBuffer->SetPalette(g_frontBuffer, CompatPrimarySurface::palette);
|
||||
}
|
||||
|
||||
updatePalette(0, 256);
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatWeakPtr.h"
|
||||
|
||||
class RealPrimarySurface
|
||||
{
|
||||
public:
|
||||
@ -13,7 +15,7 @@ public:
|
||||
static void disableUpdates();
|
||||
static void enableUpdates();
|
||||
static HRESULT flip(DWORD flags);
|
||||
static IDirectDrawSurface7* getSurface();
|
||||
static CompatWeakPtr<IDirectDrawSurface7> getSurface();
|
||||
static void invalidate(const RECT* rect);
|
||||
static bool isFullScreen();
|
||||
static bool isLost();
|
||||
@ -24,6 +26,4 @@ public:
|
||||
static void setPalette();
|
||||
static void update();
|
||||
static void updatePalette(DWORD startingEntry, DWORD count);
|
||||
|
||||
static DDSURFACEDESC2 s_surfaceDesc;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user