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:
parent
d39a4ab0fc
commit
bf58555d22
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user