mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-12-14 12:09:36 +00:00
Override alt-enter behavior, use borderless fullscreen instead of exclusive fullscreen. This should fix the game breaking when bringing up the open file dialog in fullscreen.
(Note that this doesn't handle resolution changes yet)
This commit is contained in:
@@ -102,11 +102,9 @@ bool InitSwapChainForWindow(HWND hWnd, ID3D11Device *device, GpComPtr<IDXGISwapC
|
||||
if (result != S_OK)
|
||||
return false;
|
||||
|
||||
#if 0
|
||||
result = dxgiFactory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER);
|
||||
if (result != S_OK)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
outSwapChain = swapChain;
|
||||
|
||||
@@ -413,8 +411,8 @@ GpDisplayDriverTickStatus_t GpDisplayDriverD3D11::PresentFrameAndSync()
|
||||
D3D11_VIEWPORT viewport;
|
||||
viewport.TopLeftX = 0;
|
||||
viewport.TopLeftY = 0;
|
||||
viewport.Width = static_cast<FLOAT>(m_windowWidth);
|
||||
viewport.Height = static_cast<FLOAT>(m_windowHeight);
|
||||
viewport.Width = static_cast<FLOAT>(m_windowWidthPhysical);
|
||||
viewport.Height = static_cast<FLOAT>(m_windowHeightPhysical);
|
||||
viewport.MinDepth = 0.0f;
|
||||
viewport.MaxDepth = 1.0f;
|
||||
|
||||
@@ -592,7 +590,7 @@ void GpDisplayDriverD3D11::ChangeToCursor(HCURSOR cursor)
|
||||
if (m_mouseIsInClientArea)
|
||||
::SetCursor(cursor);
|
||||
|
||||
SetClassLongPtrW(m_hwnd, GCLP_HCURSOR, reinterpret_cast<LONG_PTR>(cursor));
|
||||
SetClassLongPtrW(m_osGlobals->m_hwnd, GCLP_HCURSOR, reinterpret_cast<LONG_PTR>(cursor));
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::ChangeToStandardCursor(EGpStandardCursor_t cursor)
|
||||
@@ -612,6 +610,105 @@ void GpDisplayDriverD3D11::ChangeToStandardCursor(EGpStandardCursor_t cursor)
|
||||
}
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::BecomeFullScreen(LONG &windowStyle)
|
||||
{
|
||||
assert(!m_isFullScreen);
|
||||
|
||||
RECT windowRect;
|
||||
if (!GetWindowRect(m_osGlobals->m_hwnd, &windowRect))
|
||||
return; // ???
|
||||
|
||||
HMONITOR monitor = MonitorFromRect(&windowRect, MONITOR_DEFAULTTONULL);
|
||||
if (!monitor)
|
||||
{
|
||||
// If the window is off-screen, use the primary monitor
|
||||
monitor = MonitorFromRect(&windowRect, MONITOR_DEFAULTTOPRIMARY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, use the nearest
|
||||
monitor = MonitorFromRect(&windowRect, MONITOR_DEFAULTTONEAREST);
|
||||
}
|
||||
|
||||
if (!monitor)
|
||||
return; // No monitor?
|
||||
|
||||
MONITORINFO monitorInfo;
|
||||
monitorInfo.cbSize = sizeof(monitorInfo);
|
||||
if (!GetMonitorInfoA(monitor, &monitorInfo))
|
||||
return;
|
||||
|
||||
m_windowModeRevertRect = windowRect;
|
||||
SetWindowLongPtr(m_osGlobals->m_hwnd, GWL_STYLE, WS_VISIBLE | WS_POPUP);
|
||||
|
||||
SetWindowPos(m_osGlobals->m_hwnd, HWND_TOP, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top, SWP_FRAMECHANGED);
|
||||
|
||||
m_isFullScreen = true;
|
||||
windowStyle = (WS_VISIBLE | WS_POPUP);
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::BecomeWindowed(LONG &windowStyle)
|
||||
{
|
||||
assert(m_isFullScreen);
|
||||
|
||||
RECT revertRect = m_windowModeRevertRect;
|
||||
|
||||
HMONITOR monitor = MonitorFromRect(&m_windowModeRevertRect, MONITOR_DEFAULTTONULL);
|
||||
if (!monitor)
|
||||
{
|
||||
// If the window is off-screen, use the primary monitor
|
||||
monitor = MonitorFromRect(&revertRect, MONITOR_DEFAULTTOPRIMARY);
|
||||
if (!monitor)
|
||||
return;
|
||||
|
||||
MONITORINFO monitorInfo;
|
||||
monitorInfo.cbSize = sizeof(monitorInfo);
|
||||
if (!GetMonitorInfoA(monitor, &monitorInfo))
|
||||
return;
|
||||
|
||||
RECT monitorRect = monitorInfo.rcWork;
|
||||
LONG monitorWidth = monitorRect.right - monitorRect.left;
|
||||
LONG monitorHeight = monitorRect.bottom - monitorRect.top;
|
||||
|
||||
LONG revertHeight = revertRect.bottom - revertRect.top;
|
||||
LONG revertWidth = revertRect.right - revertRect.left;
|
||||
|
||||
if (revertWidth > monitorWidth)
|
||||
revertWidth = monitorWidth;
|
||||
|
||||
if (revertHeight > monitorHeight)
|
||||
revertHeight = monitorHeight;
|
||||
|
||||
revertRect.bottom = revertRect.top + revertHeight;
|
||||
revertRect.right = revertRect.right + revertWidth;
|
||||
|
||||
LONG xDelta = 0;
|
||||
if (revertRect.right > monitorRect.right)
|
||||
xDelta = monitorRect.right - revertRect.right;
|
||||
else if (revertRect.left < monitorRect.left)
|
||||
xDelta = monitorRect.left - revertRect.left;
|
||||
|
||||
LONG yDelta = 0;
|
||||
if (revertRect.bottom > monitorRect.bottom)
|
||||
yDelta = monitorRect.bottom - revertRect.bottom;
|
||||
else if (revertRect.top < monitorRect.top)
|
||||
yDelta = monitorRect.top - revertRect.top;
|
||||
|
||||
|
||||
revertRect.left = revertRect.left + xDelta;
|
||||
revertRect.top = revertRect.top + yDelta;
|
||||
revertRect.bottom = revertRect.top + revertHeight;
|
||||
revertRect.right = revertRect.right + revertWidth;
|
||||
}
|
||||
|
||||
SetWindowLongPtr(m_osGlobals->m_hwnd, GWL_STYLE, WS_VISIBLE | WS_OVERLAPPEDWINDOW);
|
||||
|
||||
SetWindowPos(m_osGlobals->m_hwnd, HWND_TOP, revertRect.left, revertRect.top, revertRect.right - revertRect.left, revertRect.bottom - revertRect.top, SWP_FRAMECHANGED);
|
||||
|
||||
m_isFullScreen = false;
|
||||
windowStyle = (WS_VISIBLE | WS_OVERLAPPEDWINDOW);
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::Run()
|
||||
{
|
||||
WNDCLASSEX wc;
|
||||
@@ -638,14 +735,14 @@ void GpDisplayDriverD3D11::Run()
|
||||
HMENU menus = NULL;
|
||||
|
||||
// TODO: Fix the resolution here
|
||||
RECT wr = { 0, 0, m_windowWidth, m_windowHeight };
|
||||
RECT wr = { 0, 0, m_windowWidthPhysical, m_windowHeightPhysical };
|
||||
AdjustWindowRect(&wr, windowStyle, menus != NULL);
|
||||
|
||||
m_hwnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", GP_APPLICATION_NAME_W L" (Direct3D 11)", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, m_osGlobals->m_hInstance, NULL);
|
||||
m_osGlobals->m_hwnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", GP_APPLICATION_NAME_W L" (Direct3D 11)", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, m_osGlobals->m_hInstance, NULL);
|
||||
|
||||
ShowWindow(m_hwnd, m_osGlobals->m_nCmdShow);
|
||||
ShowWindow(m_osGlobals->m_hwnd, m_osGlobals->m_nCmdShow);
|
||||
|
||||
StartD3DForWindow(m_hwnd, m_swapChain, m_device, m_deviceContext);
|
||||
StartD3DForWindow(m_osGlobals->m_hwnd, m_swapChain, m_device, m_deviceContext);
|
||||
|
||||
InitResources();
|
||||
|
||||
@@ -674,7 +771,7 @@ void GpDisplayDriverD3D11::Run()
|
||||
|
||||
tme.cbSize = sizeof(tme);
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = m_hwnd;
|
||||
tme.hwndTrack = m_osGlobals->m_hwnd;
|
||||
tme.dwHoverTime = HOVER_DEFAULT;
|
||||
TrackMouseEvent(&tme);
|
||||
}
|
||||
@@ -682,38 +779,55 @@ void GpDisplayDriverD3D11::Run()
|
||||
else if (msg.message == WM_MOUSELEAVE)
|
||||
m_mouseIsInClientArea = false;
|
||||
|
||||
m_osGlobals->m_translateWindowsMessageFunc(&msg, m_properties.m_eventQueue);
|
||||
m_osGlobals->m_translateWindowsMessageFunc(&msg, m_properties.m_eventQueue, m_pixelScaleX, m_pixelScaleY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_isFullScreen != m_isFullScreenDesired)
|
||||
{
|
||||
if (m_isFullScreenDesired)
|
||||
BecomeFullScreen(windowStyle);
|
||||
else
|
||||
BecomeWindowed(windowStyle);
|
||||
}
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect(m_hwnd, &clientRect);
|
||||
GetClientRect(m_osGlobals->m_hwnd, &clientRect);
|
||||
|
||||
unsigned int desiredWidth = clientRect.right - clientRect.left;
|
||||
unsigned int desiredHeight = clientRect.bottom - clientRect.top;
|
||||
if (clientRect.right - clientRect.left != m_windowWidth || clientRect.bottom - clientRect.top != m_windowHeight)
|
||||
if (clientRect.right - clientRect.left != m_windowWidthPhysical || clientRect.bottom - clientRect.top != m_windowHeightPhysical)
|
||||
{
|
||||
uint32_t prevWidth = m_windowWidth;
|
||||
uint32_t prevHeight = m_windowHeight;
|
||||
uint32_t prevWidth = m_windowWidthPhysical;
|
||||
uint32_t prevHeight = m_windowHeightPhysical;
|
||||
uint32_t virtualWidth = m_windowWidthVirtual;
|
||||
uint32_t virtualHeight = m_windowHeightVirtual;
|
||||
float pixelScaleX = 1.0f;
|
||||
float pixelScaleY = 1.0f;
|
||||
|
||||
if (m_properties.m_adjustRequestedResolutionFunc(m_properties.m_adjustRequestedResolutionFuncContext, desiredWidth, desiredHeight))
|
||||
if (m_properties.m_adjustRequestedResolutionFunc(m_properties.m_adjustRequestedResolutionFuncContext, desiredWidth, desiredHeight, virtualWidth, virtualHeight, pixelScaleX, pixelScaleY))
|
||||
{
|
||||
bool resizedOK = ResizeD3DWindow(m_hwnd, m_windowWidth, m_windowHeight, desiredWidth, desiredHeight, windowStyle, menus);
|
||||
bool resizedOK = ResizeD3DWindow(m_osGlobals->m_hwnd, m_windowWidthPhysical, m_windowHeightPhysical, desiredWidth, desiredHeight, windowStyle, menus);
|
||||
resizedOK = resizedOK && DetachSwapChain();
|
||||
resizedOK = resizedOK && ResizeSwapChain(m_swapChain, m_windowWidth, m_windowHeight);
|
||||
resizedOK = resizedOK && ResizeSwapChain(m_swapChain, m_windowWidthPhysical, m_windowHeightPhysical);
|
||||
resizedOK = resizedOK && InitBackBuffer();
|
||||
|
||||
if (!resizedOK)
|
||||
break; // Critical video driver error, exit
|
||||
|
||||
m_windowWidthVirtual = virtualWidth;
|
||||
m_windowHeightVirtual = virtualHeight;
|
||||
m_pixelScaleX = pixelScaleX;
|
||||
m_pixelScaleY = pixelScaleY;
|
||||
|
||||
if (GpVOSEvent *resizeEvent = m_properties.m_eventQueue->QueueEvent())
|
||||
{
|
||||
resizeEvent->m_eventType = GpVOSEventTypes::kVideoResolutionChanged;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_prevWidth = prevWidth;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_prevHeight = prevHeight;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_newWidth = m_windowWidth;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_newHeight = m_windowHeight;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_newWidth = m_windowWidthVirtual;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_newHeight = m_windowHeightVirtual;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -737,9 +851,9 @@ void GpDisplayDriverD3D11::Shutdown()
|
||||
void GpDisplayDriverD3D11::GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *pixelFormat)
|
||||
{
|
||||
if (width)
|
||||
*width = m_windowWidth;
|
||||
*width = m_windowWidthVirtual;
|
||||
if (height)
|
||||
*height = m_windowHeight;
|
||||
*height = m_windowHeightVirtual;
|
||||
if (pixelFormat)
|
||||
*pixelFormat = GpPixelFormats::k8BitStandard;
|
||||
}
|
||||
@@ -760,8 +874,8 @@ void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, int32_t
|
||||
//m_deviceContext->OMSetDepthStencilState(m_drawQuadDepthStencilState, 0);
|
||||
|
||||
{
|
||||
const float twoDivWidth = 2.0f / static_cast<float>(m_windowWidth);
|
||||
const float negativeTwoDivHeight = -2.0f / static_cast<float>(m_windowHeight);
|
||||
const float twoDivWidth = 2.0f / static_cast<float>(m_windowWidthVirtual);
|
||||
const float negativeTwoDivHeight = -2.0f / static_cast<float>(m_windowHeightVirtual);
|
||||
|
||||
DrawQuadVertexConstants constantsData;
|
||||
constantsData.m_ndcOriginX = static_cast<float>(x) * twoDivWidth - 1.0f;
|
||||
@@ -906,6 +1020,16 @@ void GpDisplayDriverD3D11::SetBackgroundColor(uint8_t r, uint8_t g, uint8_t b, u
|
||||
m_bgColor[3] = static_cast<float>(a) / 255.0f;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::RequestToggleFullScreen(uint32_t timestamp)
|
||||
{
|
||||
// Alt-Enter gets re-sent after a full-screen toggle, so we ignore toggle requests until half a second has seconds have elapsed
|
||||
if (timestamp > m_lastFullScreenToggleTimeStamp + 30)
|
||||
{
|
||||
m_isFullScreenDesired = !m_isFullScreenDesired;
|
||||
m_lastFullScreenToggleTimeStamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
GpDisplayDriverD3D11 *GpDisplayDriverD3D11::Create(const GpDisplayDriverProperties &properties)
|
||||
{
|
||||
void *storage = malloc(sizeof(GpDisplayDriverD3D11));
|
||||
@@ -918,8 +1042,12 @@ GpDisplayDriverD3D11 *GpDisplayDriverD3D11::Create(const GpDisplayDriverProperti
|
||||
GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &properties)
|
||||
: m_properties(properties)
|
||||
, m_frameTimeAccumulated(0)
|
||||
, m_windowWidth(640)
|
||||
, m_windowHeight(480)
|
||||
, m_windowWidthPhysical(640)
|
||||
, m_windowHeightPhysical(480)
|
||||
, m_windowWidthVirtual(640)
|
||||
, m_windowHeightVirtual(480)
|
||||
, m_pixelScaleX(1.0f)
|
||||
, m_pixelScaleY(1.0f)
|
||||
, m_vosFiber(nullptr)
|
||||
, m_osGlobals(static_cast<GpWindowsGlobals*>(properties.m_osGlobals))
|
||||
, m_pendingCursor(nullptr)
|
||||
@@ -927,8 +1055,12 @@ GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &prop
|
||||
, m_currentStandardCursor(EGpStandardCursors::kArrow)
|
||||
, m_pendingStandardCursor(EGpStandardCursors::kArrow)
|
||||
, m_mouseIsInClientArea(false)
|
||||
, m_isFullScreen(false)
|
||||
, m_isFullScreenDesired(false)
|
||||
, m_lastFullScreenToggleTimeStamp(0)
|
||||
{
|
||||
memset(&m_syncTimeBase, 0, sizeof(m_syncTimeBase));
|
||||
memset(&m_windowModeRevertRect, 0, sizeof(m_windowModeRevertRect));
|
||||
|
||||
QueryPerformanceFrequency(&m_QPFrequency);
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ public:
|
||||
|
||||
void SetBackgroundColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) override;
|
||||
|
||||
void RequestToggleFullScreen(uint32_t timestamp) override;
|
||||
|
||||
static GpDisplayDriverD3D11 *Create(const GpDisplayDriverProperties &properties);
|
||||
|
||||
private:
|
||||
@@ -81,6 +83,9 @@ private:
|
||||
void ChangeToCursor(HCURSOR cursor);
|
||||
void ChangeToStandardCursor(EGpStandardCursor_t cursor);
|
||||
|
||||
void BecomeFullScreen(LONG &windowStyle);
|
||||
void BecomeWindowed(LONG &windowStyle);
|
||||
|
||||
GpComPtr<IDXGISwapChain1> m_swapChain;
|
||||
GpComPtr<ID3D11Device> m_device;
|
||||
GpComPtr<ID3D11DeviceContext> m_deviceContext;
|
||||
@@ -108,11 +113,20 @@ private:
|
||||
UINT m_expectedSyncDelta;
|
||||
bool m_isResettingSwapChain;
|
||||
|
||||
bool m_isFullScreen;
|
||||
bool m_isFullScreenDesired;
|
||||
RECT m_windowModeRevertRect;
|
||||
uint32_t m_lastFullScreenToggleTimeStamp;
|
||||
|
||||
LONGLONG m_frameTimeAccumulated;
|
||||
LONGLONG m_frameTimeSliceSize;
|
||||
|
||||
DWORD m_windowWidth;
|
||||
DWORD m_windowHeight;
|
||||
DWORD m_windowWidthPhysical; // Physical resolution is the resolution of the actual window
|
||||
DWORD m_windowHeightPhysical;
|
||||
DWORD m_windowWidthVirtual; // Virtual resolution is the resolution reported to teh game
|
||||
DWORD m_windowHeightVirtual;
|
||||
float m_pixelScaleX;
|
||||
float m_pixelScaleY;
|
||||
|
||||
IGpCursor_Win32 *m_activeCursor;
|
||||
IGpCursor_Win32 *m_pendingCursor;
|
||||
@@ -126,7 +140,6 @@ private:
|
||||
HCURSOR m_arrowCursor;
|
||||
HCURSOR m_waitCursor;
|
||||
HCURSOR m_ibeamCursor;
|
||||
HWND m_hwnd;
|
||||
|
||||
float m_bgColor[4];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user