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

Create default primary in fullscreen mode

Fixes intro videos displaying in a small window in Midtown Madness 2
This commit is contained in:
narzoul 2022-07-23 23:56:08 +02:00
parent 2099c80095
commit 6327bc506f
5 changed files with 80 additions and 52 deletions

View File

@ -39,7 +39,6 @@ namespace
void onRelease();
CompatWeakPtr<IDirectDraw7> g_defaultPrimaryDD;
CompatWeakPtr<IDirectDrawSurface7> g_defaultPrimary;
CompatWeakPtr<IDirectDrawSurface7> g_frontBuffer;
@ -113,47 +112,54 @@ namespace
return TRUE;
}
CompatPtr<IDirectDraw7> dd;
if (FAILED(CALL_ORIG_PROC(DirectDrawCreateEx)(
lpGUID, reinterpret_cast<void**>(&dd.getRef()), IID_IDirectDraw7, nullptr)))
auto tagSurface = DDraw::TagSurface::findFullscreenWindow();
LOG_DEBUG << "Creating " << (tagSurface ? "fullscreen" : "windowed") << " default primary";
if (tagSurface)
{
return FALSE;
DDSURFACEDESC desc = {};
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
CompatPtr<IDirectDraw> dd(tagSurface->getDD());
CompatPtr<IDirectDrawSurface> primary;
dd.get()->lpVtbl->CreateSurface(dd, &desc, &primary.getRef(), nullptr);
g_defaultPrimary = CompatPtr<IDirectDrawSurface7>(primary).detach();
}
else
{
CompatPtr<IDirectDraw7> dd;
if (FAILED(CALL_ORIG_PROC(DirectDrawCreateEx)(
lpGUID, reinterpret_cast<void**>(&dd.getRef()), IID_IDirectDraw7, nullptr)))
{
return FALSE;
}
if (FAILED(dd.get()->lpVtbl->SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL)))
{
return FALSE;
}
DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
dd.get()->lpVtbl->CreateSurface(dd, &desc, &g_defaultPrimary.getRef(), nullptr);
}
if (FAILED(dd.get()->lpVtbl->SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL)))
{
return FALSE;
}
CompatPtr<IDirectDrawSurface7> primary;
DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if (FAILED(dd.get()->lpVtbl->CreateSurface(dd, &desc, &primary.getRef(), nullptr)))
{
return FALSE;
}
g_defaultPrimary = primary.detach();
g_defaultPrimaryDD = dd.detach();
return FALSE;
return nullptr != g_defaultPrimary;
}
void createDefaultPrimary()
{
if (g_frontBuffer || g_defaultPrimary && SUCCEEDED(g_defaultPrimary->IsLost(g_defaultPrimary)))
if (g_defaultPrimary ? SUCCEEDED(g_defaultPrimary->IsLost(g_defaultPrimary)) : g_frontBuffer)
{
return;
}
DDraw::RealPrimarySurface::destroyDefaultPrimary();
if (DDraw::TagSurface::doesFullscreenDirectDrawExist())
{
return;
}
auto dm = Win32::DisplayMode::getEmulatedDisplayMode();
if (0 == dm.diff.cx && 0 == dm.diff.cy)
{
@ -270,6 +276,7 @@ namespace
g_presentationWindow = nullptr;
}
g_defaultPrimary = nullptr;
g_frontBuffer = nullptr;
g_lastFlipSurface = nullptr;
g_windowedBackBuffer.release();
@ -425,8 +432,6 @@ namespace
}
DDraw::ScopedThreadLock lock;
createDefaultPrimary();
updatePresentationWindowPos();
msUntilUpdateReady = DDraw::RealPrimarySurface::flush();
}
}
@ -509,8 +514,11 @@ namespace DDraw
void RealPrimarySurface::destroyDefaultPrimary()
{
g_defaultPrimary.release();
g_defaultPrimaryDD.release();
if (g_defaultPrimary)
{
LOG_DEBUG << "Destroying default primary";
g_defaultPrimary.release();
}
}
HRESULT RealPrimarySurface::flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags)
@ -585,6 +593,9 @@ namespace DDraw
}
}
createDefaultPrimary();
updatePresentationWindowPos();
auto src(g_isDelayedFlipPending ? g_lastFlipSurface->getDDS() : DDraw::PrimarySurface::getPrimary());
RECT emptyRect = {};
HRESULT result = src ? src->BltFast(src, 0, 0, src, &emptyRect, DDBLTFAST_WAIT) : DD_OK;

View File

