mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added FullscreenMode setting
This commit is contained in:
parent
fb9f28456e
commit
55eab96f78
@ -11,6 +11,7 @@ namespace Config
|
|||||||
Settings::DisplayRefreshRate displayRefreshRate;
|
Settings::DisplayRefreshRate displayRefreshRate;
|
||||||
Settings::DisplayResolution displayResolution;
|
Settings::DisplayResolution displayResolution;
|
||||||
Settings::ForceD3D9On12 forceD3D9On12;
|
Settings::ForceD3D9On12 forceD3D9On12;
|
||||||
|
Settings::FullscreenMode fullscreenMode;
|
||||||
Settings::RenderColorDepth renderColorDepth;
|
Settings::RenderColorDepth renderColorDepth;
|
||||||
Settings::ResolutionScale resolutionScale;
|
Settings::ResolutionScale resolutionScale;
|
||||||
Settings::SpriteDetection spriteDetection;
|
Settings::SpriteDetection spriteDetection;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <Config/Settings/DisplayRefreshRate.h>
|
#include <Config/Settings/DisplayRefreshRate.h>
|
||||||
#include <Config/Settings/DisplayResolution.h>
|
#include <Config/Settings/DisplayResolution.h>
|
||||||
#include <Config/Settings/ForceD3D9On12.h>
|
#include <Config/Settings/ForceD3D9On12.h>
|
||||||
|
#include <Config/Settings/FullscreenMode.h>
|
||||||
#include <Config/Settings/RenderColorDepth.h>
|
#include <Config/Settings/RenderColorDepth.h>
|
||||||
#include <Config/Settings/ResolutionScale.h>
|
#include <Config/Settings/ResolutionScale.h>
|
||||||
#include <Config/Settings/SpriteDetection.h>
|
#include <Config/Settings/SpriteDetection.h>
|
||||||
@ -32,6 +33,7 @@ namespace Config
|
|||||||
extern Settings::DisplayRefreshRate displayRefreshRate;
|
extern Settings::DisplayRefreshRate displayRefreshRate;
|
||||||
extern Settings::DisplayResolution displayResolution;
|
extern Settings::DisplayResolution displayResolution;
|
||||||
extern Settings::ForceD3D9On12 forceD3D9On12;
|
extern Settings::ForceD3D9On12 forceD3D9On12;
|
||||||
|
extern Settings::FullscreenMode fullscreenMode;
|
||||||
extern Settings::RenderColorDepth renderColorDepth;
|
extern Settings::RenderColorDepth renderColorDepth;
|
||||||
extern Settings::ResolutionScale resolutionScale;
|
extern Settings::ResolutionScale resolutionScale;
|
||||||
extern Settings::SpriteDetection spriteDetection;
|
extern Settings::SpriteDetection spriteDetection;
|
||||||
|
21
DDrawCompat/Config/Settings/FullscreenMode.h
Normal file
21
DDrawCompat/Config/Settings/FullscreenMode.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Config/MappedSetting.h>
|
||||||
|
|
||||||
|
namespace Config
|
||||||
|
{
|
||||||
|
namespace Settings
|
||||||
|
{
|
||||||
|
class FullscreenMode : public MappedSetting<UINT>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const UINT BORDERLESS = 0;
|
||||||
|
static const UINT EXCLUSIVE = 1;
|
||||||
|
|
||||||
|
FullscreenMode()
|
||||||
|
: MappedSetting("FullscreenMode", "borderless", { {"borderless", BORDERLESS}, {"exclusive", EXCLUSIVE} })
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,10 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <winternl.h>
|
||||||
|
#include <d3dkmthk.h>
|
||||||
|
|
||||||
#include <Common/Hook.h>
|
#include <Common/Hook.h>
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
#include <D3dDdi/Adapter.h>
|
#include <D3dDdi/Adapter.h>
|
||||||
@ -9,6 +13,7 @@
|
|||||||
#include <D3dDdi/Hooks.h>
|
#include <D3dDdi/Hooks.h>
|
||||||
#include <D3dDdi/KernelModeThunks.h>
|
#include <D3dDdi/KernelModeThunks.h>
|
||||||
#include <D3dDdi/ScopedCriticalSection.h>
|
#include <D3dDdi/ScopedCriticalSection.h>
|
||||||
|
#include <D3dDdi/Log/KernelModeThunksLog.h>
|
||||||
#include <Dll/Dll.h>
|
#include <Dll/Dll.h>
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_OPENADAPTER& data)
|
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_OPENADAPTER& data)
|
||||||
@ -28,26 +33,36 @@ namespace
|
|||||||
|
|
||||||
typedef HRESULT(APIENTRY* PFND3D9ON12_OPENADAPTER)(
|
typedef HRESULT(APIENTRY* PFND3D9ON12_OPENADAPTER)(
|
||||||
D3DDDIARG_OPENADAPTER* pOpenAdapter, LUID* pLUID, D3D9ON12_CREATE_DEVICE_ARGS* pArgs);
|
D3DDDIARG_OPENADAPTER* pOpenAdapter, LUID* pLUID, D3D9ON12_CREATE_DEVICE_ARGS* pArgs);
|
||||||
|
typedef HRESULT(APIENTRY* PFND3D9ON12_KMTPRESENT)(
|
||||||
|
HANDLE hDevice, D3DKMT_PRESENT* pKMTArgs);
|
||||||
|
|
||||||
struct D3D9ON12_PRIVATE_DDI_TABLE
|
struct D3D9ON12_PRIVATE_DDI_TABLE
|
||||||
{
|
{
|
||||||
PFND3D9ON12_OPENADAPTER pfnOpenAdapter;
|
PFND3D9ON12_OPENADAPTER pfnOpenAdapter;
|
||||||
|
FARPROC pfnGetSharedGDIHandle;
|
||||||
|
FARPROC pfnCreateSharedNTHandle;
|
||||||
|
FARPROC pfnGetDeviceState;
|
||||||
|
PFND3D9ON12_KMTPRESENT pfnKMTPresent;
|
||||||
};
|
};
|
||||||
|
|
||||||
void APIENTRY getPrivateDdiTable(D3D9ON12_PRIVATE_DDI_TABLE* pPrivateDDITable);
|
void APIENTRY getPrivateDdiTable(D3D9ON12_PRIVATE_DDI_TABLE* pPrivateDDITable);
|
||||||
|
HRESULT APIENTRY kmtPresent(HANDLE hDevice, D3DKMT_PRESENT* pKMTArgs);
|
||||||
HRESULT APIENTRY openAdapter(D3DDDIARG_OPENADAPTER* pOpenData);
|
HRESULT APIENTRY openAdapter(D3DDDIARG_OPENADAPTER* pOpenData);
|
||||||
HRESULT APIENTRY openAdapterPrivate(D3DDDIARG_OPENADAPTER* pOpenData, LUID* pLUID, D3D9ON12_CREATE_DEVICE_ARGS* pArgs);
|
HRESULT APIENTRY openAdapterPrivate(D3DDDIARG_OPENADAPTER* pOpenData, LUID* pLUID, D3D9ON12_CREATE_DEVICE_ARGS* pArgs);
|
||||||
|
|
||||||
decltype(&getPrivateDdiTable) g_origGetPrivateDdiTable = nullptr;
|
decltype(&getPrivateDdiTable) g_origGetPrivateDdiTable = nullptr;
|
||||||
PFND3DDDI_OPENADAPTER g_origOpenAdapter = nullptr;
|
PFND3DDDI_OPENADAPTER g_origOpenAdapter = nullptr;
|
||||||
PFND3D9ON12_OPENADAPTER g_origOpenAdapterPrivate = nullptr;
|
PFND3D9ON12_OPENADAPTER g_origOpenAdapterPrivate = nullptr;
|
||||||
|
PFND3D9ON12_KMTPRESENT g_origKmtPresent = nullptr;
|
||||||
|
|
||||||
void APIENTRY getPrivateDdiTable(D3D9ON12_PRIVATE_DDI_TABLE* pPrivateDDITable)
|
void APIENTRY getPrivateDdiTable(D3D9ON12_PRIVATE_DDI_TABLE* pPrivateDDITable)
|
||||||
{
|
{
|
||||||
LOG_FUNC("GetPrivateDDITable", pPrivateDDITable);
|
LOG_FUNC("GetPrivateDDITable", pPrivateDDITable);
|
||||||
g_origGetPrivateDdiTable(pPrivateDDITable);
|
g_origGetPrivateDdiTable(pPrivateDDITable);
|
||||||
g_origOpenAdapterPrivate = pPrivateDDITable->pfnOpenAdapter;
|
g_origOpenAdapterPrivate = pPrivateDDITable->pfnOpenAdapter;
|
||||||
|
g_origKmtPresent = pPrivateDDITable->pfnKMTPresent;
|
||||||
pPrivateDDITable->pfnOpenAdapter = &openAdapterPrivate;
|
pPrivateDDITable->pfnOpenAdapter = &openAdapterPrivate;
|
||||||
|
pPrivateDDITable->pfnKMTPresent = &kmtPresent;
|
||||||
}
|
}
|
||||||
|
|
||||||
FARPROC WINAPI getProcAddress(HMODULE hModule, LPCSTR lpProcName)
|
FARPROC WINAPI getProcAddress(HMODULE hModule, LPCSTR lpProcName)
|
||||||
@ -84,6 +99,13 @@ namespace
|
|||||||
return LOG_RESULT(CALL_ORIG_FUNC(GetProcAddress)(hModule, lpProcName));
|
return LOG_RESULT(CALL_ORIG_FUNC(GetProcAddress)(hModule, lpProcName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT APIENTRY kmtPresent(HANDLE hDevice, D3DKMT_PRESENT* pKMTArgs)
|
||||||
|
{
|
||||||
|
LOG_FUNC("KMTPresent", hDevice, pKMTArgs);
|
||||||
|
D3dDdi::KernelModeThunks::fixPresent(*pKMTArgs);
|
||||||
|
return LOG_RESULT(g_origKmtPresent(hDevice, pKMTArgs));
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT openAdapterCommon(D3DDDIARG_OPENADAPTER* pOpenData, std::function<HRESULT()> origOpenAdapter)
|
HRESULT openAdapterCommon(D3DDDIARG_OPENADAPTER* pOpenData, std::function<HRESULT()> origOpenAdapter)
|
||||||
{
|
{
|
||||||
D3dDdi::ScopedCriticalSection lock;
|
D3dDdi::ScopedCriticalSection lock;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <DDraw/ScopedThreadLock.h>
|
#include <DDraw/ScopedThreadLock.h>
|
||||||
#include <DDraw/Surfaces/PrimarySurface.h>
|
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||||
#include <Gdi/Palette.h>
|
#include <Gdi/Palette.h>
|
||||||
|
#include <Gdi/Window.h>
|
||||||
#include <Win32/DisplayMode.h>
|
#include <Win32/DisplayMode.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -28,6 +29,8 @@ namespace
|
|||||||
D3dDdi::KernelModeThunks::AdapterInfo g_lastOpenAdapterInfo = {};
|
D3dDdi::KernelModeThunks::AdapterInfo g_lastOpenAdapterInfo = {};
|
||||||
Compat::SrwLock g_adapterInfoSrwLock;
|
Compat::SrwLock g_adapterInfoSrwLock;
|
||||||
std::string g_lastDDrawDeviceName;
|
std::string g_lastDDrawDeviceName;
|
||||||
|
decltype(&D3DKMTSubmitPresentBltToHwQueue) g_origSubmitPresentBltToHwQueue = nullptr;
|
||||||
|
decltype(&D3DKMTSubmitPresentToHwQueue) g_origSubmitPresentToHwQueue = nullptr;
|
||||||
|
|
||||||
long long g_qpcLastVsync = 0;
|
long long g_qpcLastVsync = 0;
|
||||||
UINT g_vsyncCounter = 0;
|
UINT g_vsyncCounter = 0;
|
||||||
@ -199,6 +202,13 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS APIENTRY present(D3DKMT_PRESENT* pData)
|
||||||
|
{
|
||||||
|
LOG_FUNC("D3DKMTPresent", pData);
|
||||||
|
D3dDdi::KernelModeThunks::fixPresent(*pData);
|
||||||
|
return LOG_RESULT(D3DKMTPresent(pData));
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS APIENTRY queryAdapterInfo(const D3DKMT_QUERYADAPTERINFO* pData)
|
NTSTATUS APIENTRY queryAdapterInfo(const D3DKMT_QUERYADAPTERINFO* pData)
|
||||||
{
|
{
|
||||||
LOG_FUNC("D3DKMTQueryAdapterInfo", pData);
|
LOG_FUNC("D3DKMTQueryAdapterInfo", pData);
|
||||||
@ -251,6 +261,20 @@ namespace
|
|||||||
return LOG_RESULT(result);
|
return LOG_RESULT(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS APIENTRY submitPresentToHwQueue(D3DKMT_SUBMITPRESENTTOHWQUEUE* pData)
|
||||||
|
{
|
||||||
|
LOG_FUNC("D3DKMTSubmitPresentToHwQueue", pData);
|
||||||
|
D3dDdi::KernelModeThunks::fixPresent(pData->PrivatePresentData);
|
||||||
|
return LOG_RESULT(g_origSubmitPresentToHwQueue(pData));
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS APIENTRY submitPresentBltToHwQueue(const D3DKMT_SUBMITPRESENTBLTTOHWQUEUE* pData)
|
||||||
|
{
|
||||||
|
LOG_FUNC("D3DKMTSubmitPresentBltToHwQueue", pData);
|
||||||
|
D3dDdi::KernelModeThunks::fixPresent(const_cast<D3DKMT_PRESENT&>(pData->PrivatePresentData));
|
||||||
|
return LOG_RESULT(g_origSubmitPresentBltToHwQueue(pData));
|
||||||
|
}
|
||||||
|
|
||||||
void updateGdiAdapterInfo()
|
void updateGdiAdapterInfo()
|
||||||
{
|
{
|
||||||
static auto lastDisplaySettingsUniqueness = Win32::DisplayMode::queryDisplaySettingsUniqueness() - 1;
|
static auto lastDisplaySettingsUniqueness = Win32::DisplayMode::queryDisplaySettingsUniqueness() - 1;
|
||||||
@ -331,6 +355,27 @@ namespace D3dDdi
|
|||||||
{
|
{
|
||||||
namespace KernelModeThunks
|
namespace KernelModeThunks
|
||||||
{
|
{
|
||||||
|
void fixPresent(D3DKMT_PRESENT& data)
|
||||||
|
{
|
||||||
|
static RECT rect = {};
|
||||||
|
if (DDraw::RealPrimarySurface::isFullscreen())
|
||||||
|
{
|
||||||
|
HWND devicePresentationWindow = DDraw::RealPrimarySurface::getDevicePresentationWindow();
|
||||||
|
if (devicePresentationWindow && devicePresentationWindow == data.hWindow)
|
||||||
|
{
|
||||||
|
rect = DDraw::RealPrimarySurface::getMonitorRect();
|
||||||
|
OffsetRect(&rect, -rect.left, -rect.top);
|
||||||
|
data.SrcRect = rect;
|
||||||
|
data.DstRect.right = data.DstRect.left + rect.right;
|
||||||
|
data.DstRect.bottom = data.DstRect.top + rect.bottom;
|
||||||
|
if (1 == data.SubRectCnt)
|
||||||
|
{
|
||||||
|
data.pSrcSubRects = ▭
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AdapterInfo getAdapterInfo(CompatRef<IDirectDraw7> dd)
|
AdapterInfo getAdapterInfo(CompatRef<IDirectDraw7> dd)
|
||||||
{
|
{
|
||||||
DDraw::ScopedThreadLock lock;
|
DDraw::ScopedThreadLock lock;
|
||||||
@ -359,12 +404,19 @@ namespace D3dDdi
|
|||||||
|
|
||||||
void installHooks()
|
void installHooks()
|
||||||
{
|
{
|
||||||
|
g_origSubmitPresentBltToHwQueue = reinterpret_cast<decltype(&D3DKMTSubmitPresentBltToHwQueue)>(
|
||||||
|
GetProcAddress(GetModuleHandle("gdi32"), "D3DKMTSubmitPresentBltToHwQueue"));
|
||||||
|
g_origSubmitPresentToHwQueue = reinterpret_cast<decltype(&D3DKMTSubmitPresentToHwQueue)>(
|
||||||
|
GetProcAddress(GetModuleHandle("gdi32"), "D3DKMTSubmitPresentToHwQueue"));
|
||||||
|
|
||||||
Compat::hookIatFunction(Dll::g_origDDrawModule, "CreateDCA", ddrawCreateDcA);
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "CreateDCA", ddrawCreateDcA);
|
||||||
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTCloseAdapter", closeAdapter);
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTCloseAdapter", closeAdapter);
|
||||||
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTCreateDCFromMemory", createDcFromMemory);
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTCreateDCFromMemory", createDcFromMemory);
|
||||||
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTOpenAdapterFromHdc", openAdapterFromHdc);
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTOpenAdapterFromHdc", openAdapterFromHdc);
|
||||||
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTPresent", present);
|
||||||
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTQueryAdapterInfo", queryAdapterInfo);
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTQueryAdapterInfo", queryAdapterInfo);
|
||||||
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTSetGammaRamp", setGammaRamp);
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTSetGammaRamp", setGammaRamp);
|
||||||
|
Compat::hookIatFunction(Dll::g_origDDrawModule, "D3DKMTSubmitPresentToHwQueue", submitPresentToHwQueue);
|
||||||
|
|
||||||
Dll::createThread(&vsyncThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL);
|
Dll::createThread(&vsyncThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <winternl.h>
|
||||||
|
#include <d3dkmthk.h>
|
||||||
|
|
||||||
#include <ddraw.h>
|
#include <ddraw.h>
|
||||||
|
|
||||||
#include <Common/CompatRef.h>
|
#include <Common/CompatRef.h>
|
||||||
@ -16,6 +20,7 @@ namespace D3dDdi
|
|||||||
MONITORINFOEXW monitorInfo;
|
MONITORINFOEXW monitorInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void fixPresent(D3DKMT_PRESENT& data);
|
||||||
AdapterInfo getAdapterInfo(CompatRef<IDirectDraw7> dd);
|
AdapterInfo getAdapterInfo(CompatRef<IDirectDraw7> dd);
|
||||||
AdapterInfo getLastOpenAdapterInfo();
|
AdapterInfo getLastOpenAdapterInfo();
|
||||||
long long getQpcLastVsync();
|
long long getQpcLastVsync();
|
||||||
|
@ -163,3 +163,18 @@ std::ostream& operator<<(std::ostream& os, const D3DKMT_SETVIDPNSOURCEOWNER1& da
|
|||||||
<< data.Version0
|
<< data.Version0
|
||||||
<< Compat::hex(data.Flags.Value);
|
<< Compat::hex(data.Flags.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const D3DKMT_SUBMITPRESENTTOHWQUEUE& data)
|
||||||
|
{
|
||||||
|
return Compat::LogStruct(os)
|
||||||
|
<< Compat::array(data.hHwQueues, data.PrivatePresentData.BroadcastContextCount + 1)
|
||||||
|
<< data.PrivatePresentData;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const D3DKMT_SUBMITPRESENTBLTTOHWQUEUE& data)
|
||||||
|
{
|
||||||
|
return Compat::LogStruct(os)
|
||||||
|
<< Compat::hex(data.hHwQueue)
|
||||||
|
<< Compat::hex(data.HwQueueProgressFenceId)
|
||||||
|
<< data.PrivatePresentData;
|
||||||
|
}
|
||||||
|
@ -23,3 +23,5 @@ std::ostream& operator<<(std::ostream& os, const D3DKMT_SETGAMMARAMP& data);
|
|||||||
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETQUEUEDLIMIT& data);
|
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETQUEUEDLIMIT& data);
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETVIDPNSOURCEOWNER& data);
|
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETVIDPNSOURCEOWNER& data);
|
||||||
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETVIDPNSOURCEOWNER1& data);
|
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETVIDPNSOURCEOWNER1& data);
|
||||||
|
std::ostream& operator<<(std::ostream& os, const D3DKMT_SUBMITPRESENTTOHWQUEUE& data);
|
||||||
|
std::ostream& operator<<(std::ostream& os, const D3DKMT_SUBMITPRESENTBLTTOHWQUEUE& data);
|
||||||
|
@ -126,7 +126,7 @@ namespace D3dDdi
|
|||||||
throw HResultException(E_FAIL);
|
throw HResultException(E_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_origData.Flags.Primary)
|
if (m_origData.Flags.MatchGdiPrimary)
|
||||||
{
|
{
|
||||||
g_presentationRect = calculatePresentationRect();
|
g_presentationRect = calculatePresentationRect();
|
||||||
auto& si = m_origData.pSurfList[0];
|
auto& si = m_origData.pSurfList[0];
|
||||||
@ -175,7 +175,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
Resource::~Resource()
|
Resource::~Resource()
|
||||||
{
|
{
|
||||||
if (m_origData.Flags.Primary)
|
if (m_origData.Flags.MatchGdiPrimary)
|
||||||
{
|
{
|
||||||
Gdi::VirtualScreen::setFullscreenMode(false);
|
Gdi::VirtualScreen::setFullscreenMode(false);
|
||||||
Gdi::Cursor::setEmulated(false);
|
Gdi::Cursor::setEmulated(false);
|
||||||
@ -215,7 +215,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
if (srcResource)
|
if (srcResource)
|
||||||
{
|
{
|
||||||
if (m_fixedData.Flags.Primary)
|
if (m_fixedData.Flags.MatchGdiPrimary)
|
||||||
{
|
{
|
||||||
return presentationBlt(data, srcResource);
|
return presentationBlt(data, srcResource);
|
||||||
}
|
}
|
||||||
@ -486,7 +486,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
void Resource::fixResourceData()
|
void Resource::fixResourceData()
|
||||||
{
|
{
|
||||||
if (m_fixedData.Flags.Primary)
|
if (m_fixedData.Flags.MatchGdiPrimary)
|
||||||
{
|
{
|
||||||
RECT r = DDraw::RealPrimarySurface::getMonitorRect();
|
RECT r = DDraw::RealPrimarySurface::getMonitorRect();
|
||||||
if (!IsRectEmpty(&r))
|
if (!IsRectEmpty(&r))
|
||||||
@ -538,7 +538,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
D3DDDIFORMAT Resource::getFormatConfig()
|
D3DDDIFORMAT Resource::getFormatConfig()
|
||||||
{
|
{
|
||||||
if (m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.Primary && D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool &&
|
if (m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.MatchGdiPrimary && D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool &&
|
||||||
(D3DDDIFMT_X8R8G8B8 == m_fixedData.Format || D3DDDIFMT_R5G6B5 == m_fixedData.Format))
|
(D3DDDIFMT_X8R8G8B8 == m_fixedData.Format || D3DDDIFMT_R5G6B5 == m_fixedData.Format))
|
||||||
{
|
{
|
||||||
switch (Config::renderColorDepth.get())
|
switch (Config::renderColorDepth.get())
|
||||||
@ -552,7 +552,7 @@ namespace D3dDdi
|
|||||||
|
|
||||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> Resource::getMultisampleConfig()
|
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> Resource::getMultisampleConfig()
|
||||||
{
|
{
|
||||||
if ((m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.Texture && !m_fixedData.Flags.Primary ||
|
if ((m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.Texture && !m_fixedData.Flags.MatchGdiPrimary ||
|
||||||
m_fixedData.Flags.ZBuffer) &&
|
m_fixedData.Flags.ZBuffer) &&
|
||||||
D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool)
|
D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool)
|
||||||
{
|
{
|
||||||
@ -570,7 +570,7 @@ namespace D3dDdi
|
|||||||
SIZE Resource::getScaledSize()
|
SIZE Resource::getScaledSize()
|
||||||
{
|
{
|
||||||
SIZE size = { static_cast<LONG>(m_fixedData.pSurfList[0].Width), static_cast<LONG>(m_fixedData.pSurfList[0].Height) };
|
SIZE size = { static_cast<LONG>(m_fixedData.pSurfList[0].Width), static_cast<LONG>(m_fixedData.pSurfList[0].Height) };
|
||||||
if ((m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.Texture && !m_fixedData.Flags.Primary ||
|
if ((m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.Texture && !m_fixedData.Flags.MatchGdiPrimary ||
|
||||||
m_fixedData.Flags.ZBuffer) &&
|
m_fixedData.Flags.ZBuffer) &&
|
||||||
D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool)
|
D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool)
|
||||||
{
|
{
|
||||||
|
@ -15,9 +15,9 @@ namespace DDraw
|
|||||||
void suppressEmulatedDirectDraw(GUID*& guid);
|
void suppressEmulatedDirectDraw(GUID*& guid);
|
||||||
|
|
||||||
template <typename TDirectDraw>
|
template <typename TDirectDraw>
|
||||||
HWND getDeviceWindow(TDirectDraw& dd)
|
HWND* getDeviceWindowPtr(TDirectDraw& dd)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<HWND**>(&dd)[1][8];
|
return &reinterpret_cast<HWND**>(&dd)[1][8];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Vtable>
|
template <typename Vtable>
|
||||||
|
@ -45,6 +45,9 @@ namespace
|
|||||||
std::atomic<long long> g_qpcLastUpdate = 0;
|
std::atomic<long long> g_qpcLastUpdate = 0;
|
||||||
UINT g_flipEndVsyncCount = 0;
|
UINT g_flipEndVsyncCount = 0;
|
||||||
UINT g_presentEndVsyncCount = 0;
|
UINT g_presentEndVsyncCount = 0;
|
||||||
|
HWND g_devicePresentationWindow = nullptr;
|
||||||
|
HWND g_deviceWindow = nullptr;
|
||||||
|
HWND* g_deviceWindowPtr = nullptr;
|
||||||
|
|
||||||
CompatPtr<IDirectDrawSurface7> getBackBuffer();
|
CompatPtr<IDirectDrawSurface7> getBackBuffer();
|
||||||
CompatPtr<IDirectDrawSurface7> getLastSurface();
|
CompatPtr<IDirectDrawSurface7> getLastSurface();
|
||||||
@ -128,6 +131,11 @@ namespace
|
|||||||
g_isFullscreen = false;
|
g_isFullscreen = false;
|
||||||
g_waitingForPrimaryUnlock = false;
|
g_waitingForPrimaryUnlock = false;
|
||||||
g_surfaceDesc = {};
|
g_surfaceDesc = {};
|
||||||
|
|
||||||
|
DDraw::RealPrimarySurface::updateDevicePresentationWindowPos();
|
||||||
|
g_devicePresentationWindow = nullptr;
|
||||||
|
g_deviceWindow = nullptr;
|
||||||
|
g_deviceWindowPtr = nullptr;
|
||||||
g_monitorRect = {};
|
g_monitorRect = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,9 +208,11 @@ namespace
|
|||||||
g_isUpdatePending = false;
|
g_isUpdatePending = false;
|
||||||
g_waitingForPrimaryUnlock = false;
|
g_waitingForPrimaryUnlock = false;
|
||||||
|
|
||||||
if (g_isFullscreen)
|
if (g_isFullscreen && g_devicePresentationWindow)
|
||||||
{
|
{
|
||||||
|
*g_deviceWindowPtr = g_devicePresentationWindow;
|
||||||
g_frontBuffer->Flip(g_frontBuffer, getBackBuffer(), DDFLIP_WAIT);
|
g_frontBuffer->Flip(g_frontBuffer, getBackBuffer(), DDFLIP_WAIT);
|
||||||
|
*g_deviceWindowPtr = g_deviceWindow;
|
||||||
}
|
}
|
||||||
g_presentEndVsyncCount = D3dDdi::KernelModeThunks::getVsyncCounter() + max(flipInterval, 1);
|
g_presentEndVsyncCount = D3dDdi::KernelModeThunks::getVsyncCounter() + max(flipInterval, 1);
|
||||||
}
|
}
|
||||||
@ -296,7 +306,13 @@ namespace DDraw
|
|||||||
g_frontBuffer = CompatPtr<IDirectDrawSurface7>::from(surface.get()).detach();
|
g_frontBuffer = CompatPtr<IDirectDrawSurface7>::from(surface.get()).detach();
|
||||||
g_frontBuffer->SetPrivateData(g_frontBuffer, IID_IReleaseNotifier,
|
g_frontBuffer->SetPrivateData(g_frontBuffer, IID_IReleaseNotifier,
|
||||||
&g_releaseNotifier, sizeof(&g_releaseNotifier), DDSPD_IUNKNOWNPOINTER);
|
&g_releaseNotifier, sizeof(&g_releaseNotifier), DDSPD_IUNKNOWNPOINTER);
|
||||||
|
|
||||||
|
g_deviceWindowPtr = DDraw::DirectDraw::getDeviceWindowPtr(dd.get());
|
||||||
|
g_deviceWindow = g_deviceWindowPtr ? *g_deviceWindowPtr : nullptr;
|
||||||
|
g_devicePresentationWindow = Gdi::Window::getPresentationWindow(g_deviceWindow);
|
||||||
|
|
||||||
onRestore();
|
onRestore();
|
||||||
|
updateDevicePresentationWindowPos();
|
||||||
|
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
@ -354,6 +370,11 @@ namespace DDraw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HWND RealPrimarySurface::getDevicePresentationWindow()
|
||||||
|
{
|
||||||
|
return g_devicePresentationWindow;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT RealPrimarySurface::getGammaRamp(DDGAMMARAMP* rampData)
|
HRESULT RealPrimarySurface::getGammaRamp(DDGAMMARAMP* rampData)
|
||||||
{
|
{
|
||||||
DDraw::ScopedThreadLock lock;
|
DDraw::ScopedThreadLock lock;
|
||||||
@ -376,6 +397,15 @@ namespace DDraw
|
|||||||
return g_frontBuffer;
|
return g_frontBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HWND RealPrimarySurface::getTopmost()
|
||||||
|
{
|
||||||
|
if (g_isFullscreen && g_devicePresentationWindow)
|
||||||
|
{
|
||||||
|
return g_devicePresentationWindow;
|
||||||
|
}
|
||||||
|
return HWND_TOPMOST;
|
||||||
|
}
|
||||||
|
|
||||||
void RealPrimarySurface::init()
|
void RealPrimarySurface::init()
|
||||||
{
|
{
|
||||||
Dll::createThread(&updateThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL);
|
Dll::createThread(&updateThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL);
|
||||||
@ -438,6 +468,28 @@ namespace DDraw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RealPrimarySurface::updateDevicePresentationWindowPos()
|
||||||
|
{
|
||||||
|
if (!g_devicePresentationWindow)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gdi::GuiThread::execute([&]()
|
||||||
|
{
|
||||||
|
if (g_isFullscreen && IsWindowVisible(g_deviceWindow) && !IsIconic(g_deviceWindow))
|
||||||
|
{
|
||||||
|
CALL_ORIG_FUNC(SetWindowPos)(g_devicePresentationWindow, HWND_TOPMOST, g_monitorRect.left, g_monitorRect.top,
|
||||||
|
g_monitorRect.right - g_monitorRect.left, g_monitorRect.bottom - g_monitorRect.top,
|
||||||
|
SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_NOREDRAW | SWP_NOOWNERZORDER | SWP_SHOWWINDOW);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Gdi::Window::updatePresentationWindowPos(g_devicePresentationWindow, g_deviceWindow);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bool RealPrimarySurface::waitForFlip(Surface* surface)
|
bool RealPrimarySurface::waitForFlip(Surface* surface)
|
||||||
{
|
{
|
||||||
auto primary(DDraw::PrimarySurface::getPrimary());
|
auto primary(DDraw::PrimarySurface::getPrimary());
|
||||||
|
@ -17,9 +17,11 @@ namespace DDraw
|
|||||||
|
|
||||||
static HRESULT flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags);
|
static HRESULT flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags);
|
||||||
static void flush();
|
static void flush();
|
||||||
|
static HWND getDevicePresentationWindow();
|
||||||
static HRESULT getGammaRamp(DDGAMMARAMP* rampData);
|
static HRESULT getGammaRamp(DDGAMMARAMP* rampData);
|
||||||
static RECT getMonitorRect();
|
static RECT getMonitorRect();
|
||||||
static CompatWeakPtr<IDirectDrawSurface7> getSurface();
|
static CompatWeakPtr<IDirectDrawSurface7> getSurface();
|
||||||
|
static HWND getTopmost();
|
||||||
static void init();
|
static void init();
|
||||||
static bool isFullscreen();
|
static bool isFullscreen();
|
||||||
static bool isLost();
|
static bool isLost();
|
||||||
@ -28,6 +30,7 @@ namespace DDraw
|
|||||||
static void scheduleUpdate();
|
static void scheduleUpdate();
|
||||||
static HRESULT setGammaRamp(DDGAMMARAMP* rampData);
|
static HRESULT setGammaRamp(DDGAMMARAMP* rampData);
|
||||||
static void update();
|
static void update();
|
||||||
|
static void updateDevicePresentationWindowPos();
|
||||||
static bool waitForFlip(Surface* surface);
|
static bool waitForFlip(Surface* surface);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ namespace DDraw
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_origCaps = origCaps;
|
g_origCaps = origCaps;
|
||||||
g_deviceWindow = DDraw::DirectDraw::getDeviceWindow(dd.get());
|
g_deviceWindow = *DDraw::DirectDraw::getDeviceWindowPtr(dd.get());
|
||||||
|
|
||||||
if (desc.ddpfPixelFormat.dwRGBBitCount <= 8)
|
if (desc.ddpfPixelFormat.dwRGBBitCount <= 8)
|
||||||
{
|
{
|
||||||
|
@ -226,6 +226,7 @@
|
|||||||
<ClInclude Include="Config\Settings\DisplayRefreshRate.h" />
|
<ClInclude Include="Config\Settings\DisplayRefreshRate.h" />
|
||||||
<ClInclude Include="Config\Settings\DisplayResolution.h" />
|
<ClInclude Include="Config\Settings\DisplayResolution.h" />
|
||||||
<ClInclude Include="Config\Settings\ForceD3D9On12.h" />
|
<ClInclude Include="Config\Settings\ForceD3D9On12.h" />
|
||||||
|
<ClInclude Include="Config\Settings\FullscreenMode.h" />
|
||||||
<ClInclude Include="Config\Settings\RenderColorDepth.h" />
|
<ClInclude Include="Config\Settings\RenderColorDepth.h" />
|
||||||
<ClInclude Include="Config\Settings\ResolutionScale.h" />
|
<ClInclude Include="Config\Settings\ResolutionScale.h" />
|
||||||
<ClInclude Include="Config\Settings\SpriteDetection.h" />
|
<ClInclude Include="Config\Settings\SpriteDetection.h" />
|
||||||
|
@ -540,6 +540,9 @@
|
|||||||
<ClInclude Include="Config\Settings\ForceD3D9On12.h">
|
<ClInclude Include="Config\Settings\ForceD3D9On12.h">
|
||||||
<Filter>Header Files\Config\Settings</Filter>
|
<Filter>Header Files\Config\Settings</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Config\Settings\FullscreenMode.h">
|
||||||
|
<Filter>Header Files\Config\Settings</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Gdi\Gdi.cpp">
|
<ClCompile Include="Gdi\Gdi.cpp">
|
||||||
|
@ -239,8 +239,11 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||||||
Time::init();
|
Time::init();
|
||||||
Win32::Thread::applyConfig();
|
Win32::Thread::applyConfig();
|
||||||
|
|
||||||
const DWORD disableMaxWindowedMode = 12;
|
if (Config::Settings::FullscreenMode::EXCLUSIVE == Config::fullscreenMode.get())
|
||||||
CALL_ORIG_PROC(SetAppCompatData)(disableMaxWindowedMode, 0);
|
{
|
||||||
|
const DWORD disableMaxWindowedMode = 12;
|
||||||
|
CALL_ORIG_PROC(SetAppCompatData)(disableMaxWindowedMode, 0);
|
||||||
|
}
|
||||||
|
|
||||||
Compat::Log() << "DDrawCompat loaded successfully";
|
Compat::Log() << "DDrawCompat loaded successfully";
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <Gdi/TitleBar.h>
|
#include <Gdi/TitleBar.h>
|
||||||
#include <Gdi/User32WndProcs.h>
|
#include <Gdi/User32WndProcs.h>
|
||||||
#include <Gdi/VirtualScreen.h>
|
#include <Gdi/VirtualScreen.h>
|
||||||
|
#include <Gdi/Window.h>
|
||||||
#include <Gdi/WinProc.h>
|
#include <Gdi/WinProc.h>
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const MENUITEMINFOW& val)
|
std::ostream& operator<<(std::ostream& os, const MENUITEMINFOW& val)
|
||||||
@ -249,6 +250,21 @@ namespace
|
|||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_SETREDRAW:
|
||||||
|
{
|
||||||
|
if (Gdi::Window::isTopLevelWindow(hwnd))
|
||||||
|
{
|
||||||
|
BOOL isVisible = IsWindowVisible(hwnd);
|
||||||
|
auto result = origDefWindowProc(hwnd, msg, wParam, lParam);
|
||||||
|
if (isVisible != IsWindowVisible(hwnd))
|
||||||
|
{
|
||||||
|
Gdi::Window::updateAll();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return defPaintProc(hwnd, msg, wParam, lParam, origDefWindowProc);
|
return defPaintProc(hwnd, msg, wParam, lParam, origDefWindowProc);
|
||||||
|
@ -38,7 +38,6 @@ namespace
|
|||||||
std::map<HWND, WindowProc> g_windowProc;
|
std::map<HWND, WindowProc> g_windowProc;
|
||||||
|
|
||||||
WindowProc getWindowProc(HWND hwnd);
|
WindowProc getWindowProc(HWND hwnd);
|
||||||
bool isTopLevelWindow(HWND hwnd);
|
|
||||||
bool isUser32ScrollBar(HWND hwnd);
|
bool isUser32ScrollBar(HWND hwnd);
|
||||||
void onDestroyWindow(HWND hwnd);
|
void onDestroyWindow(HWND hwnd);
|
||||||
void onGetMinMaxInfo(MINMAXINFO& mmi);
|
void onGetMinMaxInfo(MINMAXINFO& mmi);
|
||||||
@ -72,7 +71,7 @@ namespace
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_SYNCPAINT:
|
case WM_SYNCPAINT:
|
||||||
if (isTopLevelWindow(hwnd))
|
if (Gdi::Window::isTopLevelWindow(hwnd))
|
||||||
{
|
{
|
||||||
Gdi::Window::onSyncPaint(hwnd);
|
Gdi::Window::onSyncPaint(hwnd);
|
||||||
return 0;
|
return 0;
|
||||||
@ -124,7 +123,7 @@ namespace
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_STYLECHANGED:
|
case WM_STYLECHANGED:
|
||||||
if (isTopLevelWindow(hwnd))
|
if (Gdi::Window::isTopLevelWindow(hwnd))
|
||||||
{
|
{
|
||||||
Gdi::Window::onStyleChanged(hwnd, wParam);
|
Gdi::Window::onStyleChanged(hwnd, wParam);
|
||||||
}
|
}
|
||||||
@ -181,11 +180,6 @@ namespace
|
|||||||
return g_windowProc[hwnd];
|
return g_windowProc[hwnd];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isTopLevelWindow(HWND hwnd)
|
|
||||||
{
|
|
||||||
return GetDesktopWindow() == GetAncestor(hwnd, GA_PARENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isUser32ScrollBar(HWND hwnd)
|
bool isUser32ScrollBar(HWND hwnd)
|
||||||
{
|
{
|
||||||
WNDCLASS wc = {};
|
WNDCLASS wc = {};
|
||||||
@ -207,7 +201,7 @@ namespace
|
|||||||
|
|
||||||
void onDestroyWindow(HWND hwnd)
|
void onDestroyWindow(HWND hwnd)
|
||||||
{
|
{
|
||||||
if (isTopLevelWindow(hwnd))
|
if (Gdi::Window::isTopLevelWindow(hwnd))
|
||||||
{
|
{
|
||||||
Gdi::Window::updateAll();
|
Gdi::Window::updateAll();
|
||||||
return;
|
return;
|
||||||
@ -272,7 +266,7 @@ namespace
|
|||||||
notifyFunc();
|
notifyFunc();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTopLevelWindow(hwnd))
|
if (Gdi::Window::isTopLevelWindow(hwnd))
|
||||||
{
|
{
|
||||||
Gdi::Window::updateAll();
|
Gdi::Window::updateAll();
|
||||||
}
|
}
|
||||||
@ -286,7 +280,7 @@ namespace
|
|||||||
|
|
||||||
void onWindowPosChanging(HWND hwnd, WINDOWPOS& wp)
|
void onWindowPosChanging(HWND hwnd, WINDOWPOS& wp)
|
||||||
{
|
{
|
||||||
if (isTopLevelWindow(hwnd))
|
if (Gdi::Window::isTopLevelWindow(hwnd))
|
||||||
{
|
{
|
||||||
wp.flags |= SWP_NOREDRAW;
|
wp.flags |= SWP_NOREDRAW;
|
||||||
}
|
}
|
||||||
@ -499,7 +493,7 @@ namespace Gdi
|
|||||||
setWindowProc(hwnd, ddcWindowProcA, ddcWindowProcW);
|
setWindowProc(hwnd, ddcWindowProcA, ddcWindowProcW);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isTopLevelWindow(hwnd))
|
if (!Gdi::Window::isTopLevelWindow(hwnd))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -355,36 +355,15 @@ namespace
|
|||||||
Gdi::GuiThread::setWindowRgn(it->second.presentationWindow, it->second.windowRegion);
|
Gdi::GuiThread::setWindowRgn(it->second.presentationWindow, it->second.windowRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
WINDOWPOS wp = {};
|
const HWND devicePresentationWindow = DDraw::RealPrimarySurface::getDevicePresentationWindow();
|
||||||
wp.flags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOSENDCHANGING;
|
if (DDraw::RealPrimarySurface::isFullscreen() && devicePresentationWindow == it->second.presentationWindow)
|
||||||
if (isVisible)
|
|
||||||
{
|
{
|
||||||
wp.hwndInsertAfter = GetWindow(hwnd, GW_HWNDPREV);
|
DDraw::RealPrimarySurface::updateDevicePresentationWindowPos();
|
||||||
if (!wp.hwndInsertAfter)
|
|
||||||
{
|
|
||||||
wp.hwndInsertAfter = (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_TOP;
|
|
||||||
}
|
|
||||||
else if (wp.hwndInsertAfter == it->second.presentationWindow)
|
|
||||||
{
|
|
||||||
wp.flags |= SWP_NOZORDER;
|
|
||||||
}
|
|
||||||
|
|
||||||
wp.x = it->second.windowRect.left;
|
|
||||||
wp.y = it->second.windowRect.top;
|
|
||||||
wp.cx = it->second.windowRect.right - it->second.windowRect.left;
|
|
||||||
wp.cy = it->second.windowRect.bottom - it->second.windowRect.top;
|
|
||||||
wp.flags |= SWP_SHOWWINDOW;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wp.flags |= SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
|
Gdi::Window::updatePresentationWindowPos(it->second.presentationWindow, hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gdi::GuiThread::execute([&]()
|
|
||||||
{
|
|
||||||
CALL_ORIG_FUNC(SetWindowPos)(it->second.presentationWindow,
|
|
||||||
wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, wp.flags);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -395,6 +374,56 @@ namespace Gdi
|
|||||||
{
|
{
|
||||||
namespace Window
|
namespace Window
|
||||||
{
|
{
|
||||||
|
HWND getPresentationWindow(HWND hwnd)
|
||||||
|
{
|
||||||
|
D3dDdi::ScopedCriticalSection lock;
|
||||||
|
auto it = g_windows.find(hwnd);
|
||||||
|
return it != g_windows.end() ? it->second.presentationWindow : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<LayeredWindow> getVisibleLayeredWindows()
|
||||||
|
{
|
||||||
|
std::vector<LayeredWindow> layeredWindows;
|
||||||
|
for (auto it = g_windowZOrder.rbegin(); it != g_windowZOrder.rend(); ++it)
|
||||||
|
{
|
||||||
|
auto& window = **it;
|
||||||
|
if (window.isLayered && !window.visibleRegion.isEmpty())
|
||||||
|
{
|
||||||
|
layeredWindows.push_back({ window.hwnd, window.windowRect, window.visibleRegion });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT wr = {};
|
||||||
|
auto configWindow = GuiThread::getConfigWindow();
|
||||||
|
if (configWindow && configWindow->isVisible())
|
||||||
|
{
|
||||||
|
GetWindowRect(configWindow->getWindow(), &wr);
|
||||||
|
auto visibleRegion(getWindowRegion(configWindow->getWindow()));
|
||||||
|
visibleRegion.offset(wr.left, wr.top);
|
||||||
|
layeredWindows.push_back({ configWindow->getWindow(), wr, visibleRegion });
|
||||||
|
auto capture = Input::getCaptureWindow();
|
||||||
|
if (capture && capture != configWindow)
|
||||||
|
{
|
||||||
|
GetWindowRect(capture->getWindow(), &wr);
|
||||||
|
layeredWindows.push_back({ capture->getWindow(), wr, nullptr });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND cursorWindow = Input::getCursorWindow();
|
||||||
|
if (cursorWindow)
|
||||||
|
{
|
||||||
|
GetWindowRect(cursorWindow, &wr);
|
||||||
|
layeredWindows.push_back({ cursorWindow, wr, nullptr });
|
||||||
|
}
|
||||||
|
|
||||||
|
return layeredWindows;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isTopLevelWindow(HWND hwnd)
|
||||||
|
{
|
||||||
|
return GetDesktopWindow() == GetAncestor(hwnd, GA_PARENT);
|
||||||
|
}
|
||||||
|
|
||||||
void onStyleChanged(HWND hwnd, WPARAM wParam)
|
void onStyleChanged(HWND hwnd, WPARAM wParam)
|
||||||
{
|
{
|
||||||
if (GWL_EXSTYLE == wParam)
|
if (GWL_EXSTYLE == wParam)
|
||||||
@ -516,44 +545,6 @@ namespace Gdi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<LayeredWindow> getVisibleLayeredWindows()
|
|
||||||
{
|
|
||||||
std::vector<LayeredWindow> layeredWindows;
|
|
||||||
for (auto it = g_windowZOrder.rbegin(); it != g_windowZOrder.rend(); ++it)
|
|
||||||
{
|
|
||||||
auto& window = **it;
|
|
||||||
if (window.isLayered && !window.visibleRegion.isEmpty())
|
|
||||||
{
|
|
||||||
layeredWindows.push_back({ window.hwnd, window.windowRect, window.visibleRegion });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RECT wr = {};
|
|
||||||
auto configWindow = GuiThread::getConfigWindow();
|
|
||||||
if (configWindow && configWindow->isVisible())
|
|
||||||
{
|
|
||||||
GetWindowRect(configWindow->getWindow(), &wr);
|
|
||||||
auto visibleRegion(getWindowRegion(configWindow->getWindow()));
|
|
||||||
visibleRegion.offset(wr.left, wr.top);
|
|
||||||
layeredWindows.push_back({ configWindow->getWindow(), wr, visibleRegion });
|
|
||||||
auto capture = Input::getCaptureWindow();
|
|
||||||
if (capture && capture != configWindow)
|
|
||||||
{
|
|
||||||
GetWindowRect(capture->getWindow(), &wr);
|
|
||||||
layeredWindows.push_back({ capture->getWindow(), wr, nullptr });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HWND cursorWindow = Input::getCursorWindow();
|
|
||||||
if (cursorWindow)
|
|
||||||
{
|
|
||||||
GetWindowRect(cursorWindow, &wr);
|
|
||||||
layeredWindows.push_back({ cursorWindow, wr, nullptr });
|
|
||||||
}
|
|
||||||
|
|
||||||
return layeredWindows;
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateAll()
|
void updateAll()
|
||||||
{
|
{
|
||||||
LOG_FUNC("Window::updateAll");
|
LOG_FUNC("Window::updateAll");
|
||||||
@ -603,5 +594,44 @@ namespace Gdi
|
|||||||
SendNotifyMessage(hwnd, WM_SYNCPAINT, 0, 0);
|
SendNotifyMessage(hwnd, WM_SYNCPAINT, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updatePresentationWindowPos(HWND presentationWindow, HWND owner)
|
||||||
|
{
|
||||||
|
const bool isOwnerVisible = IsWindowVisible(owner) && !IsIconic(owner);
|
||||||
|
|
||||||
|
WINDOWPOS wp = {};
|
||||||
|
wp.flags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOSENDCHANGING;
|
||||||
|
if (isOwnerVisible)
|
||||||
|
{
|
||||||
|
wp.hwndInsertAfter = GetWindow(owner, GW_HWNDPREV);
|
||||||
|
if (!wp.hwndInsertAfter)
|
||||||
|
{
|
||||||
|
wp.hwndInsertAfter = (GetWindowLong(owner, GWL_EXSTYLE) & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_TOP;
|
||||||
|
}
|
||||||
|
else if (wp.hwndInsertAfter == presentationWindow)
|
||||||
|
{
|
||||||
|
wp.flags |= SWP_NOZORDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT wr = {};
|
||||||
|
GetWindowRect(owner, &wr);
|
||||||
|
|
||||||
|
wp.x = wr.left;
|
||||||
|
wp.y = wr.top;
|
||||||
|
wp.cx = wr.right - wr.left;
|
||||||
|
wp.cy = wr.bottom - wr.top;
|
||||||
|
wp.flags |= SWP_SHOWWINDOW;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wp.flags |= SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gdi::GuiThread::execute([&]()
|
||||||
|
{
|
||||||
|
CALL_ORIG_FUNC(SetWindowPos)(presentationWindow,
|
||||||
|
wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, wp.flags);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,15 @@ namespace Gdi
|
|||||||
Gdi::Region region;
|
Gdi::Region region;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
HWND getPresentationWindow(HWND hwnd);
|
||||||
std::vector<LayeredWindow> getVisibleLayeredWindows();
|
std::vector<LayeredWindow> getVisibleLayeredWindows();
|
||||||
|
bool isTopLevelWindow(HWND hwnd);
|
||||||
void onStyleChanged(HWND hwnd, WPARAM wParam);
|
void onStyleChanged(HWND hwnd, WPARAM wParam);
|
||||||
void onSyncPaint(HWND hwnd);
|
void onSyncPaint(HWND hwnd);
|
||||||
void present(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src,
|
void present(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src,
|
||||||
CompatRef<IDirectDrawClipper> clipper);
|
CompatRef<IDirectDrawClipper> clipper);
|
||||||
void present(Gdi::Region excludeRegion);
|
void present(Gdi::Region excludeRegion);
|
||||||
void updateAll();
|
void updateAll();
|
||||||
|
void updatePresentationWindowPos(HWND presentationWindow, HWND owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,8 +285,9 @@ namespace Input
|
|||||||
CALL_ORIG_FUNC(SetLayeredWindowAttributes)(g_cursorWindow, RGB(0xFF, 0xFF, 0xFF), 0, LWA_COLORKEY);
|
CALL_ORIG_FUNC(SetLayeredWindowAttributes)(g_cursorWindow, RGB(0xFF, 0xFF, 0xFF), 0, LWA_COLORKEY);
|
||||||
|
|
||||||
g_cursorPos = { (g_monitorRect.left + g_monitorRect.right) / 2, (g_monitorRect.top + g_monitorRect.bottom) / 2 };
|
g_cursorPos = { (g_monitorRect.left + g_monitorRect.right) / 2, (g_monitorRect.top + g_monitorRect.bottom) / 2 };
|
||||||
CALL_ORIG_FUNC(SetWindowPos)(g_cursorWindow, HWND_TOPMOST, g_cursorPos.x, g_cursorPos.y,
|
CALL_ORIG_FUNC(SetWindowPos)(g_cursorWindow, DDraw::RealPrimarySurface::getTopmost(),
|
||||||
g_bmpArrowSize.cx, g_bmpArrowSize.cy, SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
|
g_cursorPos.x, g_cursorPos.y, g_bmpArrowSize.cx, g_bmpArrowSize.cy,
|
||||||
|
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
|
||||||
g_capture->onMouseMove(getRelativeCursorPos());
|
g_capture->onMouseMove(getRelativeCursorPos());
|
||||||
|
|
||||||
resetMouseHook();
|
resetMouseHook();
|
||||||
@ -305,8 +306,9 @@ namespace Input
|
|||||||
{
|
{
|
||||||
Gdi::GuiThread::execute([]()
|
Gdi::GuiThread::execute([]()
|
||||||
{
|
{
|
||||||
CALL_ORIG_FUNC(SetWindowPos)(g_cursorWindow, HWND_TOPMOST, g_cursorPos.x, g_cursorPos.y,
|
CALL_ORIG_FUNC(SetWindowPos)(g_cursorWindow, DDraw::RealPrimarySurface::getTopmost(),
|
||||||
g_bmpArrowSize.cx, g_bmpArrowSize.cy, SWP_NOACTIVATE | SWP_NOSENDCHANGING);
|
g_cursorPos.x, g_cursorPos.y, g_bmpArrowSize.cx, g_bmpArrowSize.cy,
|
||||||
|
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOSENDCHANGING);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,6 @@ namespace Overlay
|
|||||||
if (m_style & WS_VISIBLE)
|
if (m_style & WS_VISIBLE)
|
||||||
{
|
{
|
||||||
updatePos();
|
updatePos();
|
||||||
ShowWindow(m_hwnd, SW_SHOWNA);
|
|
||||||
Input::setCapture(this);
|
Input::setCapture(this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -214,8 +213,10 @@ namespace Overlay
|
|||||||
m_rect = calculateRect({ monitorRect.left / m_scaleFactor, monitorRect.top / m_scaleFactor,
|
m_rect = calculateRect({ monitorRect.left / m_scaleFactor, monitorRect.top / m_scaleFactor,
|
||||||
monitorRect.right / m_scaleFactor, monitorRect.bottom / m_scaleFactor });
|
monitorRect.right / m_scaleFactor, monitorRect.bottom / m_scaleFactor });
|
||||||
|
|
||||||
CALL_ORIG_FUNC(SetWindowPos)(m_hwnd, HWND_TOPMOST, m_rect.left * m_scaleFactor, m_rect.top * m_scaleFactor,
|
CALL_ORIG_FUNC(SetWindowPos)(m_hwnd, DDraw::RealPrimarySurface::getTopmost(),
|
||||||
(m_rect.right - m_rect.left) * m_scaleFactor, (m_rect.bottom - m_rect.top) * m_scaleFactor, SWP_NOACTIVATE);
|
m_rect.left * m_scaleFactor, m_rect.top * m_scaleFactor,
|
||||||
|
(m_rect.right - m_rect.left) * m_scaleFactor, (m_rect.bottom - m_rect.top) * m_scaleFactor,
|
||||||
|
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
|
||||||
|
|
||||||
if (Input::getCaptureWindow() == this)
|
if (Input::getCaptureWindow() == this)
|
||||||
{
|
{
|
||||||
@ -230,7 +231,10 @@ namespace Overlay
|
|||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
case WM_DISPLAYCHANGE:
|
case WM_DISPLAYCHANGE:
|
||||||
updatePos();
|
if (m_style & WS_VISIBLE)
|
||||||
|
{
|
||||||
|
updatePos();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user