diff --git a/DDrawCompat/Config/Config.cpp b/DDrawCompat/Config/Config.cpp index 3126db3..48c2943 100644 --- a/DDrawCompat/Config/Config.cpp +++ b/DDrawCompat/Config/Config.cpp @@ -13,6 +13,7 @@ namespace Config Settings::DisplayResolution displayResolution; Settings::ForceD3D9On12 forceD3D9On12; Settings::FullscreenMode fullscreenMode; + Settings::RemoveBorders removeBorders; Settings::RenderColorDepth renderColorDepth; Settings::ResolutionScale resolutionScale; Settings::SpriteDetection spriteDetection; diff --git a/DDrawCompat/Config/Config.h b/DDrawCompat/Config/Config.h index 68cb4a2..a29e4ef 100644 --- a/DDrawCompat/Config/Config.h +++ b/DDrawCompat/Config/Config.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,7 @@ namespace Config extern Settings::DisplayResolution displayResolution; extern Settings::ForceD3D9On12 forceD3D9On12; extern Settings::FullscreenMode fullscreenMode; + extern Settings::RemoveBorders removeBorders; extern Settings::RenderColorDepth renderColorDepth; extern Settings::ResolutionScale resolutionScale; extern Settings::SpriteDetection spriteDetection; diff --git a/DDrawCompat/Config/Settings/RemoveBorders.h b/DDrawCompat/Config/Settings/RemoveBorders.h new file mode 100644 index 0000000..e43d52b --- /dev/null +++ b/DDrawCompat/Config/Settings/RemoveBorders.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace Config +{ + namespace Settings + { + class RemoveBorders : public MappedSetting + { + public: + RemoveBorders() + : MappedSetting("RemoveBorders", "off", { {"off", false}, {"on", true} }) + { + } + }; + } +} diff --git a/DDrawCompat/DDraw/DirectDraw.cpp b/DDrawCompat/DDraw/DirectDraw.cpp index 038942d..313cba2 100644 --- a/DDrawCompat/DDraw/DirectDraw.cpp +++ b/DDrawCompat/DDraw/DirectDraw.cpp @@ -83,7 +83,18 @@ namespace HRESULT result = getOrigVtable(This).SetCooperativeLevel(This, hWnd, dwFlags); if (SUCCEEDED(result)) { - DDraw::TagSurface::create(*CompatPtr::from(This)); + auto tagSurface = DDraw::TagSurface::get(*CompatPtr::from(This)); + if (tagSurface) + { + if (dwFlags & DDSCL_FULLSCREEN) + { + tagSurface->setFullscreenWindow(hWnd); + } + else if (dwFlags & DDSCL_NORMAL) + { + tagSurface->setFullscreenWindow(nullptr); + } + } } return result; } diff --git a/DDrawCompat/DDraw/Surfaces/TagSurface.cpp b/DDrawCompat/DDraw/Surfaces/TagSurface.cpp index dc0ed95..6f4c2e7 100644 --- a/DDrawCompat/DDraw/Surfaces/TagSurface.cpp +++ b/DDrawCompat/DDraw/Surfaces/TagSurface.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -10,14 +11,23 @@ namespace namespace DDraw { + TagSurface::TagSurface(DWORD origCaps, void* ddObject) + : Surface(origCaps) + , m_ddObject(ddObject) + , m_fullscreenWindow(nullptr) + , m_fullscreenWindowStyle(0) + , m_fullscreenWindowExStyle(0) + { + } + + TagSurface::~TagSurface() + { + setFullscreenWindow(nullptr); + g_ddObjects.erase(m_ddObject); + } + HRESULT TagSurface::create(CompatRef dd) { - auto ddObject = DDraw::DirectDraw::getDdObject(dd.get()); - if (g_ddObjects.find(ddObject) != g_ddObjects.end()) - { - return DD_OK; - } - DDSURFACEDESC desc = {}; desc.dwSize = sizeof(desc); desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; @@ -25,6 +35,7 @@ namespace DDraw desc.dwHeight = 1; desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + auto ddObject = DDraw::DirectDraw::getDdObject(dd.get()); auto privateData(std::make_unique(desc.ddsCaps.dwCaps, ddObject)); g_ddObjects[ddObject] = privateData.get(); @@ -32,6 +43,18 @@ namespace DDraw return Surface::create(dd, desc, surface, std::move(privateData)); } + TagSurface* TagSurface::findFullscreenWindow(HWND hwnd) + { + for (auto& pair : g_ddObjects) + { + if (hwnd == pair.second->m_fullscreenWindow) + { + return pair.second; + } + } + return nullptr; + } + void TagSurface::forEachDirectDraw(std::function)> callback) { struct DirectDrawInterface @@ -49,8 +72,75 @@ namespace DDraw } } - TagSurface::~TagSurface() + TagSurface* TagSurface::get(CompatRef dd) { - g_ddObjects.erase(m_ddObject); + auto ddObject = DDraw::DirectDraw::getDdObject(dd.get()); + auto it = g_ddObjects.find(ddObject); + if (it != g_ddObjects.end()) + { + return it->second; + } + + if (FAILED(create(dd))) + { + return nullptr; + } + return g_ddObjects[ddObject]; + } + + void TagSurface::setFullscreenWindow(HWND hwnd) + { + if (m_fullscreenWindow == hwnd) + { + return; + } + HWND prevFullscreenWindow = m_fullscreenWindow; + m_fullscreenWindow = hwnd; + + if (Config::removeBorders.get()) + { + if (hwnd) + { + setWindowStyle(CALL_ORIG_FUNC(GetWindowLongA)(hwnd, GWL_STYLE)); + setWindowExStyle(CALL_ORIG_FUNC(GetWindowLongA)(hwnd, GWL_EXSTYLE)); + } + else if (prevFullscreenWindow) + { + CALL_ORIG_FUNC(SetWindowLongA)(prevFullscreenWindow, GWL_STYLE, m_fullscreenWindowStyle); + CALL_ORIG_FUNC(SetWindowLongA)(prevFullscreenWindow, GWL_EXSTYLE, m_fullscreenWindowExStyle); + m_fullscreenWindowStyle = 0; + m_fullscreenWindowExStyle = 0; + } + } + } + + LONG TagSurface::setWindowStyle(LONG style) + { + auto lastError = GetLastError(); + SetLastError(0); + LONG prevStyle = CALL_ORIG_FUNC(SetWindowLongA)(m_fullscreenWindow, GWL_STYLE, style); + if (0 != prevStyle || 0 == GetLastError()) + { + CALL_ORIG_FUNC(SetWindowLongA)(m_fullscreenWindow, GWL_STYLE, + (style | WS_POPUP) & ~(WS_BORDER | WS_DLGFRAME | WS_SYSMENU | WS_THICKFRAME)); + m_fullscreenWindowStyle = style; + SetLastError(lastError); + } + return prevStyle; + } + + LONG TagSurface::setWindowExStyle(LONG exStyle) + { + auto lastError = GetLastError(); + SetLastError(0); + LONG prevExStyle = CALL_ORIG_FUNC(SetWindowLongA)(m_fullscreenWindow, GWL_EXSTYLE, exStyle); + if (0 != prevExStyle || 0 == GetLastError()) + { + CALL_ORIG_FUNC(SetWindowLongA)(m_fullscreenWindow, GWL_EXSTYLE, + exStyle & ~(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_WINDOWEDGE)); + m_fullscreenWindowExStyle = exStyle; + SetLastError(lastError); + } + return prevExStyle; } } diff --git a/DDrawCompat/DDraw/Surfaces/TagSurface.h b/DDrawCompat/DDraw/Surfaces/TagSurface.h index 3778d6f..bda76f2 100644 --- a/DDrawCompat/DDraw/Surfaces/TagSurface.h +++ b/DDrawCompat/DDraw/Surfaces/TagSurface.h @@ -11,13 +11,24 @@ namespace DDraw class TagSurface : public Surface { public: - TagSurface(DWORD origCaps, void* ddObject) : Surface(origCaps), m_ddObject(ddObject) {} + TagSurface(DWORD origCaps, void* ddObject); virtual ~TagSurface() override; - static HRESULT create(CompatRef dd); + static TagSurface* get(CompatRef dd); + static TagSurface* findFullscreenWindow(HWND hwnd); + static void forEachDirectDraw(std::function)> callback); + void setFullscreenWindow(HWND hwnd); + LONG setWindowStyle(LONG style); + LONG setWindowExStyle(LONG exStyle); + private: + static HRESULT create(CompatRef dd); + void* m_ddObject; + HWND m_fullscreenWindow; + LONG m_fullscreenWindowStyle; + LONG m_fullscreenWindowExStyle; }; } diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj index c100f96..157b539 100644 --- a/DDrawCompat/DDrawCompat.vcxproj +++ b/DDrawCompat/DDrawCompat.vcxproj @@ -228,6 +228,7 @@ + diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters index 576e100..2103f1b 100644 --- a/DDrawCompat/DDrawCompat.vcxproj.filters +++ b/DDrawCompat/DDrawCompat.vcxproj.filters @@ -552,6 +552,9 @@ Header Files\Config\Settings + + Header Files\Config\Settings + diff --git a/DDrawCompat/Gdi/WinProc.cpp b/DDrawCompat/Gdi/WinProc.cpp index 946da25..2a084e8 100644 --- a/DDrawCompat/Gdi/WinProc.cpp +++ b/DDrawCompat/Gdi/WinProc.cpp @@ -6,10 +6,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -426,6 +428,22 @@ namespace return reinterpret_cast(oldWndProc); } } + else if ((GWL_STYLE == nIndex || GWL_EXSTYLE == nIndex) && Config::removeBorders.get()) + { + auto tagSurface = DDraw::TagSurface::findFullscreenWindow(hWnd); + if (tagSurface) + { + if (GWL_STYLE == nIndex) + { + return tagSurface->setWindowStyle(dwNewLong); + } + else + { + return tagSurface->setWindowExStyle(dwNewLong); + } + } + } + return origSetWindowLong(hWnd, nIndex, dwNewLong); }