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:
parent
2099c80095
commit
6327bc506f
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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>);
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user