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

Use default primary if none exists for windowed fullscreen presentation

This commit is contained in:
narzoul 2022-06-07 15:46:38 +02:00
parent d39a4ab0fc
commit bf58555d22
5 changed files with 89 additions and 3 deletions

View File

@ -38,6 +38,9 @@ namespace
void onRelease();
CompatWeakPtr<IDirectDraw7> g_defaultPrimaryDD;
CompatWeakPtr<IDirectDrawSurface7> g_defaultPrimary;
CompatWeakPtr<IDirectDrawSurface7> g_frontBuffer;
CompatWeakPtr<IDirectDrawSurface7> g_windowedBackBuffer;
CompatWeakPtr<IDirectDrawClipper> g_clipper;
@ -100,6 +103,65 @@ namespace
}
}
BOOL WINAPI createDefaultPrimaryEnum(
GUID* lpGUID, LPSTR /*lpDriverDescription*/, LPSTR lpDriverName, LPVOID lpContext, HMONITOR /*hm*/)
{
auto& deviceName = *static_cast<std::wstring*>(lpContext);
if (deviceName != std::wstring(lpDriverName, lpDriverName + strlen(lpDriverName)))
{
return TRUE;
}
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;
}
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;
}
void createDefaultPrimary()
{
if (g_frontBuffer || g_defaultPrimary && SUCCEEDED(g_defaultPrimary->IsLost(g_defaultPrimary)))
{
return;
}
DDraw::RealPrimarySurface::destroyDefaultPrimary();
if (DDraw::TagSurface::doesFullscreenDirectDrawExist())
{
return;
}
auto dm = Win32::DisplayMode::getEmulatedDisplayMode();
if (0 == dm.diff.cx && 0 == dm.diff.cy)
{
return;
}
CALL_ORIG_PROC(DirectDrawEnumerateExA)(createDefaultPrimaryEnum, &dm.deviceName, DDENUM_ATTACHEDSECONDARYDEVICES);
}
CompatPtr<IDirectDrawSurface7> createWindowedBackBuffer(DDRAWI_DIRECTDRAW_LCL* ddLcl, DWORD width, DWORD height)
{
if (!ddLcl)
@ -361,6 +423,7 @@ namespace
}
DDraw::ScopedThreadLock lock;
createDefaultPrimary();
updatePresentationWindowPos();
msUntilUpdateReady = DDraw::RealPrimarySurface::flush();
}
@ -372,6 +435,7 @@ namespace DDraw
template <typename DirectDraw>
HRESULT RealPrimarySurface::create(CompatRef<DirectDraw> dd)
{
LOG_FUNC("RealPrimarySurface::create", &dd);
DDraw::ScopedThreadLock lock;
g_monitorRect = D3dDdi::KernelModeThunks::getAdapterInfo(*CompatPtr<IDirectDraw7>::from(&dd)).monitorInfo.rcMonitor;
@ -439,6 +503,12 @@ namespace DDraw
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw4>);
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw7>);
void RealPrimarySurface::destroyDefaultPrimary()
{
g_defaultPrimary.release();
g_defaultPrimaryDD.release();
}
HRESULT RealPrimarySurface::flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags)
{
const DWORD flipInterval = getFlipInterval(flags);

View File

@ -15,6 +15,7 @@ namespace DDraw
template <typename DirectDraw>
static HRESULT create(CompatRef<DirectDraw> dd);
static void destroyDefaultPrimary();
static HRESULT flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags);
static int flush();
static HWND getDevicePresentationWindow();

View File

@ -50,6 +50,8 @@ namespace DDraw
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
HRESULT PrimarySurface::create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface)
{
LOG_FUNC("PrimarySurface::create", &dd, desc, surface);
DDraw::RealPrimarySurface::destroyDefaultPrimary();
const auto& dm = DDraw::DirectDraw::getDisplayMode(*CompatPtr<IDirectDraw7>::from(&dd));
g_monitorRect = D3dDdi::KernelModeThunks::getAdapterInfo(*CompatPtr<IDirectDraw7>::from(&dd)).monitorInfo.rcMonitor;
g_monitorRect.right = g_monitorRect.left + dm.dwWidth;
@ -58,7 +60,7 @@ namespace DDraw
HRESULT result = RealPrimarySurface::create(dd);
if (FAILED(result))
{
return result;
return LOG_RESULT(result);
}
const DWORD origCaps = desc.ddsCaps.dwCaps;
@ -79,7 +81,7 @@ namespace DDraw
LOG_INFO << "ERROR: Failed to create the compat primary surface: " << Compat::hex(result);
g_monitorRect = {};
RealPrimarySurface::release();
return result;
return LOG_RESULT(result);
}
g_origCaps = origCaps;
@ -97,7 +99,7 @@ namespace DDraw
g_device = D3dDdi::Device::findDeviceByResource(DirectDrawSurface::getDriverResourceHandle(*surface));
data->restore();
D3dDdi::Device::updateAllConfig();
return DD_OK;
return LOG_RESULT(DD_OK);
}
template HRESULT PrimarySurface::create(

View File

@ -43,6 +43,18 @@ 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)

View File

@ -19,6 +19,7 @@ namespace DDraw
static TagSurface* get(CompatRef<IDirectDraw> dd);
static TagSurface* findFullscreenWindow(HWND hwnd);
static bool doesFullscreenDirectDrawExist();
static void forEachDirectDraw(std::function<void(CompatRef<IDirectDraw7>)> callback);
void setFullscreenWindow(HWND hwnd);