mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Moved DirectDraw parts to DDraw namespace and subdirectory
This commit is contained in:
parent
b65f98f0e3
commit
55f840cb50
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Unknwnbase.h>
|
||||
|
||||
#include "CompatWeakPtr.h"
|
||||
|
||||
namespace CompatActivateAppHandler
|
||||
{
|
||||
void installHooks();
|
||||
bool isActive();
|
||||
void setFullScreenCooperativeLevel(CompatWeakPtr<IUnknown> dd, HWND hwnd, DWORD flags);
|
||||
void uninstallHooks();
|
||||
}
|
@ -1,223 +0,0 @@
|
||||
#include "CompatActivateAppHandler.h"
|
||||
#include "CompatDirectDraw.h"
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatDisplayMode.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "CompatRef.h"
|
||||
#include "IReleaseNotifier.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct DirectDrawInterface
|
||||
{
|
||||
void* vtable;
|
||||
void* ddObject;
|
||||
DirectDrawInterface* next;
|
||||
DWORD refCount;
|
||||
DWORD unknown1;
|
||||
DWORD unknown2;
|
||||
};
|
||||
|
||||
DirectDrawInterface* g_fullScreenDirectDraw = nullptr;
|
||||
CompatWeakPtr<IDirectDrawSurface> g_fullScreenTagSurface;
|
||||
|
||||
void onReleaseFullScreenTagSurface();
|
||||
|
||||
IReleaseNotifier g_fullScreenTagSurfaceReleaseNotifier(&onReleaseFullScreenTagSurface);
|
||||
|
||||
CompatPtr<IDirectDrawSurface> createFullScreenTagSurface(CompatRef<IDirectDraw> dd)
|
||||
{
|
||||
DDSURFACEDESC desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
|
||||
desc.dwWidth = 1;
|
||||
desc.dwHeight = 1;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
|
||||
CompatPtr<IDirectDrawSurface> tagSurface;
|
||||
dd->CreateSurface(&dd, &desc, &tagSurface.getRef(), nullptr);
|
||||
if (tagSurface)
|
||||
{
|
||||
CompatPtr<IDirectDrawSurface7> tagSurface7(tagSurface);
|
||||
tagSurface7->SetPrivateData(
|
||||
tagSurface7, IID_IReleaseNotifier, &g_fullScreenTagSurfaceReleaseNotifier,
|
||||
sizeof(&g_fullScreenTagSurfaceReleaseNotifier), DDSPD_IUNKNOWNPOINTER);
|
||||
}
|
||||
|
||||
return tagSurface;
|
||||
}
|
||||
|
||||
bool isFullScreenDirectDraw(void* dd)
|
||||
{
|
||||
return dd && g_fullScreenDirectDraw &&
|
||||
static_cast<DirectDrawInterface*>(dd)->ddObject == g_fullScreenDirectDraw->ddObject;
|
||||
}
|
||||
|
||||
void onReleaseFullScreenTagSurface()
|
||||
{
|
||||
CompatActivateAppHandler::setFullScreenCooperativeLevel(nullptr, nullptr, 0);
|
||||
g_fullScreenDirectDraw = nullptr;
|
||||
g_fullScreenTagSurface = nullptr;
|
||||
}
|
||||
|
||||
void setFullScreenDirectDraw(CompatRef<IDirectDraw> dd)
|
||||
{
|
||||
g_fullScreenTagSurface.release();
|
||||
g_fullScreenTagSurface = createFullScreenTagSurface(dd).detach();
|
||||
|
||||
/*
|
||||
IDirectDraw interfaces don't conform to the COM rule about object identity:
|
||||
QueryInterface with IID_IUnknown does not always return the same pointer for the same object.
|
||||
The IUnknown (== IDirectDraw v1) interface may even be freed, making the interface invalid,
|
||||
while the DirectDraw object itself can still be kept alive by its other interfaces.
|
||||
Unfortunately, the IDirectDrawSurface GetDDInterface method inherits this problem and may
|
||||
also return an invalid (already freed) interface pointer.
|
||||
To work around this problem, a copy of the necessary interface data is passed
|
||||
to CompatActivateAppHandler, which is sufficient for it to use QueryInterface to "safely"
|
||||
obtain a valid interface pointer (other than IUnknown/IDirectDraw v1) to the full-screen
|
||||
DirectDraw object.
|
||||
*/
|
||||
|
||||
static DirectDrawInterface fullScreenDirectDraw = {};
|
||||
ZeroMemory(&fullScreenDirectDraw, sizeof(fullScreenDirectDraw));
|
||||
DirectDrawInterface& ddIntf = reinterpret_cast<DirectDrawInterface&>(dd.get());
|
||||
fullScreenDirectDraw.vtable = ddIntf.vtable;
|
||||
fullScreenDirectDraw.ddObject = ddIntf.ddObject;
|
||||
g_fullScreenDirectDraw = &fullScreenDirectDraw;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
void CompatDirectDraw<TDirectDraw>::setCompatVtable(Vtable<TDirectDraw>& vtable)
|
||||
{
|
||||
vtable.CreateSurface = &CreateSurface;
|
||||
vtable.GetDisplayMode = &GetDisplayMode;
|
||||
vtable.RestoreDisplayMode = &RestoreDisplayMode;
|
||||
vtable.SetCooperativeLevel = &SetCooperativeLevel;
|
||||
vtable.SetDisplayMode = &SetDisplayMode;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::CreateSurface(
|
||||
TDirectDraw* This,
|
||||
TSurfaceDesc* lpDDSurfaceDesc,
|
||||
TSurface** lplpDDSurface,
|
||||
IUnknown* pUnkOuter)
|
||||
{
|
||||
HRESULT result = DD_OK;
|
||||
|
||||
const bool isPrimary = lpDDSurfaceDesc &&
|
||||
(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE);
|
||||
|
||||
if (isPrimary)
|
||||
{
|
||||
result = CompatDirectDrawSurface<TSurface>::createCompatPrimarySurface<TDirectDraw>(
|
||||
*This, *lpDDSurfaceDesc, *lplpDDSurface);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lpDDSurfaceDesc &&
|
||||
(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH) &&
|
||||
(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT) &&
|
||||
!(lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_ALPHA | DDSCAPS_ZBUFFER)))
|
||||
{
|
||||
CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
|
||||
auto dm = CompatDisplayMode::getDisplayMode(*dd);
|
||||
|
||||
TSurfaceDesc desc = *lpDDSurfaceDesc;
|
||||
if (!(desc.dwFlags & DDSD_PIXELFORMAT))
|
||||
{
|
||||
desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
desc.ddpfPixelFormat = dm.ddpfPixelFormat;
|
||||
}
|
||||
if (!(desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_OVERLAY | DDSCAPS_TEXTURE |
|
||||
DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER)))
|
||||
{
|
||||
desc.dwFlags |= DDSD_CAPS;
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
|
||||
}
|
||||
result = s_origVtable.CreateSurface(This, &desc, lplpDDSurface, pUnkOuter);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = s_origVtable.CreateSurface(This, lpDDSurfaceDesc, lplpDDSurface, pUnkOuter);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
CompatDirectDrawSurface<TSurface>::fixSurfacePtrs(**lplpDDSurface);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::GetDisplayMode(
|
||||
TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc)
|
||||
{
|
||||
const DWORD size = lpDDSurfaceDesc ? lpDDSurfaceDesc->dwSize : 0;
|
||||
if (sizeof(DDSURFACEDESC) != size && sizeof(DDSURFACEDESC2) != size)
|
||||
{
|
||||
return DDERR_INVALIDPARAMS;
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
|
||||
const DDSURFACEDESC2 dm = CompatDisplayMode::getDisplayMode(*dd);
|
||||
CopyMemory(lpDDSurfaceDesc, &dm, size);
|
||||
lpDDSurfaceDesc->dwSize = size;
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::RestoreDisplayMode(TDirectDraw* This)
|
||||
{
|
||||
CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
|
||||
return CompatDisplayMode::restoreDisplayMode(*dd);
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::SetCooperativeLevel(
|
||||
TDirectDraw* This, HWND hWnd, DWORD dwFlags)
|
||||
{
|
||||
if ((dwFlags & DDSCL_FULLSCREEN) && !CompatActivateAppHandler::isActive())
|
||||
{
|
||||
return DDERR_EXCLUSIVEMODEALREADYSET;
|
||||
}
|
||||
|
||||
HRESULT result = s_origVtable.SetCooperativeLevel(This, hWnd, dwFlags);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
if (dwFlags & DDSCL_FULLSCREEN)
|
||||
{
|
||||
CompatPtr<IDirectDraw> dd(Compat::queryInterface<IDirectDraw>(This));
|
||||
setFullScreenDirectDraw(*dd);
|
||||
CompatActivateAppHandler::setFullScreenCooperativeLevel(
|
||||
reinterpret_cast<IUnknown*>(g_fullScreenDirectDraw), hWnd, dwFlags);
|
||||
}
|
||||
else if (isFullScreenDirectDraw(This) && g_fullScreenTagSurface)
|
||||
{
|
||||
g_fullScreenTagSurface.release();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
template <typename... Params>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::SetDisplayMode(
|
||||
TDirectDraw* This,
|
||||
DWORD dwWidth,
|
||||
DWORD dwHeight,
|
||||
DWORD dwBPP,
|
||||
Params... params)
|
||||
{
|
||||
CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
|
||||
return CompatDisplayMode::setDisplayMode(*dd, dwWidth, dwHeight, dwBPP, params...);
|
||||
}
|
||||
|
||||
template CompatDirectDraw<IDirectDraw>;
|
||||
template CompatDirectDraw<IDirectDraw2>;
|
||||
template CompatDirectDraw<IDirectDraw4>;
|
||||
template CompatDirectDraw<IDirectDraw7>;
|
@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CompatVtable.h"
|
||||
#include "DDrawTypes.h"
|
||||
#include "DirectDrawVtblVisitor.h"
|
||||
|
||||
template <typename TDirectDraw>
|
||||
class CompatDirectDraw : public CompatVtable<CompatDirectDraw<TDirectDraw>, TDirectDraw>
|
||||
{
|
||||
public:
|
||||
typedef typename Types<TDirectDraw>::TCreatedSurface TSurface;
|
||||
typedef typename Types<TDirectDraw>::TSurfaceDesc TSurfaceDesc;
|
||||
|
||||
static void setCompatVtable(Vtable<TDirectDraw>& vtable);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE CreateSurface(
|
||||
TDirectDraw* This,
|
||||
TSurfaceDesc* lpDDSurfaceDesc,
|
||||
TSurface** lplpDDSurface,
|
||||
IUnknown* pUnkOuter);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE GetDisplayMode(TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc);
|
||||
static HRESULT STDMETHODCALLTYPE RestoreDisplayMode(TDirectDraw* This);
|
||||
static HRESULT STDMETHODCALLTYPE SetCooperativeLevel(TDirectDraw* This, HWND hWnd, DWORD dwFlags);
|
||||
|
||||
template <typename... Params>
|
||||
static HRESULT STDMETHODCALLTYPE SetDisplayMode(
|
||||
TDirectDraw* This,
|
||||
DWORD dwWidth,
|
||||
DWORD dwHeight,
|
||||
DWORD dwBPP,
|
||||
Params... params);
|
||||
};
|
@ -1,61 +0,0 @@
|
||||
#include <cstring>
|
||||
#include <deque>
|
||||
|
||||
#include "CompatDirectDrawPalette.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "Config.h"
|
||||
#include "RealPrimarySurface.h"
|
||||
#include "Time.h"
|
||||
|
||||
void CompatDirectDrawPalette::setCompatVtable(IDirectDrawPaletteVtbl& vtable)
|
||||
{
|
||||
vtable.SetEntries = &SetEntries;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawPalette::SetEntries(
|
||||
IDirectDrawPalette* This,
|
||||
DWORD dwFlags,
|
||||
DWORD dwStartingEntry,
|
||||
DWORD dwCount,
|
||||
LPPALETTEENTRY lpEntries)
|
||||
{
|
||||
if (This == CompatPrimarySurface::g_palette)
|
||||
{
|
||||
waitForNextUpdate();
|
||||
if (lpEntries && dwStartingEntry + dwCount <= 256 &&
|
||||
0 == std::memcmp(&CompatPrimarySurface::g_paletteEntries[dwStartingEntry],
|
||||
lpEntries, dwCount * sizeof(PALETTEENTRY)))
|
||||
{
|
||||
return DD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT result = s_origVtable.SetEntries(This, dwFlags, dwStartingEntry, dwCount, lpEntries);
|
||||
if (This == CompatPrimarySurface::g_palette && SUCCEEDED(result))
|
||||
{
|
||||
std::memcpy(&CompatPrimarySurface::g_paletteEntries[dwStartingEntry], lpEntries,
|
||||
dwCount * sizeof(PALETTEENTRY));
|
||||
RealPrimarySurface::updatePalette(dwStartingEntry, dwCount);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void CompatDirectDrawPalette::waitForNextUpdate()
|
||||
{
|
||||
static std::deque<long long> updatesInLastMs;
|
||||
|
||||
const long long qpcNow = Time::queryPerformanceCounter();
|
||||
const long long qpcLastMsBegin = qpcNow - Time::g_qpcFrequency / 1000;
|
||||
while (!updatesInLastMs.empty() && qpcLastMsBegin - updatesInLastMs.front() > 0)
|
||||
{
|
||||
updatesInLastMs.pop_front();
|
||||
}
|
||||
|
||||
if (updatesInLastMs.size() >= Config::maxPaletteUpdatesPerMs)
|
||||
{
|
||||
Sleep(1);
|
||||
updatesInLastMs.clear();
|
||||
}
|
||||
|
||||
updatesInLastMs.push_back(Time::queryPerformanceCounter());
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CompatVtable.h"
|
||||
#include "DirectDrawPaletteVtblVisitor.h"
|
||||
|
||||
class CompatDirectDrawPalette : public CompatVtable<CompatDirectDrawPalette, IDirectDrawPalette>
|
||||
{
|
||||
public:
|
||||
static void setCompatVtable(IDirectDrawPaletteVtbl& vtable);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE SetEntries(
|
||||
IDirectDrawPalette* This,
|
||||
DWORD dwFlags,
|
||||
DWORD dwStartingEntry,
|
||||
DWORD dwCount,
|
||||
LPPALETTEENTRY lpEntries);
|
||||
|
||||
static void waitForNextUpdate();
|
||||
};
|
@ -1,554 +0,0 @@
|
||||
#include <set>
|
||||
|
||||
#include "CompatDirectDraw.h"
|
||||
#include "CompatDirectDrawPalette.h"
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatDisplayMode.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "DDrawRepository.h"
|
||||
#include "Gdi/Gdi.h"
|
||||
#include "IReleaseNotifier.h"
|
||||
#include "RealPrimarySurface.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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DDSURFACEDESC2 tempSurfaceDesc = desc;
|
||||
tempSurfaceDesc.dwWidth = 1;
|
||||
tempSurfaceDesc.dwHeight = 1;
|
||||
DDrawRepository::ScopedSurface tempSurface(desc);
|
||||
if (!tempSurface.surface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RECT r = { 0, 0, 1, 1 };
|
||||
surface->Blt(&surface, &r, tempSurface.surface, &r, DDBLT_WAIT, nullptr);
|
||||
}
|
||||
|
||||
HRESULT WINAPI fixSurfacePtrEnumCallback(
|
||||
LPDIRECTDRAWSURFACE7 lpDDSurface,
|
||||
LPDDSURFACEDESC2 lpDDSurfaceDesc,
|
||||
LPVOID lpContext)
|
||||
{
|
||||
auto& visitedSurfaces = *static_cast<std::set<IDirectDrawSurface7*>*>(lpContext);
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> surface(lpDDSurface);
|
||||
if (visitedSurfaces.find(surface) == visitedSurfaces.end())
|
||||
{
|
||||
visitedSurfaces.insert(surface);
|
||||
fixSurfacePtr(*surface, *lpDDSurfaceDesc);
|
||||
surface->EnumAttachedSurfaces(surface, lpContext, &fixSurfacePtrEnumCallback);
|
||||
}
|
||||
|
||||
return DDENUMRET_OK;
|
||||
}
|
||||
|
||||
void fixSurfacePtrs(CompatRef<IDirectDrawSurface7> surface)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
surface->GetSurfaceDesc(&surface, &desc);
|
||||
|
||||
fixSurfacePtr(surface, desc);
|
||||
std::set<IDirectDrawSurface7*> visitedSurfaces{ &surface };
|
||||
surface->EnumAttachedSurfaces(&surface, &visitedSurfaces, &fixSurfacePtrEnumCallback);
|
||||
}
|
||||
|
||||
CompatWeakPtr<IDirectDrawSurface7> getMirroredSurface(
|
||||
CompatRef<IDirectDrawSurface7> surface, RECT* srcRect, DWORD mirrorFx)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
HRESULT result = surface->GetSurfaceDesc(&surface, &desc);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to get surface description for mirroring: " << result);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (srcRect)
|
||||
{
|
||||
desc.dwWidth = srcRect->right - srcRect->left;
|
||||
desc.dwHeight = srcRect->bottom - srcRect->top;
|
||||
}
|
||||
|
||||
DDrawRepository::ScopedSurface mirroredSurface(desc);
|
||||
if (!mirroredSurface.surface)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RECT rect = { 0, 0, static_cast<LONG>(desc.dwWidth), static_cast<LONG>(desc.dwHeight) };
|
||||
if ((mirrorFx & DDBLTFX_MIRRORLEFTRIGHT) && (mirrorFx & DDBLTFX_MIRRORUPDOWN))
|
||||
{
|
||||
DDrawRepository::Surface tempMirroredSurface = DDrawRepository::ScopedSurface(desc);
|
||||
if (!tempMirroredSurface.surface ||
|
||||
!mirrorBlt(*tempMirroredSurface.surface, surface, srcRect ? *srcRect : rect,
|
||||
DDBLTFX_MIRRORLEFTRIGHT) ||
|
||||
!mirrorBlt(*mirroredSurface.surface, *tempMirroredSurface.surface, rect,
|
||||
DDBLTFX_MIRRORUPDOWN))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if (!mirrorBlt(*mirroredSurface.surface, surface, srcRect ? *srcRect : rect, mirrorFx))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return mirroredSurface.surface;
|
||||
}
|
||||
|
||||
bool mirrorBlt(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src,
|
||||
RECT srcRect, DWORD mirrorFx)
|
||||
{
|
||||
if (DDBLTFX_MIRRORLEFTRIGHT == mirrorFx)
|
||||
{
|
||||
LONG width = srcRect.right - srcRect.left;
|
||||
srcRect.left = srcRect.right - 1;
|
||||
for (LONG x = 0; x < width; ++x)
|
||||
{
|
||||
HRESULT result = dst->BltFast(&dst, x, 0, &src, &srcRect, DDBLTFAST_WAIT);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed BltFast for mirroring: " << result);
|
||||
return false;
|
||||
}
|
||||
--srcRect.left;
|
||||
--srcRect.right;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LONG height = srcRect.bottom - srcRect.top;
|
||||
srcRect.top = srcRect.bottom - 1;
|
||||
for (LONG y = 0; y < height; ++y)
|
||||
{
|
||||
HRESULT result = dst->BltFast(&dst, 0, y, &src, &srcRect, DDBLTFAST_WAIT);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed BltFast for mirroring: " << result);
|
||||
return false;
|
||||
}
|
||||
--srcRect.top;
|
||||
--srcRect.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
void CompatDirectDrawSurface<TSurface>::setCompatVtable(Vtable<TSurface>& vtable)
|
||||
{
|
||||
vtable.Blt = &Blt;
|
||||
vtable.BltFast = &BltFast;
|
||||
vtable.Flip = &Flip;
|
||||
vtable.GetCaps = &GetCaps;
|
||||
vtable.GetSurfaceDesc = &GetSurfaceDesc;
|
||||
vtable.IsLost = &IsLost;
|
||||
vtable.Lock = &Lock;
|
||||
vtable.QueryInterface = &QueryInterface;
|
||||
vtable.ReleaseDC = &ReleaseDC;
|
||||
vtable.Restore = &Restore;
|
||||
vtable.SetClipper = &SetClipper;
|
||||
vtable.SetPalette = &SetPalette;
|
||||
vtable.Unlock = &Unlock;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
template <typename TDirectDraw>
|
||||
HRESULT CompatDirectDrawSurface<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 = CompatDisplayMode::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 = dd->CreateSurface(&dd, &compatDesc, &compatSurface, nullptr);
|
||||
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>
|
||||
void CompatDirectDrawSurface<TSurface>::fixSurfacePtrs(CompatRef<TSurface> surface)
|
||||
{
|
||||
CompatPtr<IDirectDrawSurface7> surface7(Compat::queryInterface<IDirectDrawSurface7>(&surface));
|
||||
::fixSurfacePtrs(*surface7);
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Blt(
|
||||
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;
|
||||
|
||||
if (lpDDSrcSurface && (dwFlags & DDBLT_DDFX) && lpDDBltFx &&
|
||||
(lpDDBltFx->dwDDFX & (DDBLTFX_MIRRORLEFTRIGHT | DDBLTFX_MIRRORUPDOWN)))
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
if (mirroredSrcSurface)
|
||||
{
|
||||
DWORD flags = dwFlags;
|
||||
DDBLTFX fx = *lpDDBltFx;
|
||||
fx.dwDDFX &= ~(DDBLTFX_MIRRORLEFTRIGHT | DDBLTFX_MIRRORUPDOWN);
|
||||
if (0 == fx.dwDDFX)
|
||||
{
|
||||
flags ^= DDBLT_DDFX;
|
||||
}
|
||||
if (flags & DDBLT_KEYSRC)
|
||||
{
|
||||
DDCOLORKEY srcColorKey = {};
|
||||
s_origVtable.GetColorKey(lpDDSrcSurface, DDCKEY_SRCBLT, &srcColorKey);
|
||||
s_origVtable.SetColorKey(mirroredSrcSurface, DDCKEY_SRCBLT, &srcColorKey);
|
||||
}
|
||||
|
||||
if (lpSrcRect)
|
||||
{
|
||||
RECT srcRect = { 0, 0, lpSrcRect->right - lpSrcRect->left, lpSrcRect->bottom - lpSrcRect->top };
|
||||
result = s_origVtable.Blt(This, lpDestRect, mirroredSrcSurface, &srcRect, flags, &fx);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = s_origVtable.Blt(This, lpDestRect, mirroredSrcSurface, nullptr, flags, &fx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = s_origVtable.Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
|
||||
}
|
||||
|
||||
if (isPrimaryDest && SUCCEEDED(result))
|
||||
{
|
||||
RealPrimarySurface::invalidate(lpDestRect);
|
||||
RealPrimarySurface::update();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::GetCaps(
|
||||
TSurface* This,
|
||||
TDdsCaps* lpDDSCaps)
|
||||
{
|
||||
HRESULT result = s_origVtable.GetCaps(This, lpDDSCaps);
|
||||
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
restorePrimaryCaps(*lpDDSCaps);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::Lock(
|
||||
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)
|
||||
{
|
||||
TSurfaceDesc desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
if (SUCCEEDED(s_origVtable.GetSurfaceDesc(This, &desc)) && !(desc.dwFlags & DDSD_HEIGHT))
|
||||
{
|
||||
// Fixes missing handling for lost vertex buffers in Messiah
|
||||
s_origVtable.Restore(This);
|
||||
// Still, pass back DDERR_SURFACELOST to the application in case it handles it
|
||||
}
|
||||
}
|
||||
|
||||
g_lockingPrimary = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<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 STDMETHODCALLTYPE CompatDirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::SetClipper(
|
||||
TSurface* This,
|
||||
LPDIRECTDRAWCLIPPER lpDDClipper)
|
||||
{
|
||||
HRESULT result = s_origVtable.SetClipper(This, lpDDClipper);
|
||||
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
RealPrimarySurface::setClipper(lpDDClipper);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<TSurface>::SetPalette(
|
||||
TSurface* This,
|
||||
LPDIRECTDRAWPALETTE lpDDPalette)
|
||||
{
|
||||
const bool isPrimary = CompatPrimarySurface::isPrimary(This);
|
||||
if (isPrimary)
|
||||
{
|
||||
if (lpDDPalette)
|
||||
{
|
||||
CompatDirectDrawPalette::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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CompatDirectDrawSurface<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 CompatDirectDrawSurface<TSurface>::restorePrimaryCaps(TDdsCaps& caps)
|
||||
{
|
||||
caps.dwCaps &= ~(DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY);
|
||||
caps.dwCaps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
|
||||
}
|
||||
|
||||
template CompatDirectDrawSurface<IDirectDrawSurface>;
|
||||
template CompatDirectDrawSurface<IDirectDrawSurface2>;
|
||||
template CompatDirectDrawSurface<IDirectDrawSurface3>;
|
||||
template CompatDirectDrawSurface<IDirectDrawSurface4>;
|
||||
template CompatDirectDrawSurface<IDirectDrawSurface7>;
|
||||
|
||||
template HRESULT CompatDirectDrawSurface<IDirectDrawSurface>::createCompatPrimarySurface(
|
||||
CompatRef<IDirectDraw> dd,
|
||||
TSurfaceDesc compatDesc,
|
||||
IDirectDrawSurface*& compatSurface);
|
||||
template HRESULT CompatDirectDrawSurface<IDirectDrawSurface>::createCompatPrimarySurface(
|
||||
CompatRef<IDirectDraw2> dd,
|
||||
TSurfaceDesc compatDesc,
|
||||
IDirectDrawSurface*& compatSurface);
|
||||
template HRESULT CompatDirectDrawSurface<IDirectDrawSurface4>::createCompatPrimarySurface(
|
||||
CompatRef<IDirectDraw4> dd,
|
||||
TSurfaceDesc compatDesc,
|
||||
IDirectDrawSurface4*& compatSurface);
|
||||
template HRESULT CompatDirectDrawSurface<IDirectDrawSurface7>::createCompatPrimarySurface(
|
||||
CompatRef<IDirectDraw7> dd,
|
||||
TSurfaceDesc compatDesc,
|
||||
IDirectDrawSurface7*& compatSurface);
|
@ -1,67 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CompatRef.h"
|
||||
#include "CompatVtable.h"
|
||||
#include "DDrawTypes.h"
|
||||
#include "DirectDrawSurfaceVtblVisitor.h"
|
||||
|
||||
template <typename TSurface>
|
||||
class CompatDirectDrawSurface : public CompatVtable<CompatDirectDrawSurface<TSurface>, TSurface>
|
||||
{
|
||||
public:
|
||||
typedef typename Types<TSurface>::TSurfaceDesc TSurfaceDesc;
|
||||
typedef typename Types<TSurface>::TDdsCaps TDdsCaps;
|
||||
typedef typename Types<TSurface>::TUnlockParam TUnlockParam;
|
||||
|
||||
static void setCompatVtable(Vtable<TSurface>& vtable);
|
||||
|
||||
template <typename TDirectDraw>
|
||||
static HRESULT createCompatPrimarySurface(
|
||||
CompatRef<TDirectDraw> dd,
|
||||
TSurfaceDesc compatDesc,
|
||||
TSurface*& compatSurface);
|
||||
|
||||
static void fixSurfacePtrs(CompatRef<TSurface> surface);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Blt(
|
||||
TSurface* This,
|
||||
LPRECT lpDestRect,
|
||||
TSurface* lpDDSrcSurface,
|
||||
LPRECT lpSrcRect,
|
||||
DWORD dwFlags,
|
||||
LPDDBLTFX lpDDBltFx);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE BltFast(
|
||||
TSurface* This,
|
||||
DWORD dwX,
|
||||
DWORD dwY,
|
||||
TSurface* lpDDSrcSurface,
|
||||
LPRECT lpSrcRect,
|
||||
DWORD dwTrans);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Flip(
|
||||
TSurface* This,
|
||||
TSurface* lpDDSurfaceTargetOverride,
|
||||
DWORD dwFlags);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE GetCaps(TSurface* This, TDdsCaps* lpDDSCaps);
|
||||
static HRESULT STDMETHODCALLTYPE GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc);
|
||||
static HRESULT STDMETHODCALLTYPE IsLost(TSurface* This);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Lock(
|
||||
TSurface* This,
|
||||
LPRECT lpDestRect,
|
||||
TSurfaceDesc* lpDDSurfaceDesc,
|
||||
DWORD dwFlags,
|
||||
HANDLE hEvent);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE QueryInterface(TSurface* This, REFIID riid, LPVOID* obp);
|
||||
static HRESULT STDMETHODCALLTYPE ReleaseDC(TSurface* This, HDC hDC);
|
||||
static HRESULT STDMETHODCALLTYPE Restore(TSurface* This);
|
||||
static HRESULT STDMETHODCALLTYPE SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper);
|
||||
static HRESULT STDMETHODCALLTYPE SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette);
|
||||
static HRESULT STDMETHODCALLTYPE Unlock(TSurface* This, TUnlockParam lpRect);
|
||||
|
||||
private:
|
||||
static void restorePrimaryCaps(TDdsCaps& caps);
|
||||
};
|
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatRef.h"
|
||||
|
||||
namespace CompatDisplayMode
|
||||
{
|
||||
void installHooks();
|
||||
|
||||
HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy);
|
||||
HBITMAP WINAPI createDIBitmap(HDC hdc, const BITMAPINFOHEADER* lpbmih, DWORD fdwInit,
|
||||
const void* lpbInit, const BITMAPINFO* lpbmi, UINT fuUsage);
|
||||
HBITMAP WINAPI createDiscardableBitmap(HDC hdc, int nWidth, int nHeight);
|
||||
|
||||
DDSURFACEDESC2 getDisplayMode(CompatRef<IDirectDraw7> dd);
|
||||
HRESULT restoreDisplayMode(CompatRef<IDirectDraw7> dd);
|
||||
HRESULT setDisplayMode(CompatRef<IDirectDraw7> dd,
|
||||
DWORD width, DWORD height, DWORD bpp, DWORD refreshRate = 0, DWORD flags = 0);
|
||||
};
|
@ -1,5 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
namespace CompatFontSmoothing
|
||||
{
|
||||
struct SystemSettings
|
||||
|
@ -1,161 +0,0 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#include "CompatDisplayMode.h"
|
||||
#include "CompatPaletteConverter.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "DDrawRepository.h"
|
||||
#include "DDrawTypes.h"
|
||||
#include "Hook.h"
|
||||
#include "RealPrimarySurface.h"
|
||||
#include "ScopedCriticalSection.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
HDC g_dc = nullptr;
|
||||
HGDIOBJ g_oldBitmap = nullptr;
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_surface;
|
||||
|
||||
void convertPaletteEntriesToRgbQuad(RGBQUAD* entries, DWORD count)
|
||||
{
|
||||
for (DWORD i = 0; i < count; ++i)
|
||||
{
|
||||
entries[i].rgbReserved = 0;
|
||||
std::swap(entries[i].rgbRed, entries[i].rgbBlue);
|
||||
}
|
||||
}
|
||||
|
||||
HBITMAP createDibSection(const DDSURFACEDESC2& dm, void*& bits)
|
||||
{
|
||||
struct PalettizedBitmapInfo
|
||||
{
|
||||
BITMAPINFOHEADER header;
|
||||
PALETTEENTRY colors[256];
|
||||
};
|
||||
|
||||
PalettizedBitmapInfo bmi = {};
|
||||
bmi.header.biSize = sizeof(bmi.header);
|
||||
bmi.header.biWidth = dm.dwWidth;
|
||||
bmi.header.biHeight = -static_cast<LONG>(dm.dwHeight);
|
||||
bmi.header.biPlanes = 1;
|
||||
bmi.header.biBitCount = static_cast<WORD>(dm.ddpfPixelFormat.dwRGBBitCount);
|
||||
bmi.header.biCompression = BI_RGB;
|
||||
|
||||
return CreateDIBSection(nullptr, reinterpret_cast<BITMAPINFO*>(&bmi),
|
||||
DIB_RGB_COLORS, &bits, nullptr, 0);
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> createSurface(const DDSURFACEDESC2& dm, void* bits)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS |
|
||||
DDSD_PITCH | DDSD_LPSURFACE;
|
||||
desc.dwWidth = dm.dwWidth;
|
||||
desc.dwHeight = dm.dwHeight;
|
||||
desc.ddpfPixelFormat = dm.ddpfPixelFormat;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
desc.lPitch = (dm.dwWidth * dm.ddpfPixelFormat.dwRGBBitCount / 8 + 3) & ~3;
|
||||
desc.lpSurface = bits;
|
||||
|
||||
auto dd(DDrawRepository::getDirectDraw());
|
||||
CompatPtr<IDirectDrawSurface7> surface;
|
||||
dd->CreateSurface(dd, &desc, &surface.getRef(), nullptr);
|
||||
return surface;
|
||||
}
|
||||
}
|
||||
|
||||
namespace CompatPaletteConverter
|
||||
{
|
||||
bool create()
|
||||
{
|
||||
auto dd(DDrawRepository::getDirectDraw());
|
||||
auto dm(CompatDisplayMode::getDisplayMode(*dd));
|
||||
DDSURFACEDESC2 realDm = {};
|
||||
realDm.dwSize = sizeof(realDm);
|
||||
dd->GetDisplayMode(dd, &realDm);
|
||||
if (dm.ddpfPixelFormat.dwRGBBitCount > 8 &&
|
||||
realDm.ddpfPixelFormat.dwRGBBitCount > 8)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void* bits = nullptr;
|
||||
HBITMAP dib = createDibSection(dm, bits);
|
||||
if (!dib)
|
||||
{
|
||||
Compat::Log() << "Failed to create the palette converter DIB section";
|
||||
return false;
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> surface(createSurface(dm, bits));
|
||||
if (!surface)
|
||||
{
|
||||
Compat::Log() << "Failed to create the palette converter surface";
|
||||
DeleteObject(dib);
|
||||
return false;
|
||||
}
|
||||
|
||||
HDC dc = CALL_ORIG_FUNC(CreateCompatibleDC)(nullptr);
|
||||
if (!dc)
|
||||
{
|
||||
Compat::Log() << "Failed to create the palette converter DC";
|
||||
DeleteObject(dib);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_oldBitmap = SelectObject(dc, dib);
|
||||
g_dc = dc;
|
||||
g_surface = surface.detach();
|
||||
return true;
|
||||
}
|
||||
|
||||
HDC getDc()
|
||||
{
|
||||
return g_dc;
|
||||
}
|
||||
|
||||
CompatWeakPtr<IDirectDrawSurface7> getSurface()
|
||||
{
|
||||
return g_surface;
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
if (!g_surface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_surface.release();
|
||||
|
||||
DeleteObject(SelectObject(g_dc, g_oldBitmap));
|
||||
DeleteDC(g_dc);
|
||||
g_dc = nullptr;
|
||||
}
|
||||
|
||||
void setClipper(CompatWeakPtr<IDirectDrawClipper> clipper)
|
||||
{
|
||||
if (g_surface)
|
||||
{
|
||||
HRESULT result = g_surface->SetClipper(g_surface, clipper);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to set a clipper on the palette converter surface: " << result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updatePalette(DWORD startingEntry, DWORD count)
|
||||
{
|
||||
if (g_dc && CompatPrimarySurface::g_palette)
|
||||
{
|
||||
RGBQUAD entries[256] = {};
|
||||
std::memcpy(entries, &CompatPrimarySurface::g_paletteEntries[startingEntry],
|
||||
count * sizeof(PALETTEENTRY));
|
||||
convertPaletteEntriesToRgbQuad(entries, count);
|
||||
SetDIBColorTable(g_dc, startingEntry, count, entries);
|
||||
}
|
||||
}
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatWeakPtr.h"
|
||||
|
||||
namespace CompatPaletteConverter
|
||||
{
|
||||
bool create();
|
||||
HDC getDc();
|
||||
CompatWeakPtr<IDirectDrawSurface7> getSurface();
|
||||
void release();
|
||||
void setClipper(CompatWeakPtr<IDirectDrawClipper> clipper);
|
||||
void updatePalette(DWORD startingEntry, DWORD count);
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "IReleaseNotifier.h"
|
||||
#include "RealPrimarySurface.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
void onRelease();
|
||||
|
||||
DDSURFACEDESC2 g_primarySurfaceDesc = {};
|
||||
CompatWeakPtr<IDirectDrawSurface> g_primarySurface = nullptr;
|
||||
std::vector<void*> g_primarySurfacePtrs;
|
||||
IReleaseNotifier g_releaseNotifier(onRelease);
|
||||
|
||||
void onRelease()
|
||||
{
|
||||
Compat::LogEnter("CompatPrimarySurface::onRelease");
|
||||
|
||||
g_primarySurfacePtrs.clear();
|
||||
g_primarySurface = nullptr;
|
||||
CompatPrimarySurface::g_palette = nullptr;
|
||||
ZeroMemory(&CompatPrimarySurface::g_paletteEntries, sizeof(CompatPrimarySurface::g_paletteEntries));
|
||||
ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
|
||||
|
||||
RealPrimarySurface::release();
|
||||
|
||||
Compat::LogLeave("CompatPrimarySurface::onRelease");
|
||||
}
|
||||
}
|
||||
|
||||
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] = {};
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatPtr.h"
|
||||
#include "CompatRef.h"
|
||||
|
||||
class IReleaseNotifier;
|
||||
|
||||
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];
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
#include "CompatActivateAppHandler.h"
|
||||
#include "CompatDirectDraw.h"
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatDisplayMode.h"
|
||||
#include "CompatFontSmoothing.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "CompatRef.h"
|
||||
#include "DDraw/ActivateAppHandler.h"
|
||||
#include "DDraw/CompatPrimarySurface.h"
|
||||
#include "DDraw/DirectDraw.h"
|
||||
#include "DDraw/DirectDrawSurface.h"
|
||||
#include "DDraw/DisplayMode.h"
|
||||
#include "DDrawLog.h"
|
||||
#include "Gdi/Gdi.h"
|
||||
|
||||
@ -35,13 +35,13 @@ namespace
|
||||
}
|
||||
|
||||
dd->SetCooperativeLevel(&dd, g_fullScreenCooperativeWindow, g_fullScreenCooperativeFlags);
|
||||
auto dm = CompatDisplayMode::getDisplayMode(dd);
|
||||
auto dm = DDraw::DisplayMode::getDisplayMode(dd);
|
||||
dd->SetDisplayMode(&dd, dm.dwWidth, dm.dwHeight, 32, dm.dwRefreshRate, 0);
|
||||
|
||||
auto primary(CompatPrimarySurface::getPrimary());
|
||||
auto primary(DDraw::CompatPrimarySurface::getPrimary());
|
||||
if (primary && SUCCEEDED(primary->Restore(primary)))
|
||||
{
|
||||
CompatDirectDrawSurface<IDirectDrawSurface7>::fixSurfacePtrs(*primary);
|
||||
DDraw::DirectDrawSurface<IDirectDrawSurface7>::fixSurfacePtrs(*primary);
|
||||
Gdi::invalidate(nullptr);
|
||||
}
|
||||
|
||||
@ -115,28 +115,31 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
namespace CompatActivateAppHandler
|
||||
namespace DDraw
|
||||
{
|
||||
void installHooks()
|
||||
namespace ActivateAppHandler
|
||||
{
|
||||
const DWORD threadId = GetCurrentThreadId();
|
||||
g_callWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, callWndProc, nullptr, threadId);
|
||||
}
|
||||
void installHooks()
|
||||
{
|
||||
const DWORD threadId = GetCurrentThreadId();
|
||||
g_callWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, callWndProc, nullptr, threadId);
|
||||
}
|
||||
|
||||
bool isActive()
|
||||
{
|
||||
return g_isActive;
|
||||
}
|
||||
bool isActive()
|
||||
{
|
||||
return g_isActive;
|
||||
}
|
||||
|
||||
void setFullScreenCooperativeLevel(CompatWeakPtr<IUnknown> dd, HWND hwnd, DWORD flags)
|
||||
{
|
||||
g_fullScreenDirectDraw = dd;
|
||||
g_fullScreenCooperativeWindow = hwnd;
|
||||
g_fullScreenCooperativeFlags = flags;
|
||||
}
|
||||
void setFullScreenCooperativeLevel(CompatWeakPtr<IUnknown> dd, HWND hwnd, DWORD flags)
|
||||
{
|
||||
g_fullScreenDirectDraw = dd;
|
||||
g_fullScreenCooperativeWindow = hwnd;
|
||||
g_fullScreenCooperativeFlags = flags;
|
||||
}
|
||||
|
||||
void uninstallHooks()
|
||||
{
|
||||
UnhookWindowsHookEx(g_callWndProcHook);
|
||||
void uninstallHooks()
|
||||
{
|
||||
UnhookWindowsHookEx(g_callWndProcHook);
|
||||
}
|
||||
}
|
||||
}
|
20
DDrawCompat/DDraw/ActivateAppHandler.h
Normal file
20
DDrawCompat/DDraw/ActivateAppHandler.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Unknwnbase.h>
|
||||
|
||||
#include "CompatWeakPtr.h"
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
namespace ActivateAppHandler
|
||||
{
|
||||
void installHooks();
|
||||
bool isActive();
|
||||
void setFullScreenCooperativeLevel(CompatWeakPtr<IUnknown> dd, HWND hwnd, DWORD flags);
|
||||
void uninstallHooks();
|
||||
}
|
||||
}
|
85
DDrawCompat/DDraw/CompatPrimarySurface.cpp
Normal file
85
DDrawCompat/DDraw/CompatPrimarySurface.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "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] = {};
|
||||
}
|
||||
}
|
22
DDrawCompat/DDraw/CompatPrimarySurface.h
Normal file
22
DDrawCompat/DDraw/CompatPrimarySurface.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatPtr.h"
|
||||
#include "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];
|
||||
}
|
||||
}
|
226
DDrawCompat/DDraw/DirectDraw.cpp
Normal file
226
DDrawCompat/DDraw/DirectDraw.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
#include "CompatPtr.h"
|
||||
#include "CompatRef.h"
|
||||
#include "DDraw/ActivateAppHandler.h"
|
||||
#include "DDraw/DirectDraw.h"
|
||||
#include "DDraw/DirectDrawSurface.h"
|
||||
#include "DDraw/DisplayMode.h"
|
||||
#include "DDraw/IReleaseNotifier.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct DirectDrawInterface
|
||||
{
|
||||
void* vtable;
|
||||
void* ddObject;
|
||||
DirectDrawInterface* next;
|
||||
DWORD refCount;
|
||||
DWORD unknown1;
|
||||
DWORD unknown2;
|
||||
};
|
||||
|
||||
DirectDrawInterface* g_fullScreenDirectDraw = nullptr;
|
||||
CompatWeakPtr<IDirectDrawSurface> g_fullScreenTagSurface;
|
||||
|
||||
void onReleaseFullScreenTagSurface();
|
||||
|
||||
DDraw::IReleaseNotifier g_fullScreenTagSurfaceReleaseNotifier(&onReleaseFullScreenTagSurface);
|
||||
|
||||
CompatPtr<IDirectDrawSurface> createFullScreenTagSurface(CompatRef<IDirectDraw> dd)
|
||||
{
|
||||
DDSURFACEDESC desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
|
||||
desc.dwWidth = 1;
|
||||
desc.dwHeight = 1;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
|
||||
CompatPtr<IDirectDrawSurface> tagSurface;
|
||||
dd->CreateSurface(&dd, &desc, &tagSurface.getRef(), nullptr);
|
||||
if (tagSurface)
|
||||
{
|
||||
CompatPtr<IDirectDrawSurface7> tagSurface7(tagSurface);
|
||||
tagSurface7->SetPrivateData(
|
||||
tagSurface7, IID_IReleaseNotifier, &g_fullScreenTagSurfaceReleaseNotifier,
|
||||
sizeof(&g_fullScreenTagSurfaceReleaseNotifier), DDSPD_IUNKNOWNPOINTER);
|
||||
}
|
||||
|
||||
return tagSurface;
|
||||
}
|
||||
|
||||
bool isFullScreenDirectDraw(void* dd)
|
||||
{
|
||||
return dd && g_fullScreenDirectDraw &&
|
||||
static_cast<DirectDrawInterface*>(dd)->ddObject == g_fullScreenDirectDraw->ddObject;
|
||||
}
|
||||
|
||||
void onReleaseFullScreenTagSurface()
|
||||
{
|
||||
DDraw::ActivateAppHandler::setFullScreenCooperativeLevel(nullptr, nullptr, 0);
|
||||
g_fullScreenDirectDraw = nullptr;
|
||||
g_fullScreenTagSurface = nullptr;
|
||||
}
|
||||
|
||||
void setFullScreenDirectDraw(CompatRef<IDirectDraw> dd)
|
||||
{
|
||||
g_fullScreenTagSurface.release();
|
||||
g_fullScreenTagSurface = createFullScreenTagSurface(dd).detach();
|
||||
|
||||
/*
|
||||
IDirectDraw interfaces don't conform to the COM rule about object identity:
|
||||
QueryInterface with IID_IUnknown does not always return the same pointer for the same object.
|
||||
The IUnknown (== IDirectDraw v1) interface may even be freed, making the interface invalid,
|
||||
while the DirectDraw object itself can still be kept alive by its other interfaces.
|
||||
Unfortunately, the IDirectDrawSurface GetDDInterface method inherits this problem and may
|
||||
also return an invalid (already freed) interface pointer.
|
||||
To work around this problem, a copy of the necessary interface data is passed
|
||||
to CompatActivateAppHandler, which is sufficient for it to use QueryInterface to "safely"
|
||||
obtain a valid interface pointer (other than IUnknown/IDirectDraw v1) to the full-screen
|
||||
DirectDraw object.
|
||||
*/
|
||||
|
||||
static DirectDrawInterface fullScreenDirectDraw = {};
|
||||
ZeroMemory(&fullScreenDirectDraw, sizeof(fullScreenDirectDraw));
|
||||
DirectDrawInterface& ddIntf = reinterpret_cast<DirectDrawInterface&>(dd.get());
|
||||
fullScreenDirectDraw.vtable = ddIntf.vtable;
|
||||
fullScreenDirectDraw.ddObject = ddIntf.ddObject;
|
||||
g_fullScreenDirectDraw = &fullScreenDirectDraw;
|
||||
}
|
||||
}
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
template <typename TDirectDraw>
|
||||
void DirectDraw<TDirectDraw>::setCompatVtable(Vtable<TDirectDraw>& vtable)
|
||||
{
|
||||
vtable.CreateSurface = &CreateSurface;
|
||||
vtable.GetDisplayMode = &GetDisplayMode;
|
||||
vtable.RestoreDisplayMode = &RestoreDisplayMode;
|
||||
vtable.SetCooperativeLevel = &SetCooperativeLevel;
|
||||
vtable.SetDisplayMode = &SetDisplayMode;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::CreateSurface(
|
||||
TDirectDraw* This,
|
||||
TSurfaceDesc* lpDDSurfaceDesc,
|
||||
TSurface** lplpDDSurface,
|
||||
IUnknown* pUnkOuter)
|
||||
{
|
||||
HRESULT result = DD_OK;
|
||||
|
||||
const bool isPrimary = lpDDSurfaceDesc &&
|
||||
(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE);
|
||||
|
||||
if (isPrimary)
|
||||
{
|
||||
result = DirectDrawSurface<TSurface>::createCompatPrimarySurface<TDirectDraw>(
|
||||
*This, *lpDDSurfaceDesc, *lplpDDSurface);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lpDDSurfaceDesc &&
|
||||
(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH) &&
|
||||
(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT) &&
|
||||
!(lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_ALPHA | DDSCAPS_ZBUFFER)))
|
||||
{
|
||||
CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
|
||||
auto dm = DisplayMode::getDisplayMode(*dd);
|
||||
|
||||
TSurfaceDesc desc = *lpDDSurfaceDesc;
|
||||
if (!(desc.dwFlags & DDSD_PIXELFORMAT))
|
||||
{
|
||||
desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
desc.ddpfPixelFormat = dm.ddpfPixelFormat;
|
||||
}
|
||||
if (!(desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_OVERLAY | DDSCAPS_TEXTURE |
|
||||
DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER)))
|
||||
{
|
||||
desc.dwFlags |= DDSD_CAPS;
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
|
||||
}
|
||||
result = s_origVtable.CreateSurface(This, &desc, lplpDDSurface, pUnkOuter);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = s_origVtable.CreateSurface(This, lpDDSurfaceDesc, lplpDDSurface, pUnkOuter);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
DirectDrawSurface<TSurface>::fixSurfacePtrs(**lplpDDSurface);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::GetDisplayMode(
|
||||
TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc)
|
||||
{
|
||||
const DWORD size = lpDDSurfaceDesc ? lpDDSurfaceDesc->dwSize : 0;
|
||||
if (sizeof(DDSURFACEDESC) != size && sizeof(DDSURFACEDESC2) != size)
|
||||
{
|
||||
return DDERR_INVALIDPARAMS;
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
|
||||
const DDSURFACEDESC2 dm = DisplayMode::getDisplayMode(*dd);
|
||||
CopyMemory(lpDDSurfaceDesc, &dm, size);
|
||||
lpDDSurfaceDesc->dwSize = size;
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::RestoreDisplayMode(TDirectDraw* This)
|
||||
{
|
||||
CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
|
||||
return DisplayMode::restoreDisplayMode(*dd);
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::SetCooperativeLevel(
|
||||
TDirectDraw* This, HWND hWnd, DWORD dwFlags)
|
||||
{
|
||||
if ((dwFlags & DDSCL_FULLSCREEN) && !ActivateAppHandler::isActive())
|
||||
{
|
||||
return DDERR_EXCLUSIVEMODEALREADYSET;
|
||||
}
|
||||
|
||||
HRESULT result = s_origVtable.SetCooperativeLevel(This, hWnd, dwFlags);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
if (dwFlags & DDSCL_FULLSCREEN)
|
||||
{
|
||||
CompatPtr<IDirectDraw> dd(Compat::queryInterface<IDirectDraw>(This));
|
||||
setFullScreenDirectDraw(*dd);
|
||||
ActivateAppHandler::setFullScreenCooperativeLevel(
|
||||
reinterpret_cast<IUnknown*>(g_fullScreenDirectDraw), hWnd, dwFlags);
|
||||
}
|
||||
else if (isFullScreenDirectDraw(This) && g_fullScreenTagSurface)
|
||||
{
|
||||
g_fullScreenTagSurface.release();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
template <typename... Params>
|
||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::SetDisplayMode(
|
||||
TDirectDraw* This,
|
||||
DWORD dwWidth,
|
||||
DWORD dwHeight,
|
||||
DWORD dwBPP,
|
||||
Params... params)
|
||||
{
|
||||
CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
|
||||
return DisplayMode::setDisplayMode(*dd, dwWidth, dwHeight, dwBPP, params...);
|
||||
}
|
||||
|
||||
template DirectDraw<IDirectDraw>;
|
||||
template DirectDraw<IDirectDraw2>;
|
||||
template DirectDraw<IDirectDraw4>;
|
||||
template DirectDraw<IDirectDraw7>;
|
||||
}
|
36
DDrawCompat/DDraw/DirectDraw.h
Normal file
36
DDrawCompat/DDraw/DirectDraw.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "CompatVtable.h"
|
||||
#include "DDraw/Types.h"
|
||||
#include "DirectDrawVtblVisitor.h"
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
template <typename TDirectDraw>
|
||||
class DirectDraw: public CompatVtable<DirectDraw<TDirectDraw>, TDirectDraw>
|
||||
{
|
||||
public:
|
||||
typedef typename Types<TDirectDraw>::TCreatedSurface TSurface;
|
||||
typedef typename Types<TDirectDraw>::TSurfaceDesc TSurfaceDesc;
|
||||
|
||||
static void setCompatVtable(Vtable<TDirectDraw>& vtable);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE CreateSurface(
|
||||
TDirectDraw* This,
|
||||
TSurfaceDesc* lpDDSurfaceDesc,
|
||||
TSurface** lplpDDSurface,
|
||||
IUnknown* pUnkOuter);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE GetDisplayMode(TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc);
|
||||
static HRESULT STDMETHODCALLTYPE RestoreDisplayMode(TDirectDraw* This);
|
||||
static HRESULT STDMETHODCALLTYPE SetCooperativeLevel(TDirectDraw* This, HWND hWnd, DWORD dwFlags);
|
||||
|
||||
template <typename... Params>
|
||||
static HRESULT STDMETHODCALLTYPE SetDisplayMode(
|
||||
TDirectDraw* This,
|
||||
DWORD dwWidth,
|
||||
DWORD dwHeight,
|
||||
DWORD dwBPP,
|
||||
Params... params);
|
||||
};
|
||||
}
|
64
DDrawCompat/DDraw/DirectDrawPalette.cpp
Normal file
64
DDrawCompat/DDraw/DirectDrawPalette.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
#include <cstring>
|
||||
#include <deque>
|
||||
|
||||
#include "Config.h"
|
||||
#include "DDraw/CompatPrimarySurface.h"
|
||||
#include "DDraw/DirectDrawPalette.h"
|
||||
#include "DDraw/RealPrimarySurface.h"
|
||||
#include "Time.h"
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
void DirectDrawPalette::setCompatVtable(IDirectDrawPaletteVtbl& vtable)
|
||||
{
|
||||
vtable.SetEntries = &SetEntries;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawPalette::SetEntries(
|
||||
IDirectDrawPalette* This,
|
||||
DWORD dwFlags,
|
||||
DWORD dwStartingEntry,
|
||||
DWORD dwCount,
|
||||
LPPALETTEENTRY lpEntries)
|
||||
{
|
||||
if (This == CompatPrimarySurface::g_palette)
|
||||
{
|
||||
waitForNextUpdate();
|
||||
if (lpEntries && dwStartingEntry + dwCount <= 256 &&
|
||||
0 == std::memcmp(&CompatPrimarySurface::g_paletteEntries[dwStartingEntry],
|
||||
lpEntries, dwCount * sizeof(PALETTEENTRY)))
|
||||
{
|
||||
return DD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT result = s_origVtable.SetEntries(This, dwFlags, dwStartingEntry, dwCount, lpEntries);
|
||||
if (This == CompatPrimarySurface::g_palette && SUCCEEDED(result))
|
||||
{
|
||||
std::memcpy(&CompatPrimarySurface::g_paletteEntries[dwStartingEntry], lpEntries,
|
||||
dwCount * sizeof(PALETTEENTRY));
|
||||
RealPrimarySurface::updatePalette(dwStartingEntry, dwCount);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DirectDrawPalette::waitForNextUpdate()
|
||||
{
|
||||
static std::deque<long long> updatesInLastMs;
|
||||
|
||||
const long long qpcNow = Time::queryPerformanceCounter();
|
||||
const long long qpcLastMsBegin = qpcNow - Time::g_qpcFrequency / 1000;
|
||||
while (!updatesInLastMs.empty() && qpcLastMsBegin - updatesInLastMs.front() > 0)
|
||||
{
|
||||
updatesInLastMs.pop_front();
|
||||
}
|
||||
|
||||
if (updatesInLastMs.size() >= Config::maxPaletteUpdatesPerMs)
|
||||
{
|
||||
Sleep(1);
|
||||
updatesInLastMs.clear();
|
||||
}
|
||||
|
||||
updatesInLastMs.push_back(Time::queryPerformanceCounter());
|
||||
}
|
||||
}
|
22
DDrawCompat/DDraw/DirectDrawPalette.h
Normal file
22
DDrawCompat/DDraw/DirectDrawPalette.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "CompatVtable.h"
|
||||
#include "DirectDrawPaletteVtblVisitor.h"
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
class DirectDrawPalette : public CompatVtable<DirectDrawPalette, IDirectDrawPalette>
|
||||
{
|
||||
public:
|
||||
static void setCompatVtable(IDirectDrawPaletteVtbl& vtable);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE SetEntries(
|
||||
IDirectDrawPalette* This,
|
||||
DWORD dwFlags,
|
||||
DWORD dwStartingEntry,
|
||||
DWORD dwCount,
|
||||
LPPALETTEENTRY lpEntries);
|
||||
|
||||
static void waitForNextUpdate();
|
||||
};
|
||||
}
|
558
DDrawCompat/DDraw/DirectDrawSurface.cpp
Normal file
558
DDrawCompat/DDraw/DirectDrawSurface.cpp
Normal file
@ -0,0 +1,558 @@
|
||||
#include <set>
|
||||
|
||||
#include "CompatPtr.h"
|
||||
#include "DDraw/CompatPrimarySurface.h"
|
||||
#include "DDraw/DirectDraw.h"
|
||||
#include "DDraw/DirectDrawPalette.h"
|
||||
#include "DDraw/DirectDrawSurface.h"
|
||||
#include "DDraw/DisplayMode.h"
|
||||
#include "DDraw/IReleaseNotifier.h"
|
||||
#include "DDraw/RealPrimarySurface.h"
|
||||
#include "DDraw/Repository.h"
|
||||
#include "DDrawProcs.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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DDSURFACEDESC2 tempSurfaceDesc = desc;
|
||||
tempSurfaceDesc.dwWidth = 1;
|
||||
tempSurfaceDesc.dwHeight = 1;
|
||||
DDraw::Repository::ScopedSurface tempSurface(desc);
|
||||
if (!tempSurface.surface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RECT r = { 0, 0, 1, 1 };
|
||||
surface->Blt(&surface, &r, tempSurface.surface, &r, DDBLT_WAIT, nullptr);
|
||||
}
|
||||
|
||||
HRESULT WINAPI fixSurfacePtrEnumCallback(
|
||||
LPDIRECTDRAWSURFACE7 lpDDSurface,
|
||||
LPDDSURFACEDESC2 lpDDSurfaceDesc,
|
||||
LPVOID lpContext)
|
||||
{
|
||||
auto& visitedSurfaces = *static_cast<std::set<IDirectDrawSurface7*>*>(lpContext);
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> surface(lpDDSurface);
|
||||
if (visitedSurfaces.find(surface) == visitedSurfaces.end())
|
||||
{
|
||||
visitedSurfaces.insert(surface);
|
||||
fixSurfacePtr(*surface, *lpDDSurfaceDesc);
|
||||
surface->EnumAttachedSurfaces(surface, lpContext, &fixSurfacePtrEnumCallback);
|
||||
}
|
||||
|
||||
return DDENUMRET_OK;
|
||||
}
|
||||
|
||||
void fixSurfacePtrs(CompatRef<IDirectDrawSurface7> surface)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
surface->GetSurfaceDesc(&surface, &desc);
|
||||
|
||||
fixSurfacePtr(surface, desc);
|
||||
std::set<IDirectDrawSurface7*> visitedSurfaces{ &surface };
|
||||
surface->EnumAttachedSurfaces(&surface, &visitedSurfaces, &fixSurfacePtrEnumCallback);
|
||||
}
|
||||
|
||||
CompatWeakPtr<IDirectDrawSurface7> getMirroredSurface(
|
||||
CompatRef<IDirectDrawSurface7> surface, RECT* srcRect, DWORD mirrorFx)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
HRESULT result = surface->GetSurfaceDesc(&surface, &desc);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to get surface description for mirroring: " << result);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (srcRect)
|
||||
{
|
||||
desc.dwWidth = srcRect->right - srcRect->left;
|
||||
desc.dwHeight = srcRect->bottom - srcRect->top;
|
||||
}
|
||||
|
||||
DDraw::Repository::ScopedSurface mirroredSurface(desc);
|
||||
if (!mirroredSurface.surface)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RECT rect = { 0, 0, static_cast<LONG>(desc.dwWidth), static_cast<LONG>(desc.dwHeight) };
|
||||
if ((mirrorFx & DDBLTFX_MIRRORLEFTRIGHT) && (mirrorFx & DDBLTFX_MIRRORUPDOWN))
|
||||
{
|
||||
DDraw::Repository::Surface tempMirroredSurface = DDraw::Repository::ScopedSurface(desc);
|
||||
if (!tempMirroredSurface.surface ||
|
||||
!mirrorBlt(*tempMirroredSurface.surface, surface, srcRect ? *srcRect : rect,
|
||||
DDBLTFX_MIRRORLEFTRIGHT) ||
|
||||
!mirrorBlt(*mirroredSurface.surface, *tempMirroredSurface.surface, rect,
|
||||
DDBLTFX_MIRRORUPDOWN))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if (!mirrorBlt(*mirroredSurface.surface, surface, srcRect ? *srcRect : rect, mirrorFx))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return mirroredSurface.surface;
|
||||
}
|
||||
|
||||
bool mirrorBlt(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src,
|
||||
RECT srcRect, DWORD mirrorFx)
|
||||
{
|
||||
if (DDBLTFX_MIRRORLEFTRIGHT == mirrorFx)
|
||||
{
|
||||
LONG width = srcRect.right - srcRect.left;
|
||||
srcRect.left = srcRect.right - 1;
|
||||
for (LONG x = 0; x < width; ++x)
|
||||
{
|
||||
HRESULT result = dst->BltFast(&dst, x, 0, &src, &srcRect, DDBLTFAST_WAIT);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed BltFast for mirroring: " << result);
|
||||
return false;
|
||||
}
|
||||
--srcRect.left;
|
||||
--srcRect.right;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LONG height = srcRect.bottom - srcRect.top;
|
||||
srcRect.top = srcRect.bottom - 1;
|
||||
for (LONG y = 0; y < height; ++y)
|
||||
{
|
||||
HRESULT result = dst->BltFast(&dst, 0, y, &src, &srcRect, DDBLTFAST_WAIT);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed BltFast for mirroring: " << result);
|
||||
return false;
|
||||
}
|
||||
--srcRect.top;
|
||||
--srcRect.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
template <typename TSurface>
|
||||
void DirectDrawSurface<TSurface>::setCompatVtable(Vtable<TSurface>& vtable)
|
||||
{
|
||||
vtable.Blt = &Blt;
|
||||
vtable.BltFast = &BltFast;
|
||||
vtable.Flip = &Flip;
|
||||
vtable.GetCaps = &GetCaps;
|
||||
vtable.GetSurfaceDesc = &GetSurfaceDesc;
|
||||
vtable.IsLost = &IsLost;
|
||||
vtable.Lock = &Lock;
|
||||
vtable.QueryInterface = &QueryInterface;
|
||||
vtable.ReleaseDC = &ReleaseDC;
|
||||
vtable.Restore = &Restore;
|
||||
vtable.SetClipper = &SetClipper;
|
||||
vtable.SetPalette = &SetPalette;
|
||||
vtable.Unlock = &Unlock;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
template <typename TDirectDraw>
|
||||
HRESULT DirectDrawSurface<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 = dd->CreateSurface(&dd, &compatDesc, &compatSurface, nullptr);
|
||||
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>
|
||||
void DirectDrawSurface<TSurface>::fixSurfacePtrs(CompatRef<TSurface> surface)
|
||||
{
|
||||
CompatPtr<IDirectDrawSurface7> surface7(Compat::queryInterface<IDirectDrawSurface7>(&surface));
|
||||
::fixSurfacePtrs(*surface7);
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawSurface<TSurface>::Blt(
|
||||
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;
|
||||
|
||||
if (lpDDSrcSurface && (dwFlags & DDBLT_DDFX) && lpDDBltFx &&
|
||||
(lpDDBltFx->dwDDFX & (DDBLTFX_MIRRORLEFTRIGHT | DDBLTFX_MIRRORUPDOWN)))
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
if (mirroredSrcSurface)
|
||||
{
|
||||
DWORD flags = dwFlags;
|
||||
DDBLTFX fx = *lpDDBltFx;
|
||||
fx.dwDDFX &= ~(DDBLTFX_MIRRORLEFTRIGHT | DDBLTFX_MIRRORUPDOWN);
|
||||
if (0 == fx.dwDDFX)
|
||||
{
|
||||
flags ^= DDBLT_DDFX;
|
||||
}
|
||||
if (flags & DDBLT_KEYSRC)
|
||||
{
|
||||
DDCOLORKEY srcColorKey = {};
|
||||
s_origVtable.GetColorKey(lpDDSrcSurface, DDCKEY_SRCBLT, &srcColorKey);
|
||||
s_origVtable.SetColorKey(mirroredSrcSurface, DDCKEY_SRCBLT, &srcColorKey);
|
||||
}
|
||||
|
||||
if (lpSrcRect)
|
||||
{
|
||||
RECT srcRect = {
|
||||
0, 0, lpSrcRect->right - lpSrcRect->left, lpSrcRect->bottom - lpSrcRect->top };
|
||||
result = s_origVtable.Blt(This, lpDestRect, mirroredSrcSurface, &srcRect, flags, &fx);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = s_origVtable.Blt(This, lpDestRect, mirroredSrcSurface, nullptr, flags, &fx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = s_origVtable.Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
|
||||
}
|
||||
|
||||
if (isPrimaryDest && SUCCEEDED(result))
|
||||
{
|
||||
RealPrimarySurface::invalidate(lpDestRect);
|
||||
RealPrimarySurface::update();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawSurface<TSurface>::GetCaps(
|
||||
TSurface* This,
|
||||
TDdsCaps* lpDDSCaps)
|
||||
{
|
||||
HRESULT result = s_origVtable.GetCaps(This, lpDDSCaps);
|
||||
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
restorePrimaryCaps(*lpDDSCaps);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawSurface<TSurface>::Lock(
|
||||
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)
|
||||
{
|
||||
TSurfaceDesc desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
if (SUCCEEDED(s_origVtable.GetSurfaceDesc(This, &desc)) && !(desc.dwFlags & DDSD_HEIGHT))
|
||||
{
|
||||
// Fixes missing handling for lost vertex buffers in Messiah
|
||||
s_origVtable.Restore(This);
|
||||
// Still, pass back DDERR_SURFACELOST to the application in case it handles it
|
||||
}
|
||||
}
|
||||
|
||||
g_lockingPrimary = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawSurface<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 STDMETHODCALLTYPE DirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawSurface<TSurface>::SetClipper(
|
||||
TSurface* This,
|
||||
LPDIRECTDRAWCLIPPER lpDDClipper)
|
||||
{
|
||||
HRESULT result = s_origVtable.SetClipper(This, lpDDClipper);
|
||||
if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This))
|
||||
{
|
||||
RealPrimarySurface::setClipper(lpDDClipper);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawSurface<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;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE DirectDrawSurface<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 DirectDrawSurface<TSurface>::restorePrimaryCaps(TDdsCaps& caps)
|
||||
{
|
||||
caps.dwCaps &= ~(DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY);
|
||||
caps.dwCaps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
|
||||
}
|
||||
|
||||
template DirectDrawSurface<IDirectDrawSurface>;
|
||||
template DirectDrawSurface<IDirectDrawSurface2>;
|
||||
template DirectDrawSurface<IDirectDrawSurface3>;
|
||||
template DirectDrawSurface<IDirectDrawSurface4>;
|
||||
template DirectDrawSurface<IDirectDrawSurface7>;
|
||||
|
||||
template HRESULT DirectDrawSurface<IDirectDrawSurface>::createCompatPrimarySurface(
|
||||
CompatRef<IDirectDraw> dd,
|
||||
TSurfaceDesc compatDesc,
|
||||
IDirectDrawSurface*& compatSurface);
|
||||
template HRESULT DirectDrawSurface<IDirectDrawSurface>::createCompatPrimarySurface(
|
||||
CompatRef<IDirectDraw2> dd,
|
||||
TSurfaceDesc compatDesc,
|
||||
IDirectDrawSurface*& compatSurface);
|
||||
template HRESULT DirectDrawSurface<IDirectDrawSurface4>::createCompatPrimarySurface(
|
||||
CompatRef<IDirectDraw4> dd,
|
||||
TSurfaceDesc compatDesc,
|
||||
IDirectDrawSurface4*& compatSurface);
|
||||
template HRESULT DirectDrawSurface<IDirectDrawSurface7>::createCompatPrimarySurface(
|
||||
CompatRef<IDirectDraw7> dd,
|
||||
TSurfaceDesc compatDesc,
|
||||
IDirectDrawSurface7*& compatSurface);
|
||||
}
|
70
DDrawCompat/DDraw/DirectDrawSurface.h
Normal file
70
DDrawCompat/DDraw/DirectDrawSurface.h
Normal file
@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include "CompatRef.h"
|
||||
#include "CompatVtable.h"
|
||||
#include "DDraw/Types.h"
|
||||
#include "DirectDrawSurfaceVtblVisitor.h"
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
template <typename TSurface>
|
||||
class DirectDrawSurface : public CompatVtable<DirectDrawSurface<TSurface>, TSurface>
|
||||
{
|
||||
public:
|
||||
typedef typename Types<TSurface>::TSurfaceDesc TSurfaceDesc;
|
||||
typedef typename Types<TSurface>::TDdsCaps TDdsCaps;
|
||||
typedef typename Types<TSurface>::TUnlockParam TUnlockParam;
|
||||
|
||||
static void setCompatVtable(Vtable<TSurface>& vtable);
|
||||
|
||||
template <typename TDirectDraw>
|
||||
static HRESULT createCompatPrimarySurface(
|
||||
CompatRef<TDirectDraw> dd,
|
||||
TSurfaceDesc compatDesc,
|
||||
TSurface*& compatSurface);
|
||||
|
||||
static void fixSurfacePtrs(CompatRef<TSurface> surface);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Blt(
|
||||
TSurface* This,
|
||||
LPRECT lpDestRect,
|
||||
TSurface* lpDDSrcSurface,
|
||||
LPRECT lpSrcRect,
|
||||
DWORD dwFlags,
|
||||
LPDDBLTFX lpDDBltFx);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE BltFast(
|
||||
TSurface* This,
|
||||
DWORD dwX,
|
||||
DWORD dwY,
|
||||
TSurface* lpDDSrcSurface,
|
||||
LPRECT lpSrcRect,
|
||||
DWORD dwTrans);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Flip(
|
||||
TSurface* This,
|
||||
TSurface* lpDDSurfaceTargetOverride,
|
||||
DWORD dwFlags);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE GetCaps(TSurface* This, TDdsCaps* lpDDSCaps);
|
||||
static HRESULT STDMETHODCALLTYPE GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc);
|
||||
static HRESULT STDMETHODCALLTYPE IsLost(TSurface* This);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Lock(
|
||||
TSurface* This,
|
||||
LPRECT lpDestRect,
|
||||
TSurfaceDesc* lpDDSurfaceDesc,
|
||||
DWORD dwFlags,
|
||||
HANDLE hEvent);
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE QueryInterface(TSurface* This, REFIID riid, LPVOID* obp);
|
||||
static HRESULT STDMETHODCALLTYPE ReleaseDC(TSurface* This, HDC hDC);
|
||||
static HRESULT STDMETHODCALLTYPE Restore(TSurface* This);
|
||||
static HRESULT STDMETHODCALLTYPE SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper);
|
||||
static HRESULT STDMETHODCALLTYPE SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette);
|
||||
static HRESULT STDMETHODCALLTYPE Unlock(TSurface* This, TUnlockParam lpRect);
|
||||
|
||||
private:
|
||||
static void restorePrimaryCaps(TDdsCaps& caps);
|
||||
};
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
#include "CompatDisplayMode.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "DDraw/DisplayMode.h"
|
||||
#include "DDraw/Repository.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "DDrawRepository.h"
|
||||
#include "Hook.h"
|
||||
|
||||
namespace
|
||||
@ -75,7 +75,7 @@ namespace
|
||||
desc.ddpfPixelFormat = g_emulatedDisplayMode.ddpfPixelFormat;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
|
||||
auto dd = DDrawRepository::getDirectDraw();
|
||||
auto dd = DDraw::Repository::getDirectDraw();
|
||||
CompatPtr<IDirectDrawSurface7> surface;
|
||||
dd->CreateSurface(dd, &desc, &surface.getRef(), nullptr);
|
||||
return surface;
|
||||
@ -170,74 +170,77 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
namespace CompatDisplayMode
|
||||
namespace DDraw
|
||||
{
|
||||
HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy)
|
||||
namespace DisplayMode
|
||||
{
|
||||
replaceDc(hdc);
|
||||
return CALL_ORIG_FUNC(CreateCompatibleBitmap)(hdc, cx, cy);
|
||||
}
|
||||
|
||||
HBITMAP WINAPI createDIBitmap(HDC hdc, const BITMAPINFOHEADER* lpbmih, DWORD fdwInit,
|
||||
const void* lpbInit, const BITMAPINFO* lpbmi, UINT fuUsage)
|
||||
{
|
||||
replaceDc(hdc);
|
||||
return CALL_ORIG_FUNC(CreateDIBitmap)(hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage);
|
||||
}
|
||||
|
||||
HBITMAP WINAPI createDiscardableBitmap(HDC hdc, int nWidth, int nHeight)
|
||||
{
|
||||
replaceDc(hdc);
|
||||
return CALL_ORIG_FUNC(createDiscardableBitmap)(hdc, nWidth, nHeight);
|
||||
}
|
||||
|
||||
DDSURFACEDESC2 getDisplayMode(CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
if (0 == g_emulatedDisplayMode.dwSize)
|
||||
HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy)
|
||||
{
|
||||
g_emulatedDisplayMode = getRealDisplayMode(dd);
|
||||
}
|
||||
return g_emulatedDisplayMode;
|
||||
}
|
||||
|
||||
void installHooks()
|
||||
{
|
||||
HOOK_FUNCTION(user32, ChangeDisplaySettingsExA, changeDisplaySettingsExA);
|
||||
HOOK_FUNCTION(user32, ChangeDisplaySettingsExW, changeDisplaySettingsExW);
|
||||
}
|
||||
|
||||
HRESULT restoreDisplayMode(CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
const HRESULT result = dd->RestoreDisplayMode(&dd);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
ZeroMemory(&g_emulatedDisplayMode, sizeof(g_emulatedDisplayMode));
|
||||
releaseCompatibleDc();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT setDisplayMode(CompatRef<IDirectDraw7> dd,
|
||||
DWORD width, DWORD height, DWORD bpp, DWORD refreshRate, DWORD flags)
|
||||
{
|
||||
DDPIXELFORMAT pf = getDisplayModePixelFormat(dd, width, height, bpp);
|
||||
if (0 == pf.dwSize)
|
||||
{
|
||||
return DDERR_INVALIDMODE;
|
||||
replaceDc(hdc);
|
||||
return CALL_ORIG_FUNC(CreateCompatibleBitmap)(hdc, cx, cy);
|
||||
}
|
||||
|
||||
const HRESULT result = dd->SetDisplayMode(&dd, width, height, 32, refreshRate, flags);
|
||||
if (FAILED(result))
|
||||
HBITMAP WINAPI createDIBitmap(HDC hdc, const BITMAPINFOHEADER* lpbmih, DWORD fdwInit,
|
||||
const void* lpbInit, const BITMAPINFO* lpbmi, UINT fuUsage)
|
||||
{
|
||||
Compat::Log() << "Failed to set the display mode to " << width << "x" << height <<
|
||||
"x" << bpp << " (" << std::hex << result << std::dec << ')';
|
||||
replaceDc(hdc);
|
||||
return CALL_ORIG_FUNC(CreateDIBitmap)(hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage);
|
||||
}
|
||||
|
||||
HBITMAP WINAPI createDiscardableBitmap(HDC hdc, int nWidth, int nHeight)
|
||||
{
|
||||
replaceDc(hdc);
|
||||
return CALL_ORIG_FUNC(createDiscardableBitmap)(hdc, nWidth, nHeight);
|
||||
}
|
||||
|
||||
DDSURFACEDESC2 getDisplayMode(CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
if (0 == g_emulatedDisplayMode.dwSize)
|
||||
{
|
||||
g_emulatedDisplayMode = getRealDisplayMode(dd);
|
||||
}
|
||||
return g_emulatedDisplayMode;
|
||||
}
|
||||
|
||||
void installHooks()
|
||||
{
|
||||
HOOK_FUNCTION(user32, ChangeDisplaySettingsExA, changeDisplaySettingsExA);
|
||||
HOOK_FUNCTION(user32, ChangeDisplaySettingsExW, changeDisplaySettingsExW);
|
||||
}
|
||||
|
||||
HRESULT restoreDisplayMode(CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
const HRESULT result = dd->RestoreDisplayMode(&dd);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
ZeroMemory(&g_emulatedDisplayMode, sizeof(g_emulatedDisplayMode));
|
||||
releaseCompatibleDc();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
g_emulatedDisplayMode = getRealDisplayMode(dd);
|
||||
g_emulatedDisplayMode.ddpfPixelFormat = pf;
|
||||
updateCompatibleDc();
|
||||
HRESULT setDisplayMode(CompatRef<IDirectDraw7> dd,
|
||||
DWORD width, DWORD height, DWORD bpp, DWORD refreshRate, DWORD flags)
|
||||
{
|
||||
DDPIXELFORMAT pf = getDisplayModePixelFormat(dd, width, height, bpp);
|
||||
if (0 == pf.dwSize)
|
||||
{
|
||||
return DDERR_INVALIDMODE;
|
||||
}
|
||||
|
||||
return DD_OK;
|
||||
const HRESULT result = dd->SetDisplayMode(&dd, width, height, 32, refreshRate, flags);
|
||||
if (FAILED(result))
|
||||
{
|
||||
Compat::Log() << "Failed to set the display mode to " << width << "x" << height <<
|
||||
"x" << bpp << " (" << std::hex << result << std::dec << ')';
|
||||
return result;
|
||||
}
|
||||
|
||||
g_emulatedDisplayMode = getRealDisplayMode(dd);
|
||||
g_emulatedDisplayMode.ddpfPixelFormat = pf;
|
||||
updateCompatibleDc();
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
}
|
||||
}
|
25
DDrawCompat/DDraw/DisplayMode.h
Normal file
25
DDrawCompat/DDraw/DisplayMode.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatRef.h"
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
namespace DisplayMode
|
||||
{
|
||||
void installHooks();
|
||||
|
||||
HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy);
|
||||
HBITMAP WINAPI createDIBitmap(HDC hdc, const BITMAPINFOHEADER* lpbmih, DWORD fdwInit,
|
||||
const void* lpbInit, const BITMAPINFO* lpbmi, UINT fuUsage);
|
||||
HBITMAP WINAPI createDiscardableBitmap(HDC hdc, int nWidth, int nHeight);
|
||||
|
||||
DDSURFACEDESC2 getDisplayMode(CompatRef<IDirectDraw7> dd);
|
||||
HRESULT restoreDisplayMode(CompatRef<IDirectDraw7> dd);
|
||||
HRESULT setDisplayMode(CompatRef<IDirectDraw7> dd,
|
||||
DWORD width, DWORD height, DWORD bpp, DWORD refreshRate = 0, DWORD flags = 0);
|
||||
};
|
||||
}
|
@ -2,19 +2,19 @@
|
||||
|
||||
#include <d3d.h>
|
||||
|
||||
#include "CompatActivateAppHandler.h"
|
||||
#include "CompatDirect3d.h"
|
||||
#include "CompatDirect3dDevice.h"
|
||||
#include "CompatDirectDraw.h"
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatDirectDrawPalette.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "CompatRef.h"
|
||||
#include "DDrawHooks.h"
|
||||
#include "DDraw/ActivateAppHandler.h"
|
||||
#include "DDraw/DirectDraw.h"
|
||||
#include "DDraw/DirectDrawSurface.h"
|
||||
#include "DDraw/DirectDrawPalette.h"
|
||||
#include "DDraw/Hooks.h"
|
||||
#include "DDraw/RealPrimarySurface.h"
|
||||
#include "DDraw/Repository.h"
|
||||
#include "DDrawLog.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "DDrawRepository.h"
|
||||
#include "RealPrimarySurface.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -118,12 +118,12 @@ namespace
|
||||
|
||||
void hookDirectDraw(CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
CompatDirectDraw<IDirectDraw7>::s_origVtable = *(&dd)->lpVtbl;
|
||||
DDraw::DirectDraw<IDirectDraw7>::s_origVtable = *(&dd)->lpVtbl;
|
||||
CompatPtr<IDirectDraw7> dd7(&dd);
|
||||
hookVtable<CompatDirectDraw<IDirectDraw>>(dd7);
|
||||
hookVtable<CompatDirectDraw<IDirectDraw2>>(dd7);
|
||||
hookVtable<CompatDirectDraw<IDirectDraw4>>(dd7);
|
||||
hookVtable<CompatDirectDraw<IDirectDraw7>>(dd7);
|
||||
hookVtable<DDraw::DirectDraw<IDirectDraw>>(dd7);
|
||||
hookVtable<DDraw::DirectDraw<IDirectDraw2>>(dd7);
|
||||
hookVtable<DDraw::DirectDraw<IDirectDraw4>>(dd7);
|
||||
hookVtable<DDraw::DirectDraw<IDirectDraw7>>(dd7);
|
||||
dd7.detach();
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ namespace
|
||||
DDPCAPS_1BIT, paletteEntries, &palette.getRef(), nullptr);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
CompatDirectDrawPalette::hookVtable(palette.get()->lpVtbl);
|
||||
DDraw::DirectDrawPalette::hookVtable(palette.get()->lpVtbl);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -156,12 +156,12 @@ namespace
|
||||
HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
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);
|
||||
DDraw::DirectDrawSurface<IDirectDrawSurface7>::s_origVtable = *surface.get()->lpVtbl;
|
||||
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface>>(surface);
|
||||
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface2>>(surface);
|
||||
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface3>>(surface);
|
||||
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface4>>(surface);
|
||||
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface7>>(surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -176,7 +176,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
namespace DDrawHooks
|
||||
namespace DDraw
|
||||
{
|
||||
void installHooks()
|
||||
{
|
||||
@ -195,7 +195,7 @@ namespace DDrawHooks
|
||||
return;
|
||||
}
|
||||
|
||||
auto dd7(DDrawRepository::getDirectDraw());
|
||||
auto dd7(Repository::getDirectDraw());
|
||||
if (!dd7)
|
||||
{
|
||||
Compat::Log() << "Failed to create a DirectDraw7 object for hooking";
|
||||
@ -214,12 +214,12 @@ namespace DDrawHooks
|
||||
hookDirect3d7(*dd7, *renderTarget7);
|
||||
}
|
||||
|
||||
CompatActivateAppHandler::installHooks();
|
||||
ActivateAppHandler::installHooks();
|
||||
}
|
||||
|
||||
void uninstallHooks()
|
||||
{
|
||||
RealPrimarySurface::removeUpdateThread();
|
||||
CompatActivateAppHandler::uninstallHooks();
|
||||
ActivateAppHandler::uninstallHooks();
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace DDrawHooks
|
||||
namespace DDraw
|
||||
{
|
||||
void installHooks();
|
||||
void uninstallHooks();
|
@ -1,4 +1,4 @@
|
||||
#include "IReleaseNotifier.h"
|
||||
#include "DDraw/IReleaseNotifier.h"
|
||||
|
||||
#include <initguid.h>
|
||||
|
40
DDrawCompat/DDraw/IReleaseNotifier.h
Normal file
40
DDrawCompat/DDraw/IReleaseNotifier.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <Unknwnbase.h>
|
||||
|
||||
// {7810158A-CB51-448A-8706-443A7DF6D4ED}
|
||||
DEFINE_GUID(IID_IReleaseNotifier,
|
||||
0x7810158a, 0xcb51, 0x448a, 0x87, 0x6, 0x44, 0x3a, 0x7d, 0xf6, 0xd4, 0xed);
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
class IReleaseNotifier
|
||||
{
|
||||
public:
|
||||
IReleaseNotifier(const std::function<void()>& notifyHandler)
|
||||
: m_notifyHandler(notifyHandler)
|
||||
{
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID*)
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
virtual ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
m_notifyHandler();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void()> m_notifyHandler;
|
||||
};
|
||||
}
|
164
DDrawCompat/DDraw/PaletteConverter.cpp
Normal file
164
DDrawCompat/DDraw/PaletteConverter.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#include "CompatPtr.h"
|
||||
#include "DDraw/CompatPrimarySurface.h"
|
||||
#include "DDraw/DisplayMode.h"
|
||||
#include "DDraw/PaletteConverter.h"
|
||||
#include "DDraw/RealPrimarySurface.h"
|
||||
#include "DDraw/Repository.h"
|
||||
#include "DDraw/Types.h"
|
||||
#include "Hook.h"
|
||||
#include "ScopedCriticalSection.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
HDC g_dc = nullptr;
|
||||
HGDIOBJ g_oldBitmap = nullptr;
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_surface;
|
||||
|
||||
void convertPaletteEntriesToRgbQuad(RGBQUAD* entries, DWORD count)
|
||||
{
|
||||
for (DWORD i = 0; i < count; ++i)
|
||||
{
|
||||
entries[i].rgbReserved = 0;
|
||||
std::swap(entries[i].rgbRed, entries[i].rgbBlue);
|
||||
}
|
||||
}
|
||||
|
||||
HBITMAP createDibSection(const DDSURFACEDESC2& dm, void*& bits)
|
||||
{
|
||||
struct PalettizedBitmapInfo
|
||||
{
|
||||
BITMAPINFOHEADER header;
|
||||
PALETTEENTRY colors[256];
|
||||
};
|
||||
|
||||
PalettizedBitmapInfo bmi = {};
|
||||
bmi.header.biSize = sizeof(bmi.header);
|
||||
bmi.header.biWidth = dm.dwWidth;
|
||||
bmi.header.biHeight = -static_cast<LONG>(dm.dwHeight);
|
||||
bmi.header.biPlanes = 1;
|
||||
bmi.header.biBitCount = static_cast<WORD>(dm.ddpfPixelFormat.dwRGBBitCount);
|
||||
bmi.header.biCompression = BI_RGB;
|
||||
|
||||
return CreateDIBSection(nullptr, reinterpret_cast<BITMAPINFO*>(&bmi),
|
||||
DIB_RGB_COLORS, &bits, nullptr, 0);
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> createSurface(const DDSURFACEDESC2& dm, void* bits)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS |
|
||||
DDSD_PITCH | DDSD_LPSURFACE;
|
||||
desc.dwWidth = dm.dwWidth;
|
||||
desc.dwHeight = dm.dwHeight;
|
||||
desc.ddpfPixelFormat = dm.ddpfPixelFormat;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
desc.lPitch = (dm.dwWidth * dm.ddpfPixelFormat.dwRGBBitCount / 8 + 3) & ~3;
|
||||
desc.lpSurface = bits;
|
||||
|
||||
auto dd(DDraw::Repository::getDirectDraw());
|
||||
CompatPtr<IDirectDrawSurface7> surface;
|
||||
dd->CreateSurface(dd, &desc, &surface.getRef(), nullptr);
|
||||
return surface;
|
||||
}
|
||||
}
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
namespace PaletteConverter
|
||||
{
|
||||
bool create()
|
||||
{
|
||||
auto dd(Repository::getDirectDraw());
|
||||
auto dm(DisplayMode::getDisplayMode(*dd));
|
||||
DDSURFACEDESC2 realDm = {};
|
||||
realDm.dwSize = sizeof(realDm);
|
||||
dd->GetDisplayMode(dd, &realDm);
|
||||
if (dm.ddpfPixelFormat.dwRGBBitCount > 8 &&
|
||||
realDm.ddpfPixelFormat.dwRGBBitCount > 8)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void* bits = nullptr;
|
||||
HBITMAP dib = createDibSection(dm, bits);
|
||||
if (!dib)
|
||||
{
|
||||
Compat::Log() << "Failed to create the palette converter DIB section";
|
||||
return false;
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> surface(createSurface(dm, bits));
|
||||
if (!surface)
|
||||
{
|
||||
Compat::Log() << "Failed to create the palette converter surface";
|
||||
DeleteObject(dib);
|
||||
return false;
|
||||
}
|
||||
|
||||
HDC dc = CALL_ORIG_FUNC(CreateCompatibleDC)(nullptr);
|
||||
if (!dc)
|
||||
{
|
||||
Compat::Log() << "Failed to create the palette converter DC";
|
||||
DeleteObject(dib);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_oldBitmap = SelectObject(dc, dib);
|
||||
g_dc = dc;
|
||||
g_surface = surface.detach();
|
||||
return true;
|
||||
}
|
||||
|
||||
HDC getDc()
|
||||
{
|
||||
return g_dc;
|
||||
}
|
||||
|
||||
CompatWeakPtr<IDirectDrawSurface7> getSurface()
|
||||
{
|
||||
return g_surface;
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
if (!g_surface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_surface.release();
|
||||
|
||||
DeleteObject(SelectObject(g_dc, g_oldBitmap));
|
||||
DeleteDC(g_dc);
|
||||
g_dc = nullptr;
|
||||
}
|
||||
|
||||
void setClipper(CompatWeakPtr<IDirectDrawClipper> clipper)
|
||||
{
|
||||
if (g_surface)
|
||||
{
|
||||
HRESULT result = g_surface->SetClipper(g_surface, clipper);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to set a clipper on the palette converter surface: " << result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updatePalette(DWORD startingEntry, DWORD count)
|
||||
{
|
||||
if (g_dc && CompatPrimarySurface::g_palette)
|
||||
{
|
||||
RGBQUAD entries[256] = {};
|
||||
std::memcpy(entries, &CompatPrimarySurface::g_paletteEntries[startingEntry],
|
||||
count * sizeof(PALETTEENTRY));
|
||||
convertPaletteEntriesToRgbQuad(entries, count);
|
||||
SetDIBColorTable(g_dc, startingEntry, count, entries);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
20
DDrawCompat/DDraw/PaletteConverter.h
Normal file
20
DDrawCompat/DDraw/PaletteConverter.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatWeakPtr.h"
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
namespace PaletteConverter
|
||||
{
|
||||
bool create();
|
||||
HDC getDc();
|
||||
CompatWeakPtr<IDirectDrawSurface7> getSurface();
|
||||
void release();
|
||||
void setClipper(CompatWeakPtr<IDirectDrawClipper> clipper);
|
||||
void updatePalette(DWORD startingEntry, DWORD count);
|
||||
}
|
||||
}
|
@ -1,17 +1,17 @@
|
||||
#include <atomic>
|
||||
|
||||
#include "CompatDirectDrawSurface.h"
|
||||
#include "CompatPaletteConverter.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "Config.h"
|
||||
#include "DDrawScopedThreadLock.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/Types.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "DDrawTypes.h"
|
||||
#include "Gdi/Gdi.h"
|
||||
#include "Hook.h"
|
||||
#include "IReleaseNotifier.h"
|
||||
#include "RealPrimarySurface.h"
|
||||
#include "Time.h"
|
||||
|
||||
namespace
|
||||
@ -24,7 +24,7 @@ namespace
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_backBuffer;
|
||||
CompatWeakPtr<IDirectDrawClipper> g_clipper;
|
||||
DDSURFACEDESC2 g_surfaceDesc = {};
|
||||
IReleaseNotifier g_releaseNotifier(onRelease);
|
||||
DDraw::IReleaseNotifier g_releaseNotifier(onRelease);
|
||||
|
||||
bool g_stopUpdateThread = false;
|
||||
HANDLE g_updateThread = nullptr;
|
||||
@ -47,10 +47,10 @@ namespace
|
||||
|
||||
bool result = false;
|
||||
|
||||
auto primary(CompatPrimarySurface::getPrimary());
|
||||
if (CompatPrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount <= 8)
|
||||
auto primary(DDraw::CompatPrimarySurface::getPrimary());
|
||||
if (DDraw::CompatPrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount <= 8)
|
||||
{
|
||||
auto paletteConverter(CompatPaletteConverter::getSurface());
|
||||
auto paletteConverter(DDraw::PaletteConverter::getSurface());
|
||||
paletteConverter->Blt(paletteConverter, &g_updateRect,
|
||||
primary, &g_updateRect, DDBLT_WAIT, nullptr);
|
||||
|
||||
@ -58,7 +58,7 @@ namespace
|
||||
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);
|
||||
DDraw::PaletteConverter::getDc(), g_updateRect.left, g_updateRect.top, SRCCOPY);
|
||||
dest->ReleaseDC(&dest, destDc);
|
||||
|
||||
if (&dest == g_frontBuffer)
|
||||
@ -92,7 +92,7 @@ namespace
|
||||
|
||||
HRESULT init(CompatPtr<IDirectDrawSurface7> surface)
|
||||
{
|
||||
if (!CompatPaletteConverter::create())
|
||||
if (!DDraw::PaletteConverter::create())
|
||||
{
|
||||
return DDERR_GENERIC;
|
||||
}
|
||||
@ -153,7 +153,7 @@ namespace
|
||||
g_backBuffer.release();
|
||||
g_clipper = nullptr;
|
||||
g_isFullScreen = false;
|
||||
CompatPaletteConverter::release();
|
||||
DDraw::PaletteConverter::release();
|
||||
|
||||
ZeroMemory(&g_surfaceDesc, sizeof(g_surfaceDesc));
|
||||
|
||||
@ -194,7 +194,7 @@ namespace
|
||||
Sleep(msUntilNextUpdate);
|
||||
}
|
||||
|
||||
Compat::DDrawScopedThreadLock lock;
|
||||
DDraw::ScopedThreadLock lock;
|
||||
const long long qpcNow = Time::queryPerformanceCounter();
|
||||
const bool isTargetUpdateStillNeeded = qpcTargetNextUpdate == g_qpcNextUpdate;
|
||||
if (g_frontBuffer && (isTargetUpdateStillNeeded || isNextUpdateSignaledAndReady(qpcNow)))
|
||||
@ -205,180 +205,183 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DirectDraw>
|
||||
HRESULT RealPrimarySurface::create(CompatRef<DirectDraw> dd)
|
||||
namespace DDraw
|
||||
{
|
||||
typename Types<DirectDraw>::TSurfaceDesc desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
|
||||
desc.dwBackBufferCount = 2;
|
||||
|
||||
CompatPtr<typename Types<DirectDraw>::TCreatedSurface> surface;
|
||||
HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);
|
||||
|
||||
bool isFlippable = true;
|
||||
if (DDERR_NOEXCLUSIVEMODE == result)
|
||||
template <typename DirectDraw>
|
||||
HRESULT RealPrimarySurface::create(CompatRef<DirectDraw> dd)
|
||||
{
|
||||
desc.dwFlags = DDSD_CAPS;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
desc.dwBackBufferCount = 0;
|
||||
isFlippable = false;
|
||||
result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);
|
||||
typename Types<DirectDraw>::TSurfaceDesc desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
|
||||
desc.dwBackBufferCount = 2;
|
||||
|
||||
CompatPtr<typename Types<DirectDraw>::TCreatedSurface> surface;
|
||||
HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);
|
||||
|
||||
bool isFlippable = true;
|
||||
if (DDERR_NOEXCLUSIVEMODE == result)
|
||||
{
|
||||
desc.dwFlags = DDSD_CAPS;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
desc.dwBackBufferCount = 0;
|
||||
isFlippable = false;
|
||||
result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);
|
||||
}
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
Compat::Log() << "Failed to create the real primary surface";
|
||||
return result;
|
||||
}
|
||||
|
||||
return init(surface);
|
||||
}
|
||||
|
||||
if (FAILED(result))
|
||||
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw>);
|
||||
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw2>);
|
||||
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw4>);
|
||||
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw7>);
|
||||
|
||||
void RealPrimarySurface::disableUpdates()
|
||||
{
|
||||
Compat::Log() << "Failed to create the real primary surface";
|
||||
++g_disableUpdateCount;
|
||||
ResetEvent(g_updateEvent);
|
||||
}
|
||||
|
||||
void RealPrimarySurface::enableUpdates()
|
||||
{
|
||||
if (0 == --g_disableUpdateCount)
|
||||
{
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT RealPrimarySurface::flip(DWORD flags)
|
||||
{
|
||||
if (!g_isFullScreen)
|
||||
{
|
||||
return DDERR_NOTFLIPPABLE;
|
||||
}
|
||||
|
||||
ResetEvent(g_updateEvent);
|
||||
|
||||
invalidate(nullptr);
|
||||
compatBlt(*g_backBuffer);
|
||||
|
||||
HRESULT result = g_frontBuffer->Flip(g_frontBuffer, nullptr, flags);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
g_qpcNextUpdate = getNextUpdateQpc(
|
||||
Time::queryPerformanceCounter() + Time::msToQpc(Config::primaryUpdateDelayAfterFlip));
|
||||
SetRectEmpty(&g_updateRect);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return init(surface);
|
||||
}
|
||||
|
||||
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw>);
|
||||
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw2>);
|
||||
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw4>);
|
||||
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw7>);
|
||||
|
||||
void RealPrimarySurface::disableUpdates()
|
||||
{
|
||||
++g_disableUpdateCount;
|
||||
ResetEvent(g_updateEvent);
|
||||
}
|
||||
|
||||
void RealPrimarySurface::enableUpdates()
|
||||
{
|
||||
if (0 == --g_disableUpdateCount)
|
||||
CompatWeakPtr<IDirectDrawSurface7> RealPrimarySurface::getSurface()
|
||||
{
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT RealPrimarySurface::flip(DWORD flags)
|
||||
{
|
||||
if (!g_isFullScreen)
|
||||
{
|
||||
return DDERR_NOTFLIPPABLE;
|
||||
return g_frontBuffer;
|
||||
}
|
||||
|
||||
ResetEvent(g_updateEvent);
|
||||
|
||||
invalidate(nullptr);
|
||||
compatBlt(*g_backBuffer);
|
||||
|
||||
HRESULT result = g_frontBuffer->Flip(g_frontBuffer, nullptr, flags);
|
||||
if (SUCCEEDED(result))
|
||||
void RealPrimarySurface::invalidate(const RECT* rect)
|
||||
{
|
||||
g_qpcNextUpdate = getNextUpdateQpc(
|
||||
Time::queryPerformanceCounter() + Time::msToQpc(Config::primaryUpdateDelayAfterFlip));
|
||||
SetRectEmpty(&g_updateRect);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CompatWeakPtr<IDirectDrawSurface7> RealPrimarySurface::getSurface()
|
||||
{
|
||||
return g_frontBuffer;
|
||||
}
|
||||
|
||||
void RealPrimarySurface::invalidate(const RECT* rect)
|
||||
{
|
||||
if (rect)
|
||||
{
|
||||
UnionRect(&g_updateRect, &g_updateRect, rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto primaryDesc = CompatPrimarySurface::getDesc();
|
||||
SetRect(&g_updateRect, 0, 0, primaryDesc.dwWidth, primaryDesc.dwHeight);
|
||||
}
|
||||
}
|
||||
|
||||
bool RealPrimarySurface::isFullScreen()
|
||||
{
|
||||
return g_isFullScreen;
|
||||
}
|
||||
|
||||
bool RealPrimarySurface::isLost()
|
||||
{
|
||||
return g_frontBuffer && DDERR_SURFACELOST == g_frontBuffer->IsLost(g_frontBuffer);
|
||||
}
|
||||
|
||||
void RealPrimarySurface::release()
|
||||
{
|
||||
g_frontBuffer.release();
|
||||
}
|
||||
|
||||
void RealPrimarySurface::removeUpdateThread()
|
||||
{
|
||||
if (!g_updateThread)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_stopUpdateThread = true;
|
||||
SetEvent(g_updateEvent);
|
||||
if (WAIT_OBJECT_0 != WaitForSingleObject(g_updateThread, 1000))
|
||||
{
|
||||
TerminateThread(g_updateThread, 0);
|
||||
Compat::Log() << "The update thread was terminated forcefully";
|
||||
}
|
||||
ResetEvent(g_updateEvent);
|
||||
g_stopUpdateThread = false;
|
||||
g_updateThread = nullptr;
|
||||
}
|
||||
|
||||
HRESULT RealPrimarySurface::restore()
|
||||
{
|
||||
return g_frontBuffer->Restore(g_frontBuffer);
|
||||
}
|
||||
|
||||
void RealPrimarySurface::setClipper(CompatWeakPtr<IDirectDrawClipper> clipper)
|
||||
{
|
||||
HRESULT result = g_frontBuffer->SetClipper(g_frontBuffer, clipper);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to set clipper on the real primary surface: " << result);
|
||||
return;
|
||||
}
|
||||
CompatPaletteConverter::setClipper(clipper);
|
||||
g_clipper = clipper;
|
||||
}
|
||||
|
||||
void RealPrimarySurface::setPalette()
|
||||
{
|
||||
if (g_surfaceDesc.ddpfPixelFormat.dwRGBBitCount <= 8)
|
||||
{
|
||||
g_frontBuffer->SetPalette(g_frontBuffer, CompatPrimarySurface::g_palette);
|
||||
}
|
||||
|
||||
updatePalette(0, 256);
|
||||
}
|
||||
|
||||
void RealPrimarySurface::update()
|
||||
{
|
||||
if (!IsRectEmpty(&g_updateRect) && 0 == g_disableUpdateCount && (g_isFullScreen || g_clipper))
|
||||
{
|
||||
const long long qpcNow = Time::queryPerformanceCounter();
|
||||
if (Time::qpcToMs(qpcNow - g_qpcNextUpdate) >= 0)
|
||||
if (rect)
|
||||
{
|
||||
updateNow(qpcNow);
|
||||
UnionRect(&g_updateRect, &g_updateRect, rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetEvent(g_updateEvent);
|
||||
auto primaryDesc = CompatPrimarySurface::getDesc();
|
||||
SetRect(&g_updateRect, 0, 0, primaryDesc.dwWidth, primaryDesc.dwHeight);
|
||||
}
|
||||
}
|
||||
|
||||
bool RealPrimarySurface::isFullScreen()
|
||||
{
|
||||
return g_isFullScreen;
|
||||
}
|
||||
|
||||
bool RealPrimarySurface::isLost()
|
||||
{
|
||||
return g_frontBuffer && DDERR_SURFACELOST == g_frontBuffer->IsLost(g_frontBuffer);
|
||||
}
|
||||
|
||||
void RealPrimarySurface::release()
|
||||
{
|
||||
g_frontBuffer.release();
|
||||
}
|
||||
|
||||
void RealPrimarySurface::removeUpdateThread()
|
||||
{
|
||||
if (!g_updateThread)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_stopUpdateThread = true;
|
||||
SetEvent(g_updateEvent);
|
||||
if (WAIT_OBJECT_0 != WaitForSingleObject(g_updateThread, 1000))
|
||||
{
|
||||
TerminateThread(g_updateThread, 0);
|
||||
Compat::Log() << "The update thread was terminated forcefully";
|
||||
}
|
||||
ResetEvent(g_updateEvent);
|
||||
g_stopUpdateThread = false;
|
||||
g_updateThread = nullptr;
|
||||
}
|
||||
|
||||
HRESULT RealPrimarySurface::restore()
|
||||
{
|
||||
return g_frontBuffer->Restore(g_frontBuffer);
|
||||
}
|
||||
|
||||
void RealPrimarySurface::setClipper(CompatWeakPtr<IDirectDrawClipper> clipper)
|
||||
{
|
||||
HRESULT result = g_frontBuffer->SetClipper(g_frontBuffer, clipper);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to set clipper on the real primary surface: " << result);
|
||||
return;
|
||||
}
|
||||
PaletteConverter::setClipper(clipper);
|
||||
g_clipper = clipper;
|
||||
}
|
||||
|
||||
void RealPrimarySurface::setPalette()
|
||||
{
|
||||
if (g_surfaceDesc.ddpfPixelFormat.dwRGBBitCount <= 8)
|
||||
{
|
||||
g_frontBuffer->SetPalette(g_frontBuffer, CompatPrimarySurface::g_palette);
|
||||
}
|
||||
|
||||
updatePalette(0, 256);
|
||||
}
|
||||
|
||||
void RealPrimarySurface::update()
|
||||
{
|
||||
if (!IsRectEmpty(&g_updateRect) && 0 == g_disableUpdateCount && (g_isFullScreen || g_clipper))
|
||||
{
|
||||
const long long qpcNow = Time::queryPerformanceCounter();
|
||||
if (Time::qpcToMs(qpcNow - g_qpcNextUpdate) >= 0)
|
||||
{
|
||||
updateNow(qpcNow);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetEvent(g_updateEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RealPrimarySurface::updatePalette(DWORD startingEntry, DWORD count)
|
||||
{
|
||||
PaletteConverter::updatePalette(startingEntry, count);
|
||||
Gdi::updatePalette(startingEntry, count);
|
||||
if (CompatPrimarySurface::g_palette)
|
||||
{
|
||||
invalidate(nullptr);
|
||||
update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RealPrimarySurface::updatePalette(DWORD startingEntry, DWORD count)
|
||||
{
|
||||
CompatPaletteConverter::updatePalette(startingEntry, count);
|
||||
Gdi::updatePalette(startingEntry, count);
|
||||
if (CompatPrimarySurface::g_palette)
|
||||
{
|
||||
invalidate(nullptr);
|
||||
update();
|
||||
}
|
||||
}
|
33
DDrawCompat/DDraw/RealPrimarySurface.h
Normal file
33
DDrawCompat/DDraw/RealPrimarySurface.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatWeakPtr.h"
|
||||
#include "CompatRef.h"
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
class RealPrimarySurface
|
||||
{
|
||||
public:
|
||||
template <typename DirectDraw>
|
||||
static HRESULT create(CompatRef<DirectDraw> dd);
|
||||
|
||||
static void disableUpdates();
|
||||
static void enableUpdates();
|
||||
static HRESULT flip(DWORD flags);
|
||||
static CompatWeakPtr<IDirectDrawSurface7> getSurface();
|
||||
static void invalidate(const RECT* rect);
|
||||
static bool isFullScreen();
|
||||
static bool isLost();
|
||||
static void release();
|
||||
static void removeUpdateThread();
|
||||
static HRESULT restore();
|
||||
static void setClipper(CompatWeakPtr<IDirectDrawClipper> clipper);
|
||||
static void setPalette();
|
||||
static void update();
|
||||
static void updatePalette(DWORD startingEntry, DWORD count);
|
||||
};
|
||||
}
|
@ -2,13 +2,13 @@
|
||||
#include <vector>
|
||||
|
||||
#include "CompatPtr.h"
|
||||
#include "DDraw/Repository.h"
|
||||
#include "DDrawLog.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "DDrawRepository.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
using DDrawRepository::Surface;
|
||||
using DDraw::Repository::Surface;
|
||||
|
||||
static std::vector<Surface> g_sysMemSurfaces;
|
||||
static std::vector<Surface> g_vidMemSurfaces;
|
||||
@ -55,7 +55,7 @@ namespace
|
||||
surface.desc.ddpfPixelFormat = pf;
|
||||
surface.desc.ddsCaps.dwCaps = caps;
|
||||
|
||||
auto dd(DDrawRepository::getDirectDraw());
|
||||
auto dd(DDraw::Repository::getDirectDraw());
|
||||
dd->CreateSurface(dd, &surface.desc, &surface.surface.getRef(), nullptr);
|
||||
return surface;
|
||||
}
|
||||
@ -158,21 +158,24 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
namespace DDrawRepository
|
||||
namespace DDraw
|
||||
{
|
||||
ScopedSurface::ScopedSurface(const DDSURFACEDESC2& desc)
|
||||
: Surface(getSurface(desc))
|
||||
namespace Repository
|
||||
{
|
||||
}
|
||||
ScopedSurface::ScopedSurface(const DDSURFACEDESC2& desc)
|
||||
: Surface(getSurface(desc))
|
||||
{
|
||||
}
|
||||
|
||||
ScopedSurface::~ScopedSurface()
|
||||
{
|
||||
returnSurface(*this);
|
||||
}
|
||||
ScopedSurface::~ScopedSurface()
|
||||
{
|
||||
returnSurface(*this);
|
||||
}
|
||||
|
||||
CompatWeakPtr<IDirectDraw7> getDirectDraw()
|
||||
{
|
||||
static auto dd = new CompatPtr<IDirectDraw7>(createDirectDraw());
|
||||
return *dd;
|
||||
CompatWeakPtr<IDirectDraw7> getDirectDraw()
|
||||
{
|
||||
static auto dd = new CompatPtr<IDirectDraw7>(createDirectDraw());
|
||||
return *dd;
|
||||
}
|
||||
}
|
||||
}
|
28
DDrawCompat/DDraw/Repository.h
Normal file
28
DDrawCompat/DDraw/Repository.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatWeakPtr.h"
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
namespace Repository
|
||||
{
|
||||
struct Surface
|
||||
{
|
||||
DDSURFACEDESC2 desc;
|
||||
CompatWeakPtr<IDirectDrawSurface7> surface;
|
||||
};
|
||||
|
||||
class ScopedSurface : public Surface
|
||||
{
|
||||
public:
|
||||
ScopedSurface(const DDSURFACEDESC2& desc);
|
||||
~ScopedSurface();
|
||||
};
|
||||
|
||||
CompatWeakPtr<IDirectDraw7> getDirectDraw();
|
||||
}
|
||||
}
|
20
DDrawCompat/DDraw/ScopedThreadLock.h
Normal file
20
DDrawCompat/DDraw/ScopedThreadLock.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "DDrawProcs.h"
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
class ScopedThreadLock
|
||||
{
|
||||
public:
|
||||
ScopedThreadLock()
|
||||
{
|
||||
Compat::origProcs.AcquireDDThreadLock();
|
||||
}
|
||||
|
||||
~ScopedThreadLock()
|
||||
{
|
||||
Compat::origProcs.ReleaseDDThreadLock();
|
||||
}
|
||||
};
|
||||
}
|
72
DDrawCompat/DDraw/Types.h
Normal file
72
DDrawCompat/DDraw/Types.h
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
struct Types1
|
||||
{
|
||||
typedef IDirectDrawSurface TSurface;
|
||||
typedef IDirectDrawSurface TCreatedSurface;
|
||||
typedef DDSURFACEDESC TSurfaceDesc;
|
||||
typedef DDSCAPS TDdsCaps;
|
||||
typedef LPDDENUMSURFACESCALLBACK TEnumSurfacesCallbackPtr;
|
||||
typedef LPVOID TUnlockParam;
|
||||
};
|
||||
|
||||
struct Types2
|
||||
{
|
||||
typedef IDirectDrawSurface2 TSurface;
|
||||
typedef IDirectDrawSurface TCreatedSurface;
|
||||
typedef DDSURFACEDESC TSurfaceDesc;
|
||||
typedef DDSCAPS TDdsCaps;
|
||||
typedef LPDDENUMSURFACESCALLBACK TEnumSurfacesCallbackPtr;
|
||||
typedef LPVOID TUnlockParam;
|
||||
};
|
||||
|
||||
struct Types3
|
||||
{
|
||||
typedef IDirectDrawSurface3 TSurface;
|
||||
typedef IDirectDrawSurface3 TCreatedSurface;
|
||||
typedef DDSURFACEDESC TSurfaceDesc;
|
||||
typedef DDSCAPS TDdsCaps;
|
||||
typedef LPDDENUMSURFACESCALLBACK TEnumSurfacesCallbackPtr;
|
||||
typedef LPVOID TUnlockParam;
|
||||
};
|
||||
|
||||
struct Types4
|
||||
{
|
||||
typedef IDirectDrawSurface4 TSurface;
|
||||
typedef IDirectDrawSurface4 TCreatedSurface;
|
||||
typedef DDSURFACEDESC2 TSurfaceDesc;
|
||||
typedef DDSCAPS2 TDdsCaps;
|
||||
typedef LPDDENUMSURFACESCALLBACK2 TEnumSurfacesCallbackPtr;
|
||||
typedef LPRECT TUnlockParam;
|
||||
};
|
||||
|
||||
struct Types7
|
||||
{
|
||||
typedef IDirectDrawSurface7 TSurface;
|
||||
typedef IDirectDrawSurface7 TCreatedSurface;
|
||||
typedef DDSURFACEDESC2 TSurfaceDesc;
|
||||
typedef DDSCAPS2 TDdsCaps;
|
||||
typedef LPDDENUMSURFACESCALLBACK7 TEnumSurfacesCallbackPtr;
|
||||
typedef LPRECT TUnlockParam;
|
||||
};
|
||||
|
||||
template <typename Interface>
|
||||
struct Types;
|
||||
|
||||
template <> struct Types<IDirectDraw> : Types1 {};
|
||||
template <> struct Types<IDirectDraw2> : Types2 {};
|
||||
template <> struct Types<IDirectDraw4> : Types4 {};
|
||||
template <> struct Types<IDirectDraw7> : Types7 {};
|
||||
|
||||
template <> struct Types<IDirectDrawSurface> : Types1 {};
|
||||
template <> struct Types<IDirectDrawSurface2> : Types2 {};
|
||||
template <> struct Types<IDirectDrawSurface3> : Types3 {};
|
||||
template <> struct Types<IDirectDrawSurface4> : Types4 {};
|
||||
template <> struct Types<IDirectDrawSurface7> : Types7 {};
|
||||
}
|
@ -147,7 +147,6 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CompatActivateAppHandler.h" />
|
||||
<ClInclude Include="CompatD3dDdiAdapterCallbacks.h" />
|
||||
<ClInclude Include="CompatD3dDdiAdapterFuncs.h" />
|
||||
<ClInclude Include="CompatD3dDdiDeviceCallbacks.h" />
|
||||
@ -155,15 +154,13 @@
|
||||
<ClInclude Include="CompatDepthBuffer.h" />
|
||||
<ClInclude Include="CompatDirect3d.h" />
|
||||
<ClInclude Include="CompatDirect3dDevice.h" />
|
||||
<ClInclude Include="CompatDirectDrawPalette.h" />
|
||||
<ClInclude Include="CompatDisplayMode.h" />
|
||||
<ClInclude Include="CompatFontSmoothing.h" />
|
||||
<ClInclude Include="CompatHooks.h" />
|
||||
<ClInclude Include="CompatPaletteConverter.h" />
|
||||
<ClInclude Include="CompatPtr.h" />
|
||||
<ClInclude Include="CompatQueryInterface.h" />
|
||||
<ClInclude Include="CompatRef.h" />
|
||||
<ClInclude Include="CompatRegistry.h" />
|
||||
<ClInclude Include="CompatVtable.h" />
|
||||
<ClInclude Include="CompatWeakPtr.h" />
|
||||
<ClInclude Include="Config.h" />
|
||||
<ClInclude Include="D3dDdiAdapterCallbacksVisitor.h" />
|
||||
@ -171,16 +168,21 @@
|
||||
<ClInclude Include="D3dDdiDeviceCallbacksVisitor.h" />
|
||||
<ClInclude Include="D3dDdiDeviceFuncsVisitor.h" />
|
||||
<ClInclude Include="D3dDdiHooks.h" />
|
||||
<ClInclude Include="DDrawHooks.h" />
|
||||
<ClInclude Include="DDrawProcs.h" />
|
||||
<ClInclude Include="CompatDirectDraw.h" />
|
||||
<ClInclude Include="CompatPrimarySurface.h" />
|
||||
<ClInclude Include="DDrawRepository.h" />
|
||||
<ClInclude Include="DDrawScopedThreadLock.h" />
|
||||
<ClInclude Include="DDrawTypes.h" />
|
||||
<ClInclude Include="CompatDirectDrawSurface.h" />
|
||||
<ClInclude Include="DDrawVtableVisitor.h" />
|
||||
<ClInclude Include="CompatVtable.h" />
|
||||
<ClInclude Include="DDraw\ActivateAppHandler.h" />
|
||||
<ClInclude Include="DDraw\DirectDraw.h" />
|
||||
<ClInclude Include="DDraw\DirectDrawPalette.h" />
|
||||
<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\Types.h" />
|
||||
<ClInclude Include="DDraw\IReleaseNotifier.h" />
|
||||
<ClInclude Include="DDraw\RealPrimarySurface.h" />
|
||||
<ClInclude Include="Direct3dDeviceVtblVisitor.h" />
|
||||
<ClInclude Include="Direct3dTypes.h" />
|
||||
<ClInclude Include="Direct3dVtblVisitor.h" />
|
||||
@ -199,13 +201,10 @@
|
||||
<ClInclude Include="Gdi\TitleBar.h" />
|
||||
<ClInclude Include="Gdi\WinProc.h" />
|
||||
<ClInclude Include="Hook.h" />
|
||||
<ClInclude Include="IReleaseNotifier.h" />
|
||||
<ClInclude Include="RealPrimarySurface.h" />
|
||||
<ClInclude Include="ScopedCriticalSection.h" />
|
||||
<ClInclude Include="Time.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CompatActivateAppHandler.cpp" />
|
||||
<ClCompile Include="CompatD3dDdiAdapterCallbacks.cpp" />
|
||||
<ClCompile Include="CompatD3dDdiAdapterFuncs.cpp" />
|
||||
<ClCompile Include="CompatD3dDdiDeviceCallbacks.cpp" />
|
||||
@ -213,19 +212,23 @@
|
||||
<ClCompile Include="CompatDepthBuffer.cpp" />
|
||||
<ClCompile Include="CompatDirect3d.cpp" />
|
||||
<ClCompile Include="CompatDirect3dDevice.cpp" />
|
||||
<ClCompile Include="CompatDirectDraw.cpp" />
|
||||
<ClCompile Include="CompatDirectDrawPalette.cpp" />
|
||||
<ClCompile Include="CompatDirectDrawSurface.cpp" />
|
||||
<ClCompile Include="CompatDisplayMode.cpp" />
|
||||
<ClCompile Include="CompatFontSmoothing.cpp" />
|
||||
<ClCompile Include="CompatHooks.cpp" />
|
||||
<ClCompile Include="CompatPaletteConverter.cpp" />
|
||||
<ClCompile Include="CompatRegistry.cpp" />
|
||||
<ClCompile Include="D3dDdiHooks.cpp" />
|
||||
<ClCompile Include="DDrawHooks.cpp" />
|
||||
<ClCompile Include="DDrawLog.cpp" />
|
||||
<ClCompile Include="DDraw\ActivateAppHandler.cpp" />
|
||||
<ClCompile Include="DDraw\DirectDraw.cpp" />
|
||||
<ClCompile Include="DDraw\DirectDrawPalette.cpp" />
|
||||
<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="DllMain.cpp" />
|
||||
<ClCompile Include="CompatPrimarySurface.cpp" />
|
||||
<ClCompile Include="DDrawProcs.cpp" />
|
||||
<ClCompile Include="Gdi\Gdi.cpp" />
|
||||
<ClCompile Include="Gdi\Caret.cpp" />
|
||||
@ -238,9 +241,6 @@
|
||||
<ClCompile Include="Gdi\TitleBar.cpp" />
|
||||
<ClCompile Include="Gdi\WinProc.cpp" />
|
||||
<ClCompile Include="Hook.cpp" />
|
||||
<ClCompile Include="IReleaseNotifier.cpp" />
|
||||
<ClCompile Include="RealPrimarySurface.cpp" />
|
||||
<ClCompile Include="DDrawRepository.cpp" />
|
||||
<ClCompile Include="Time.cpp" />
|
||||
<ClCompile Include="UnmodifiedDDrawProcs.cpp" />
|
||||
</ItemGroup>
|
||||
|
@ -19,26 +19,20 @@
|
||||
<Filter Include="Source Files\Gdi">
|
||||
<UniqueIdentifier>{a8e1437a-7bec-4492-830a-9a0d844aa06b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\DDraw">
|
||||
<UniqueIdentifier>{370ccd34-b783-421b-87fc-84ce703e851d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\DDraw">
|
||||
<UniqueIdentifier>{bcc85014-8548-43ff-902f-16bcb6a0e96b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="DDrawProcs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatDirectDraw.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDrawTypes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatDirectDrawSurface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDrawVtableVisitor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatVtable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDrawLog.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -51,45 +45,21 @@
|
||||
<ClInclude Include="DirectDrawPaletteVtblVisitor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatDirectDrawPalette.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RealPrimarySurface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatPrimarySurface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IReleaseNotifier.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDrawScopedThreadLock.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Hook.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatRegistry.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDrawRepository.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatPaletteConverter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ScopedCriticalSection.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Time.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatActivateAppHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatPtr.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -102,9 +72,6 @@
|
||||
<ClInclude Include="CompatRef.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatDisplayMode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatFontSmoothing.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -117,9 +84,6 @@
|
||||
<ClInclude Include="CompatDirect3d.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDrawHooks.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Direct3dDeviceVtblVisitor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -189,6 +153,48 @@
|
||||
<ClInclude Include="Gdi\WinProc.h">
|
||||
<Filter>Header Files\Gdi</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CompatVtable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\CompatPrimarySurface.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\IReleaseNotifier.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\RealPrimarySurface.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\ActivateAppHandler.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\DisplayMode.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\PaletteConverter.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\Hooks.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\Repository.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\ScopedThreadLock.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\Types.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\DirectDraw.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\DirectDrawPalette.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\DirectDrawSurface.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DllMain.cpp">
|
||||
@ -203,45 +209,15 @@
|
||||
<ClCompile Include="DDrawLog.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RealPrimarySurface.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatPrimarySurface.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IReleaseNotifier.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatDirectDraw.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatDirectDrawSurface.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatDirectDrawPalette.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Hook.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatRegistry.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DDrawRepository.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatPaletteConverter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Time.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatActivateAppHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatDisplayMode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatFontSmoothing.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -251,9 +227,6 @@
|
||||
<ClCompile Include="CompatDirect3d.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DDrawHooks.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompatDirect3dDevice.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -305,6 +278,39 @@
|
||||
<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>
|
||||
<ClCompile Include="DDraw\RealPrimarySurface.cpp">
|
||||
<Filter>Source Files\DDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DDraw\ActivateAppHandler.cpp">
|
||||
<Filter>Source Files\DDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DDraw\DisplayMode.cpp">
|
||||
<Filter>Source Files\DDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DDraw\PaletteConverter.cpp">
|
||||
<Filter>Source Files\DDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DDraw\Hooks.cpp">
|
||||
<Filter>Source Files\DDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DDraw\Repository.cpp">
|
||||
<Filter>Source Files\DDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DDraw\DirectDraw.cpp">
|
||||
<Filter>Source Files\DDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DDraw\DirectDrawPalette.cpp">
|
||||
<Filter>Source Files\DDraw</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DDraw\DirectDrawSurface.cpp">
|
||||
<Filter>Source Files\DDraw</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="DDrawCompat.def">
|
||||
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatWeakPtr.h"
|
||||
|
||||
namespace DDrawRepository
|
||||
{
|
||||
struct Surface
|
||||
{
|
||||
DDSURFACEDESC2 desc;
|
||||
CompatWeakPtr<IDirectDrawSurface7> surface;
|
||||
};
|
||||
|
||||
class ScopedSurface : public Surface
|
||||
{
|
||||
public:
|
||||
ScopedSurface(const DDSURFACEDESC2& desc);
|
||||
~ScopedSurface();
|
||||
};
|
||||
|
||||
CompatWeakPtr<IDirectDraw7> getDirectDraw();
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "DDrawProcs.h"
|
||||
|
||||
namespace Compat
|
||||
{
|
||||
class DDrawScopedThreadLock
|
||||
{
|
||||
public:
|
||||
DDrawScopedThreadLock()
|
||||
{
|
||||
origProcs.AcquireDDThreadLock();
|
||||
}
|
||||
|
||||
~DDrawScopedThreadLock()
|
||||
{
|
||||
origProcs.ReleaseDDThreadLock();
|
||||
}
|
||||
};
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
struct DDrawTypes
|
||||
{
|
||||
typedef IDirectDrawSurface TSurface;
|
||||
typedef IDirectDrawSurface TCreatedSurface;
|
||||
typedef DDSURFACEDESC TSurfaceDesc;
|
||||
typedef DDSCAPS TDdsCaps;
|
||||
typedef LPDDENUMSURFACESCALLBACK TEnumSurfacesCallbackPtr;
|
||||
typedef LPVOID TUnlockParam;
|
||||
};
|
||||
|
||||
struct DDrawTypes2
|
||||
{
|
||||
typedef IDirectDrawSurface2 TSurface;
|
||||
typedef IDirectDrawSurface TCreatedSurface;
|
||||
typedef DDSURFACEDESC TSurfaceDesc;
|
||||
typedef DDSCAPS TDdsCaps;
|
||||
typedef LPDDENUMSURFACESCALLBACK TEnumSurfacesCallbackPtr;
|
||||
typedef LPVOID TUnlockParam;
|
||||
};
|
||||
|
||||
struct DDrawTypes3
|
||||
{
|
||||
typedef IDirectDrawSurface3 TSurface;
|
||||
typedef IDirectDrawSurface3 TCreatedSurface;
|
||||
typedef DDSURFACEDESC TSurfaceDesc;
|
||||
typedef DDSCAPS TDdsCaps;
|
||||
typedef LPDDENUMSURFACESCALLBACK TEnumSurfacesCallbackPtr;
|
||||
typedef LPVOID TUnlockParam;
|
||||
};
|
||||
|
||||
struct DDrawTypes4
|
||||
{
|
||||
typedef IDirectDrawSurface4 TSurface;
|
||||
typedef IDirectDrawSurface4 TCreatedSurface;
|
||||
typedef DDSURFACEDESC2 TSurfaceDesc;
|
||||
typedef DDSCAPS2 TDdsCaps;
|
||||
typedef LPDDENUMSURFACESCALLBACK2 TEnumSurfacesCallbackPtr;
|
||||
typedef LPRECT TUnlockParam;
|
||||
};
|
||||
|
||||
struct DDrawTypes7
|
||||
{
|
||||
typedef IDirectDrawSurface7 TSurface;
|
||||
typedef IDirectDrawSurface7 TCreatedSurface;
|
||||
typedef DDSURFACEDESC2 TSurfaceDesc;
|
||||
typedef DDSCAPS2 TDdsCaps;
|
||||
typedef LPDDENUMSURFACESCALLBACK7 TEnumSurfacesCallbackPtr;
|
||||
typedef LPRECT TUnlockParam;
|
||||
};
|
||||
|
||||
template <typename Interface>
|
||||
struct Types;
|
||||
|
||||
#define DD_CONCAT(x, y, ...) x##y
|
||||
|
||||
#define DD_TYPES(Interface, ...) \
|
||||
template <> \
|
||||
struct Types<DD_CONCAT(Interface, __VA_ARGS__)> : DD_CONCAT(DDrawTypes, __VA_ARGS__) \
|
||||
{}
|
||||
|
||||
DD_TYPES(IDirectDraw);
|
||||
DD_TYPES(IDirectDraw, 2);
|
||||
DD_TYPES(IDirectDraw, 4);
|
||||
DD_TYPES(IDirectDraw, 7);
|
||||
|
||||
DD_TYPES(IDirectDrawSurface);
|
||||
DD_TYPES(IDirectDrawSurface, 2);
|
||||
DD_TYPES(IDirectDrawSurface, 3);
|
||||
DD_TYPES(IDirectDrawSurface, 4);
|
||||
DD_TYPES(IDirectDrawSurface, 7);
|
||||
|
||||
#undef DD_TYPES
|
||||
#undef DD_CONCAT
|
@ -5,12 +5,12 @@
|
||||
#include <Windows.h>
|
||||
#include <Uxtheme.h>
|
||||
|
||||
#include "CompatDisplayMode.h"
|
||||
#include "CompatFontSmoothing.h"
|
||||
#include "CompatHooks.h"
|
||||
#include "CompatRegistry.h"
|
||||
#include "D3dDdiHooks.h"
|
||||
#include "DDrawHooks.h"
|
||||
#include "DDraw/DisplayMode.h"
|
||||
#include "DDraw/Hooks.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "Gdi/Gdi.h"
|
||||
#include "Time.h"
|
||||
@ -30,7 +30,7 @@ namespace
|
||||
Compat::Log() << "Installing Direct3D driver hooks";
|
||||
D3dDdiHooks::installHooks();
|
||||
Compat::Log() << "Installing DirectDraw hooks";
|
||||
DDrawHooks::installHooks();
|
||||
DDraw::installHooks();
|
||||
Compat::Log() << "Installing GDI hooks";
|
||||
Gdi::installHooks();
|
||||
Compat::Log() << "Installing registry hooks";
|
||||
@ -117,7 +117,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID /*lpvReserved*/)
|
||||
SetProcessAffinityMask(GetCurrentProcess(), 1);
|
||||
SetThemeAppProperties(0);
|
||||
|
||||
CompatDisplayMode::installHooks();
|
||||
DDraw::DisplayMode::installHooks();
|
||||
CompatFontSmoothing::g_origSystemSettings = CompatFontSmoothing::getSystemSettings();
|
||||
CompatHooks::installHooks();
|
||||
Time::init();
|
||||
@ -135,7 +135,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID /*lpvReserved*/)
|
||||
else if (fdwReason == DLL_PROCESS_DETACH)
|
||||
{
|
||||
Compat::Log() << "Detaching DDrawCompat";
|
||||
DDrawHooks::uninstallHooks();
|
||||
DDraw::uninstallHooks();
|
||||
D3dDdiHooks::uninstallHooks();
|
||||
Gdi::uninstallHooks();
|
||||
Compat::unhookAllFunctions();
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "Config.h"
|
||||
#include "DDraw/CompatPrimarySurface.h"
|
||||
#include "DDraw/Repository.h"
|
||||
#include "DDrawLog.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "DDrawRepository.h"
|
||||
#include "Gdi/DcCache.h"
|
||||
|
||||
namespace
|
||||
@ -55,13 +55,13 @@ namespace
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> createGdiSurface()
|
||||
{
|
||||
DDSURFACEDESC2 desc = CompatPrimarySurface::getDesc();
|
||||
DDSURFACEDESC2 desc = DDraw::CompatPrimarySurface::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;
|
||||
desc.lpSurface = g_surfaceMemory;
|
||||
|
||||
auto dd(DDrawRepository::getDirectDraw());
|
||||
auto dd(DDraw::Repository::getDirectDraw());
|
||||
CompatPtr<IDirectDrawSurface7> surface;
|
||||
HRESULT result = dd->CreateSurface(dd, &desc, &surface.getRef(), nullptr);
|
||||
if (FAILED(result))
|
||||
@ -163,7 +163,7 @@ namespace Gdi
|
||||
|
||||
bool init()
|
||||
{
|
||||
auto dd(DDrawRepository::getDirectDraw());
|
||||
auto dd(DDraw::Repository::getDirectDraw());
|
||||
dd->CreatePalette(dd,
|
||||
DDPCAPS_8BIT | DDPCAPS_ALLOW256, g_paletteEntries, &g_palette.getRef(), nullptr);
|
||||
return nullptr != g_palette;
|
||||
@ -202,15 +202,15 @@ namespace Gdi
|
||||
{
|
||||
PALETTEENTRY entries[256] = {};
|
||||
std::memcpy(&entries[startingEntry],
|
||||
&CompatPrimarySurface::g_paletteEntries[startingEntry],
|
||||
&DDraw::CompatPrimarySurface::g_paletteEntries[startingEntry],
|
||||
count * sizeof(PALETTEENTRY));
|
||||
|
||||
for (DWORD i = startingEntry; i < startingEntry + count; ++i)
|
||||
{
|
||||
if (entries[i].peFlags & PC_RESERVED)
|
||||
{
|
||||
entries[i] = CompatPrimarySurface::g_paletteEntries[0];
|
||||
entries[i].peFlags = CompatPrimarySurface::g_paletteEntries[i].peFlags;
|
||||
entries[i] = DDraw::CompatPrimarySurface::g_paletteEntries[0];
|
||||
entries[i].peFlags = DDraw::CompatPrimarySurface::g_paletteEntries[i].peFlags;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "CompatDisplayMode.h"
|
||||
#include "DDraw/DisplayMode.h"
|
||||
#include "DDrawLog.h"
|
||||
#include "Gdi/Dc.h"
|
||||
#include "Gdi/DcFunctions.h"
|
||||
@ -225,9 +225,9 @@ namespace Gdi
|
||||
// Bitmap functions
|
||||
HOOK_GDI_DC_FUNCTION(msimg32, AlphaBlend);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, BitBlt);
|
||||
HOOK_FUNCTION(gdi32, CreateCompatibleBitmap, CompatDisplayMode::createCompatibleBitmap);
|
||||
HOOK_FUNCTION(gdi32, CreateDIBitmap, CompatDisplayMode::createDIBitmap);
|
||||
HOOK_FUNCTION(gdi32, CreateDiscardableBitmap, CompatDisplayMode::createDiscardableBitmap);
|
||||
HOOK_FUNCTION(gdi32, CreateCompatibleBitmap, DDraw::DisplayMode::createCompatibleBitmap);
|
||||
HOOK_FUNCTION(gdi32, CreateDIBitmap, DDraw::DisplayMode::createDIBitmap);
|
||||
HOOK_FUNCTION(gdi32, CreateDiscardableBitmap, DDraw::DisplayMode::createDiscardableBitmap);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, ExtFloodFill);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, GdiAlphaBlend);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, GdiGradientFill);
|
||||
|
@ -1,7 +1,8 @@
|
||||
#include <atomic>
|
||||
|
||||
#include "CompatPaletteConverter.h"
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "DDraw/CompatPrimarySurface.h"
|
||||
#include "DDraw/PaletteConverter.h"
|
||||
#include "DDraw/RealPrimarySurface.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "Gdi/Caret.h"
|
||||
#include "Gdi/DcCache.h"
|
||||
@ -10,7 +11,6 @@
|
||||
#include "Gdi/PaintHandlers.h"
|
||||
#include "Gdi/ScrollFunctions.h"
|
||||
#include "Gdi/WinProc.h"
|
||||
#include "RealPrimarySurface.h"
|
||||
#include "ScopedCriticalSection.h"
|
||||
|
||||
namespace
|
||||
@ -58,7 +58,7 @@ namespace
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
auto primary(CompatPrimarySurface::getPrimary());
|
||||
auto primary(DDraw::CompatPrimarySurface::getPrimary());
|
||||
if (FAILED(primary->Lock(primary, nullptr, &desc, lockFlags | DDLOCK_WAIT, nullptr)))
|
||||
{
|
||||
return false;
|
||||
@ -79,12 +79,12 @@ namespace
|
||||
void unlockPrimarySurface()
|
||||
{
|
||||
GdiFlush();
|
||||
auto primary(CompatPrimarySurface::getPrimary());
|
||||
auto primary(DDraw::CompatPrimarySurface::getPrimary());
|
||||
primary->Unlock(primary, nullptr);
|
||||
if (DDLOCK_READONLY != g_ddLockFlags)
|
||||
{
|
||||
RealPrimarySurface::invalidate(nullptr);
|
||||
RealPrimarySurface::update();
|
||||
DDraw::RealPrimarySurface::invalidate(nullptr);
|
||||
DDraw::RealPrimarySurface::update();
|
||||
}
|
||||
|
||||
if (0 != g_ddLockFlags)
|
||||
@ -220,7 +220,7 @@ namespace Gdi
|
||||
|
||||
bool isEmulationEnabled()
|
||||
{
|
||||
return g_disableEmulationCount <= 0 && RealPrimarySurface::isFullScreen();
|
||||
return g_disableEmulationCount <= 0 && DDraw::RealPrimarySurface::isFullScreen();
|
||||
}
|
||||
|
||||
void unhookWndProc(LPCSTR className, WNDPROC oldWndProc)
|
||||
@ -239,7 +239,7 @@ namespace Gdi
|
||||
|
||||
void updatePalette(DWORD startingEntry, DWORD count)
|
||||
{
|
||||
if (isEmulationEnabled() && CompatPrimarySurface::g_palette)
|
||||
if (isEmulationEnabled() && DDraw::CompatPrimarySurface::g_palette)
|
||||
{
|
||||
Gdi::DcCache::updatePalette(startingEntry, count);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "CompatRegistry.h"
|
||||
#include "DDraw/CompatPrimarySurface.h"
|
||||
#include "DDraw/RealPrimarySurface.h"
|
||||
#include "DDrawLog.h"
|
||||
#include "Gdi/Dc.h"
|
||||
#include "Gdi/Gdi.h"
|
||||
@ -8,7 +9,6 @@
|
||||
#include "Gdi/ScrollFunctions.h"
|
||||
#include "Gdi/TitleBar.h"
|
||||
#include "Hook.h"
|
||||
#include "RealPrimarySurface.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -170,7 +170,7 @@ namespace
|
||||
Gdi::Dc::releaseDc(dc);
|
||||
if (result)
|
||||
{
|
||||
RealPrimarySurface::disableUpdates();
|
||||
DDraw::RealPrimarySurface::disableUpdates();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -183,7 +183,7 @@ namespace
|
||||
if (result && compatDc)
|
||||
{
|
||||
UpdateWindow(hwnd);
|
||||
RealPrimarySurface::enableUpdates();
|
||||
DDraw::RealPrimarySurface::enableUpdates();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "DDraw/RealPrimarySurface.h"
|
||||
#include "DDrawLog.h"
|
||||
#include "Gdi/Gdi.h"
|
||||
#include "Gdi/ScrollFunctions.h"
|
||||
#include "Hook.h"
|
||||
#include "RealPrimarySurface.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -57,10 +57,10 @@ namespace Gdi
|
||||
{
|
||||
if (Gdi::isEmulationEnabled())
|
||||
{
|
||||
RealPrimarySurface::disableUpdates();
|
||||
DDraw::RealPrimarySurface::disableUpdates();
|
||||
RedrawWindow(hwnd, nullptr, nullptr,
|
||||
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN | RDW_UPDATENOW);
|
||||
RealPrimarySurface::enableUpdates();
|
||||
DDraw::RealPrimarySurface::enableUpdates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "CompatPrimarySurface.h"
|
||||
#include "DDraw/CompatPrimarySurface.h"
|
||||
#include "Gdi/Gdi.h"
|
||||
#include "Gdi/TitleBar.h"
|
||||
#include "Hook.h"
|
||||
@ -96,7 +96,7 @@ namespace Gdi
|
||||
{
|
||||
flags |= DC_ACTIVE;
|
||||
}
|
||||
if (CompatPrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount > 8)
|
||||
if (DDraw::CompatPrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount > 8)
|
||||
{
|
||||
flags |= DC_GRADIENT;
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <Unknwnbase.h>
|
||||
|
||||
// {7810158A-CB51-448A-8706-443A7DF6D4ED}
|
||||
DEFINE_GUID(IID_IReleaseNotifier,
|
||||
0x7810158a, 0xcb51, 0x448a, 0x87, 0x6, 0x44, 0x3a, 0x7d, 0xf6, 0xd4, 0xed);
|
||||
|
||||
class IReleaseNotifier
|
||||
{
|
||||
public:
|
||||
IReleaseNotifier(const std::function<void()>& notifyHandler)
|
||||
: m_notifyHandler(notifyHandler)
|
||||
{
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID*)
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
virtual ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
m_notifyHandler();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void()> m_notifyHandler;
|
||||
};
|
@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define CINTERFACE
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "CompatWeakPtr.h"
|
||||
#include "CompatRef.h"
|
||||
|
||||
class RealPrimarySurface
|
||||
{
|
||||
public:
|
||||
template <typename DirectDraw>
|
||||
static HRESULT create(CompatRef<DirectDraw> dd);
|
||||
|
||||
static void disableUpdates();
|
||||
static void enableUpdates();
|
||||
static HRESULT flip(DWORD flags);
|
||||
static CompatWeakPtr<IDirectDrawSurface7> getSurface();
|
||||
static void invalidate(const RECT* rect);
|
||||
static bool isFullScreen();
|
||||
static bool isLost();
|
||||
static void release();
|
||||
static void removeUpdateThread();
|
||||
static HRESULT restore();
|
||||
static void setClipper(CompatWeakPtr<IDirectDrawClipper> clipper);
|
||||
static void setPalette();
|
||||
static void update();
|
||||
static void updatePalette(DWORD startingEntry, DWORD count);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user