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();
|
void onRelease();
|
||||||
|
|
||||||
|
CompatWeakPtr<IDirectDraw7> g_defaultPrimaryDD;
|
||||||
|
CompatWeakPtr<IDirectDrawSurface7> g_defaultPrimary;
|
||||||
|
|
||||||
CompatWeakPtr<IDirectDrawSurface7> g_frontBuffer;
|
CompatWeakPtr<IDirectDrawSurface7> g_frontBuffer;
|
||||||
CompatWeakPtr<IDirectDrawSurface7> g_windowedBackBuffer;
|
CompatWeakPtr<IDirectDrawSurface7> g_windowedBackBuffer;
|
||||||
CompatWeakPtr<IDirectDrawClipper> g_clipper;
|
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)
|
CompatPtr<IDirectDrawSurface7> createWindowedBackBuffer(DDRAWI_DIRECTDRAW_LCL* ddLcl, DWORD width, DWORD height)
|
||||||
{
|
{
|
||||||
if (!ddLcl)
|
if (!ddLcl)
|
||||||
@ -361,6 +423,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
DDraw::ScopedThreadLock lock;
|
DDraw::ScopedThreadLock lock;
|
||||||
|
createDefaultPrimary();
|
||||||
updatePresentationWindowPos();
|
updatePresentationWindowPos();
|
||||||
msUntilUpdateReady = DDraw::RealPrimarySurface::flush();
|
msUntilUpdateReady = DDraw::RealPrimarySurface::flush();
|
||||||
}
|
}
|
||||||
@ -372,6 +435,7 @@ namespace DDraw
|
|||||||
template <typename DirectDraw>
|
template <typename DirectDraw>
|
||||||
HRESULT RealPrimarySurface::create(CompatRef<DirectDraw> dd)
|
HRESULT RealPrimarySurface::create(CompatRef<DirectDraw> dd)
|
||||||
{
|
{
|
||||||
|
LOG_FUNC("RealPrimarySurface::create", &dd);
|
||||||
DDraw::ScopedThreadLock lock;
|
DDraw::ScopedThreadLock lock;
|
||||||
g_monitorRect = D3dDdi::KernelModeThunks::getAdapterInfo(*CompatPtr<IDirectDraw7>::from(&dd)).monitorInfo.rcMonitor;
|
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<IDirectDraw4>);
|
||||||
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw7>);
|
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw7>);
|
||||||
|
|
||||||
|
void RealPrimarySurface::destroyDefaultPrimary()
|
||||||
|
{
|
||||||
|
g_defaultPrimary.release();
|
||||||
|
g_defaultPrimaryDD.release();
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT RealPrimarySurface::flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags)
|
HRESULT RealPrimarySurface::flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags)
|
||||||
{
|
{
|
||||||
const DWORD flipInterval = getFlipInterval(flags);
|
const DWORD flipInterval = getFlipInterval(flags);
|
||||||
|
@ -15,6 +15,7 @@ namespace DDraw
|
|||||||
template <typename DirectDraw>
|
template <typename DirectDraw>
|
||||||
static HRESULT create(CompatRef<DirectDraw> dd);
|
static HRESULT create(CompatRef<DirectDraw> dd);
|
||||||
|
|
||||||
|
static void destroyDefaultPrimary();
|
||||||
static HRESULT flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags);
|
static HRESULT flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags);
|
||||||
static int flush();
|
static int flush();
|
||||||
static HWND getDevicePresentationWindow();
|
static HWND getDevicePresentationWindow();
|
||||||
|
@ -50,6 +50,8 @@ namespace DDraw
|
|||||||
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
|
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
|
||||||
HRESULT PrimarySurface::create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface)
|
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));
|
const auto& dm = DDraw::DirectDraw::getDisplayMode(*CompatPtr<IDirectDraw7>::from(&dd));
|
||||||
g_monitorRect = D3dDdi::KernelModeThunks::getAdapterInfo(*CompatPtr<IDirectDraw7>::from(&dd)).monitorInfo.rcMonitor;
|
g_monitorRect = D3dDdi::KernelModeThunks::getAdapterInfo(*CompatPtr<IDirectDraw7>::from(&dd)).monitorInfo.rcMonitor;
|
||||||
g_monitorRect.right = g_monitorRect.left + dm.dwWidth;
|
g_monitorRect.right = g_monitorRect.left + dm.dwWidth;
|
||||||
@ -58,7 +60,7 @@ namespace DDraw
|
|||||||
HRESULT result = RealPrimarySurface::create(dd);
|
HRESULT result = RealPrimarySurface::create(dd);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
return result;
|
return LOG_RESULT(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
const DWORD origCaps = desc.ddsCaps.dwCaps;
|
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);
|
LOG_INFO << "ERROR: Failed to create the compat primary surface: " << Compat::hex(result);
|
||||||
g_monitorRect = {};
|
g_monitorRect = {};
|
||||||
RealPrimarySurface::release();
|
RealPrimarySurface::release();
|
||||||
return result;
|
return LOG_RESULT(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_origCaps = origCaps;
|
g_origCaps = origCaps;
|
||||||
@ -97,7 +99,7 @@ namespace DDraw
|
|||||||
g_device = D3dDdi::Device::findDeviceByResource(DirectDrawSurface::getDriverResourceHandle(*surface));
|
g_device = D3dDdi::Device::findDeviceByResource(DirectDrawSurface::getDriverResourceHandle(*surface));
|
||||||
data->restore();
|
data->restore();
|
||||||
D3dDdi::Device::updateAllConfig();
|
D3dDdi::Device::updateAllConfig();
|
||||||
return DD_OK;
|
return LOG_RESULT(DD_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
template HRESULT PrimarySurface::create(
|
template HRESULT PrimarySurface::create(
|
||||||
|
@ -43,6 +43,18 @@ namespace DDraw
|
|||||||
return Surface::create(dd, desc, surface, std::move(privateData));
|
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)
|
TagSurface* TagSurface::findFullscreenWindow(HWND hwnd)
|
||||||
{
|
{
|
||||||
for (auto& pair : g_ddObjects)
|
for (auto& pair : g_ddObjects)
|
||||||
|
@ -19,6 +19,7 @@ namespace DDraw
|
|||||||
static TagSurface* get(CompatRef<IDirectDraw> dd);
|
static TagSurface* get(CompatRef<IDirectDraw> dd);
|
||||||
static TagSurface* findFullscreenWindow(HWND hwnd);
|
static TagSurface* findFullscreenWindow(HWND hwnd);
|
||||||
|
|
||||||
|
static bool doesFullscreenDirectDrawExist();
|
||||||
static void forEachDirectDraw(std::function<void(CompatRef<IDirectDraw7>)> callback);
|
static void forEachDirectDraw(std::function<void(CompatRef<IDirectDraw7>)> callback);
|
||||||
|
|
||||||
void setFullscreenWindow(HWND hwnd);
|
void setFullscreenWindow(HWND hwnd);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user