@ -13,17 +13,20 @@ namespace DDraw
{
TagSurface::TagSurface(DWORD origCaps, DDRAWI_DIRECTDRAW_LCL* ddLcl)
: Surface(origCaps)
, m_ddLcl(ddLcl)
, m_ddInt{}
, m_fullscreenWindow(nullptr)
, m_fullscreenWindowStyle(0)
, m_fullscreenWindowExStyle(0)
{
m_ddInt.lpVtbl = &CompatVtable<IDirectDraw>::s_origVtable;
m_ddInt.lpLcl = ddLcl;
m_ddInt.dwIntRefCnt = 1;
}
TagSurface::~TagSurface()
{
setFullscreenWindow(nullptr);
g_ddObjects.erase(m_ddLcl);
g_ddObjects.erase(m_ddInt.lpLcl);
}
HRESULT TagSurface::create(CompatRef<IDirectDraw> dd)
@ -43,23 +46,12 @@ namespace DDraw
return Surface::create(dd, desc, surface, std::move(privateData));
}
bool TagSurface::doesFullscreenDirectDrawExist()
{
for (auto& pair : g_ddObjects)
{
if (pair.second->m_fullscreenWindow)
{
return true;
}
}
return false;
}
TagSurface* TagSurface::findFullscreenWindow(HWND hwnd)
{
for (auto& pair : g_ddObjects)
{
if (hwnd == pair.second->m_fullscreenWindow)
if (pair.second->m_fullscreenWindow &&
(!hwnd || hwnd == pair.second->m_fullscreenWindow))
{
return pair.second;
}
@ -93,6 +85,11 @@ namespace DDraw
return g_ddObjects[ddLcl];
}
CompatPtr<IDirectDraw7> TagSurface::getDD()
{
return CompatPtr<IDirectDraw7>::from(reinterpret_cast<IDirectDraw*>(&m_ddInt));
}
void TagSurface::setFullscreenWindow(HWND hwnd)
{
if (m_fullscreenWindow == hwnd)

View File

@ -16,10 +16,9 @@ namespace DDraw
static TagSurface* get(DDRAWI_DIRECTDRAW_LCL* ddLcl);
static TagSurface* get(CompatRef<IDirectDraw> dd);
static TagSurface* findFullscreenWindow(HWND hwnd);
static bool doesFullscreenDirectDrawExist();
static TagSurface* findFullscreenWindow(HWND hwnd = nullptr);
CompatPtr<IDirectDraw7> getDD();
bool isFullscreen() const { return m_fullscreenWindow; }
void setFullscreenWindow(HWND hwnd);
LONG setWindowStyle(LONG style);
@ -28,7 +27,7 @@ namespace DDraw
private:
static HRESULT create(CompatRef<IDirectDraw> dd);
DDRAWI_DIRECTDRAW_LCL* m_ddLcl;
DDRAWI_DIRECTDRAW_INT m_ddInt;
HWND m_fullscreenWindow;
LONG m_fullscreenWindowStyle;
LONG m_fullscreenWindowExStyle;

View File

@ -14,6 +14,10 @@
namespace
{
typedef void (WINAPI* SurfaceFlipNotifyFunc)(void*);
SurfaceFlipNotifyFunc g_origSurfaceFlipNotify = nullptr;
SurfaceFlipNotifyFunc g_origSurfaceFlipNotify7 = nullptr;
void hookDirect3dDevice(CompatRef<IDirect3D3> d3d, CompatRef<IDirectDrawSurface4> renderTarget);
void hookDirect3dExecuteBuffer(CompatRef<IDirect3DDevice> dev);
void hookDirect3dLight(CompatRef<IDirect3D3> d3d);
@ -220,6 +224,16 @@ namespace
Direct3d::Direct3dViewport::hookVtable(*CompatPtr<IDirect3DViewport2>(viewport).get()->lpVtbl);
Direct3d::Direct3dViewport::hookVtable(*CompatPtr<IDirect3DViewport3>(viewport).get()->lpVtbl);
}
template <auto& origSurfaceFlipNotify>
void WINAPI surfaceFlipNotify(void* ptr)
{
LOG_FUNC("SurfaceFlipNotify", ptr);
if (ptr)
{
origSurfaceFlipNotify(ptr);
}
}
}
namespace Direct3d
@ -233,5 +247,10 @@ namespace Direct3d
hookDirect3d(*dd, *renderTarget4);
hookDirect3d7(*dd7);
}
Compat::hookFunction("d3dim", "SurfaceFlipNotify", reinterpret_cast<void*&>(g_origSurfaceFlipNotify),
surfaceFlipNotify<g_origSurfaceFlipNotify>);
Compat::hookFunction("d3dim700", "SurfaceFlipNotify", reinterpret_cast<void*&>(g_origSurfaceFlipNotify7),
surfaceFlipNotify<g_origSurfaceFlipNotify7>);
}
}

View File

@ -180,6 +180,7 @@ namespace Gdi
void setEmulated(bool isEmulated)
{
LOG_FUNC("Cursor::setEmulated", isEmulated);
Compat::ScopedCriticalSection lock(g_cs);
if (isEmulated == g_isEmulated)
{
@ -202,6 +203,7 @@ namespace Gdi
void setMonitorClipRect(const RECT& rect)
{
LOG_FUNC("Cursor::setMonitorClipRect", rect);
Compat::ScopedCriticalSection lock(g_cs);
if (IsRectEmpty(&rect))
{