From 10f61c11e9ae5ccad6160ba02961df53ac4d2070 Mon Sep 17 00:00:00 2001 From: narzoul Date: Tue, 28 Apr 2020 01:06:13 +0200 Subject: [PATCH] Emulate disabled font smoothing --- DDrawCompat/DDraw/ActivateAppHandler.cpp | 82 ----------------- DDrawCompat/DDraw/ActivateAppHandler.h | 11 --- DDrawCompat/DDraw/DirectDraw.cpp | 24 ++--- DDrawCompat/DDraw/DirectDraw.h | 9 +- DDrawCompat/DDrawCompat.vcxproj | 6 +- DDrawCompat/DDrawCompat.vcxproj.filters | 18 ++-- DDrawCompat/Dll/DllMain.cpp | 3 - DDrawCompat/Gdi/DcFunctions.cpp | 49 ++++++++--- DDrawCompat/Gdi/Font.cpp | 107 +++++++++++++++++++++++ DDrawCompat/Gdi/Font.h | 22 +++++ DDrawCompat/Gdi/Gdi.cpp | 24 ++--- DDrawCompat/Win32/FontSmoothing.cpp | 57 ------------ DDrawCompat/Win32/FontSmoothing.h | 26 ------ 13 files changed, 196 insertions(+), 242 deletions(-) delete mode 100644 DDrawCompat/DDraw/ActivateAppHandler.cpp delete mode 100644 DDrawCompat/DDraw/ActivateAppHandler.h create mode 100644 DDrawCompat/Gdi/Font.cpp create mode 100644 DDrawCompat/Gdi/Font.h delete mode 100644 DDrawCompat/Win32/FontSmoothing.cpp delete mode 100644 DDrawCompat/Win32/FontSmoothing.h diff --git a/DDrawCompat/DDraw/ActivateAppHandler.cpp b/DDrawCompat/DDraw/ActivateAppHandler.cpp deleted file mode 100644 index 0330c31..0000000 --- a/DDrawCompat/DDraw/ActivateAppHandler.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include - -#include "Common/Hook.h" -#include "Common/Log.h" -#include "DDraw/ActivateAppHandler.h" -#include "DDraw/RealPrimarySurface.h" -#include "Gdi/Gdi.h" -#include "Win32/DisplayMode.h" -#include "Win32/FontSmoothing.h" - -namespace -{ - Win32::FontSmoothing::SystemSettings g_fontSmoothingSettings = {}; - WNDPROC g_origDdWndProc = nullptr; - - void activateApp() - { - Win32::FontSmoothing::setSystemSettings(g_fontSmoothingSettings); - } - - void deactivateApp() - { - g_fontSmoothingSettings = Win32::FontSmoothing::getSystemSettings(); - Win32::FontSmoothing::setSystemSettings(Win32::FontSmoothing::g_origSystemSettings); - } - - LRESULT CALLBACK ddWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - LOG_FUNC("ddWndProc", hwnd, Compat::logWm(uMsg), Compat::hex(wParam), Compat::hex(lParam)); - static bool isDisplayChangeNotificationEnabled = true; - - switch (uMsg) - { - case WM_ACTIVATEAPP: - { - isDisplayChangeNotificationEnabled = false; - if (TRUE == wParam) - { - activateApp(); - } - else - { - deactivateApp(); - } - - LRESULT result = g_origDdWndProc(hwnd, uMsg, wParam, lParam); - - isDisplayChangeNotificationEnabled = true; - return LOG_RESULT(result); - } - - case WM_DISPLAYCHANGE: - { - // Fix for alt-tabbing in Commandos 2 - if (!isDisplayChangeNotificationEnabled) - { - return LOG_RESULT(0); - } - break; - } - } - - return LOG_RESULT(g_origDdWndProc(hwnd, uMsg, wParam, lParam)); - } -} - -namespace DDraw -{ - namespace ActivateAppHandler - { - void setCooperativeLevel(HWND hwnd, DWORD flags) - { - static bool isDdWndProcHooked = false; - if ((flags & DDSCL_FULLSCREEN) && !isDdWndProcHooked) - { - g_origDdWndProc = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_WNDPROC)); - Compat::hookFunction(reinterpret_cast(g_origDdWndProc), ddWndProc, "ddWndProc"); - isDdWndProcHooked = true; - } - } - } -} diff --git a/DDrawCompat/DDraw/ActivateAppHandler.h b/DDrawCompat/DDraw/ActivateAppHandler.h deleted file mode 100644 index 9220c7a..0000000 --- a/DDrawCompat/DDraw/ActivateAppHandler.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -namespace DDraw -{ - namespace ActivateAppHandler - { - void setCooperativeLevel(HWND hwnd, DWORD flags); - } -} diff --git a/DDrawCompat/DDraw/DirectDraw.cpp b/DDrawCompat/DDraw/DirectDraw.cpp index 6e55120..94cd1ad 100644 --- a/DDrawCompat/DDraw/DirectDraw.cpp +++ b/DDrawCompat/DDraw/DirectDraw.cpp @@ -1,9 +1,8 @@ -#include "Common/CompatPtr.h" -#include "D3dDdi/KernelModeThunks.h" -#include "DDraw/ActivateAppHandler.h" -#include "DDraw/DirectDraw.h" -#include "DDraw/Surfaces/PrimarySurface.h" -#include "Win32/DisplayMode.h" +#include +#include +#include +#include +#include namespace DDraw { @@ -67,7 +66,6 @@ namespace DDraw vtable.CreateSurface = &CreateSurface; vtable.FlipToGDISurface = &FlipToGDISurface; vtable.GetGDISurface = &GetGDISurface; - vtable.SetCooperativeLevel = &SetCooperativeLevel; vtable.WaitForVerticalBlank = &WaitForVerticalBlank; } @@ -125,18 +123,6 @@ namespace DDraw return s_origVtable.Initialize(This, lpGUID); } - template - HRESULT STDMETHODCALLTYPE DirectDraw::SetCooperativeLevel( - TDirectDraw* This, HWND hWnd, DWORD dwFlags) - { - HRESULT result = s_origVtable.SetCooperativeLevel(This, hWnd, dwFlags); - if (SUCCEEDED(result)) - { - ActivateAppHandler::setCooperativeLevel(hWnd, dwFlags); - } - return result; - } - template HRESULT STDMETHODCALLTYPE DirectDraw::WaitForVerticalBlank( TDirectDraw* This, DWORD dwFlags, HANDLE hEvent) diff --git a/DDrawCompat/DDraw/DirectDraw.h b/DDrawCompat/DDraw/DirectDraw.h index 8387b9f..c7d80e1 100644 --- a/DDrawCompat/DDraw/DirectDraw.h +++ b/DDrawCompat/DDraw/DirectDraw.h @@ -2,10 +2,10 @@ #include -#include "Common/CompatRef.h" -#include "Common/CompatVtable.h" -#include "DDraw/Visitors/DirectDrawVtblVisitor.h" -#include "DDraw/Types.h" +#include +#include +#include +#include namespace DDraw { @@ -31,7 +31,6 @@ namespace DDraw static HRESULT STDMETHODCALLTYPE FlipToGDISurface(TDirectDraw* This); static HRESULT STDMETHODCALLTYPE GetGDISurface(TDirectDraw* This, TSurface** lplpGDIDDSSurface); static HRESULT STDMETHODCALLTYPE Initialize(TDirectDraw* This, GUID* lpGUID); - static HRESULT STDMETHODCALLTYPE SetCooperativeLevel(TDirectDraw* This, HWND hWnd, DWORD dwFlags); static HRESULT STDMETHODCALLTYPE WaitForVerticalBlank(TDirectDraw* This, DWORD dwFlags, HANDLE hEvent); }; } diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj index 23a714b..f973d85 100644 --- a/DDrawCompat/DDrawCompat.vcxproj +++ b/DDrawCompat/DDrawCompat.vcxproj @@ -170,7 +170,6 @@ - @@ -214,6 +213,7 @@ + @@ -229,7 +229,6 @@ - @@ -255,7 +254,6 @@ - @@ -285,6 +283,7 @@ + @@ -300,7 +299,6 @@ - diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters index 3470305..1b8d844 100644 --- a/DDrawCompat/DDrawCompat.vcxproj.filters +++ b/DDrawCompat/DDrawCompat.vcxproj.filters @@ -117,9 +117,6 @@ Header Files\DDraw - - Header Files\DDraw - Header Files\DDraw @@ -225,9 +222,6 @@ Header Files\Direct3d\Visitors - - Header Files\Win32 - Header Files\Win32 @@ -387,6 +381,9 @@ Header Files\Direct3d + + Header Files\Gdi + @@ -425,9 +422,6 @@ Source Files\DDraw - - Source Files\DDraw - Source Files\DDraw @@ -476,9 +470,6 @@ Source Files\Common - - Source Files\Win32 - Source Files\Win32 @@ -596,6 +587,9 @@ Source Files\Direct3d + + Source Files\Gdi + diff --git a/DDrawCompat/Dll/DllMain.cpp b/DDrawCompat/Dll/DllMain.cpp index f19ad6e..a9694cb 100644 --- a/DDrawCompat/Dll/DllMain.cpp +++ b/DDrawCompat/Dll/DllMain.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -144,7 +143,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) SetProcessDPIAware(); SetThemeAppProperties(0); - Win32::FontSmoothing::g_origSystemSettings = Win32::FontSmoothing::getSystemSettings(); Win32::MsgHooks::installHooks(); Time::init(); @@ -164,7 +162,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) Compat::unhookAllFunctions(); FreeLibrary(g_origDDrawModule); } - Win32::FontSmoothing::setSystemSettingsForced(Win32::FontSmoothing::g_origSystemSettings); timeEndPeriod(1); Compat::Log() << "DDrawCompat detached successfully"; } diff --git a/DDrawCompat/Gdi/DcFunctions.cpp b/DDrawCompat/Gdi/DcFunctions.cpp index 89004cf..b976dce 100644 --- a/DDrawCompat/Gdi/DcFunctions.cpp +++ b/DDrawCompat/Gdi/DcFunctions.cpp @@ -1,15 +1,16 @@ #include -#include "Common/Hook.h" -#include "Common/Log.h" -#include "Gdi/AccessGuard.h" -#include "Gdi/Dc.h" -#include "Gdi/DcFunctions.h" -#include "Gdi/Gdi.h" -#include "Gdi/Region.h" -#include "Gdi/VirtualScreen.h" -#include "Gdi/Window.h" -#include "Win32/DisplayMode.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace { @@ -164,6 +165,13 @@ namespace return LOG_RESULT(TRUE); } + template + Result WINAPI compatGdiTextDcFunc(HDC dc, Params... params) + { + Gdi::Font::Mapper fontMapper(dc); + return compatGdiDcFunc(dc, params...); + } + HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy) { LOG_FUNC("CreateCompatibleBitmap", hdc, cx, cy); @@ -230,6 +238,12 @@ namespace return &compatGdiDcFunc; } + template + OrigFuncPtr getCompatGdiTextDcFuncPtr(FuncPtr) + { + return &compatGdiTextDcFunc; + } + HDC getFirstDc() { return nullptr; @@ -289,6 +303,17 @@ namespace moduleName, funcName, getCompatGdiDcFuncPtr(origFunc)); } + template + void hookGdiTextDcFunction(const char* moduleName, const char* funcName) + { +#ifdef DEBUGLOGS + g_funcNames[origFunc] = funcName; +#endif + + Compat::hookFunction( + moduleName, funcName, getCompatGdiTextDcFuncPtr(origFunc)); + } + int WINAPI getRandomRgn(HDC hdc, HRGN hrgn, INT iNum) { int result = CALL_ORIG_FUNC(GetRandomRgn)(hdc, hrgn, iNum); @@ -319,8 +344,8 @@ namespace hookGdiDcFunction(#module, #func) #define HOOK_GDI_TEXT_DC_FUNCTION(module, func) \ - HOOK_GDI_DC_FUNCTION(module, func##A); \ - HOOK_GDI_DC_FUNCTION(module, func##W) + hookGdiTextDcFunction(#module, #func "A"); \ + hookGdiTextDcFunction(#module, #func "W") namespace Gdi { diff --git a/DDrawCompat/Gdi/Font.cpp b/DDrawCompat/Gdi/Font.cpp new file mode 100644 index 0000000..15ea050 --- /dev/null +++ b/DDrawCompat/Gdi/Font.cpp @@ -0,0 +1,107 @@ +#include +#include +#include + +namespace +{ + BOOL g_isFontSmoothingEnabled = FALSE; + + BOOL WINAPI systemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni, + decltype(&SystemParametersInfoA) origSystemParametersInfo, const char* origFuncName) + { + LOG_FUNC(origFuncName, Compat::hex(uiAction), uiParam, pvParam, fWinIni); + switch (uiAction) + { + case SPI_GETFONTSMOOTHING: + if (pvParam) + { + *static_cast(pvParam) = g_isFontSmoothingEnabled; + return TRUE; + } + break; + case SPI_SETFONTSMOOTHING: + g_isFontSmoothingEnabled = 0 != uiParam; + return TRUE; + } + return LOG_RESULT(origSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni)); + } + + BOOL WINAPI systemParametersInfoA(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni) + { + return systemParametersInfo(uiAction, uiParam, pvParam, fWinIni, + CALL_ORIG_FUNC(SystemParametersInfoA), "SystemParametersInfoA"); + } + + BOOL WINAPI systemParametersInfoW(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni) + { + return systemParametersInfo(uiAction, uiParam, pvParam, fWinIni, + CALL_ORIG_FUNC(SystemParametersInfoW), "SystemParametersInfoW"); + } +} + +namespace Gdi +{ + namespace Font + { + Mapper::Mapper(HDC dc) : m_dc(dc), m_origFont(nullptr) + { + if (!dc || g_isFontSmoothingEnabled) + { + return; + } + + HFONT origFont = static_cast(GetCurrentObject(dc, OBJ_FONT)); + if (!origFont) + { + return; + } + + LOGFONT logFont = {}; + GetObject(origFont, sizeof(logFont), &logFont); + switch (logFont.lfQuality) + { + case NONANTIALIASED_QUALITY: + case ANTIALIASED_QUALITY: + case CLEARTYPE_QUALITY: + case CLEARTYPE_NATURAL_QUALITY: + return; + } + + logFont.lfQuality = NONANTIALIASED_QUALITY; + m_origFont = static_cast(SelectObject(dc, CreateFontIndirect(&logFont))); + } + + Mapper::~Mapper() + { + if (m_origFont) + { + DeleteObject(SelectObject(m_dc, m_origFont)); + } + } + + void installHooks() + { + SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &g_isFontSmoothingEnabled, 0); + + char fontSmoothing[2] = {}; + DWORD fontSmoothingSize = sizeof(fontSmoothing); + RegGetValue(HKEY_CURRENT_USER, "Control Panel\\Desktop", "FontSmoothing", RRF_RT_REG_SZ, nullptr, + &fontSmoothing, &fontSmoothingSize); + + BOOL isFontSmoothingEnabledInRegistry = 0 == strcmp(fontSmoothing, "2"); + if (isFontSmoothingEnabledInRegistry != g_isFontSmoothingEnabled) + { + SystemParametersInfo(SPI_SETFONTSMOOTHING, isFontSmoothingEnabledInRegistry, nullptr, + SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); + } + + HOOK_FUNCTION(user32, SystemParametersInfoA, systemParametersInfoA); + HOOK_FUNCTION(user32, SystemParametersInfoW, systemParametersInfoW); + } + + bool isFontSmoothingEnabled() + { + return g_isFontSmoothingEnabled; + } + } +} diff --git a/DDrawCompat/Gdi/Font.h b/DDrawCompat/Gdi/Font.h new file mode 100644 index 0000000..1b75301 --- /dev/null +++ b/DDrawCompat/Gdi/Font.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace Gdi +{ + namespace Font + { + class Mapper + { + public: + Mapper(HDC dc); + ~Mapper(); + + private: + HDC m_dc; + HFONT m_origFont; + }; + + void installHooks(); + } +} diff --git a/DDrawCompat/Gdi/Gdi.cpp b/DDrawCompat/Gdi/Gdi.cpp index c5cc25a..b58eaae 100644 --- a/DDrawCompat/Gdi/Gdi.cpp +++ b/DDrawCompat/Gdi/Gdi.cpp @@ -1,14 +1,15 @@ -#include "DDraw/Surfaces/PrimarySurface.h" -#include "Gdi/Caret.h" -#include "Gdi/Dc.h" -#include "Gdi/DcCache.h" -#include "Gdi/DcFunctions.h" -#include "Gdi/Gdi.h" -#include "Gdi/PaintHandlers.h" -#include "Gdi/Palette.h" -#include "Gdi/ScrollFunctions.h" -#include "Gdi/Window.h" -#include "Gdi/WinProc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace { @@ -47,6 +48,7 @@ namespace Gdi Window::installHooks(); WinProc::installHooks(); Caret::installHooks(); + Font::installHooks(); } bool isDisplayDc(HDC dc) diff --git a/DDrawCompat/Win32/FontSmoothing.cpp b/DDrawCompat/Win32/FontSmoothing.cpp deleted file mode 100644 index 68595a8..0000000 --- a/DDrawCompat/Win32/FontSmoothing.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include - -#include "Win32/FontSmoothing.h" - -namespace Win32 -{ - namespace FontSmoothing - { - SystemSettings g_origSystemSettings = {}; - - bool SystemSettings::operator==(const SystemSettings& rhs) const - { - return isEnabled == rhs.isEnabled && - type == rhs.type && - contrast == rhs.contrast && - orientation == rhs.orientation; - } - - bool SystemSettings::operator!=(const SystemSettings& rhs) const - { - return !(*this == rhs); - } - - SystemSettings getSystemSettings() - { - SystemSettings settings = {}; - SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &settings.isEnabled, 0); - SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &settings.type, 0); - SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &settings.contrast, 0); - SystemParametersInfo(SPI_GETFONTSMOOTHINGORIENTATION, 0, &settings.orientation, 0); - return settings; - } - - void setSystemSettings(const SystemSettings& settings) - { - if (settings != getSystemSettings()) - { - setSystemSettingsForced(settings); - } - } - - void setSystemSettingsForced(const SystemSettings& settings) - { - SystemParametersInfo(SPI_SETFONTSMOOTHING, settings.isEnabled, nullptr, 0); - SystemParametersInfo(SPI_SETFONTSMOOTHINGTYPE, 0, - reinterpret_cast(settings.type), 0); - SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, - reinterpret_cast(settings.contrast), 0); - SystemParametersInfo(SPI_SETFONTSMOOTHINGORIENTATION, 0, - reinterpret_cast(settings.orientation), 0); - - const char* regKey = "FontSmoothing"; - PostMessage(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETFONTSMOOTHING, reinterpret_cast(regKey)); - RedrawWindow(nullptr, nullptr, nullptr, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN); - } - } -} diff --git a/DDrawCompat/Win32/FontSmoothing.h b/DDrawCompat/Win32/FontSmoothing.h deleted file mode 100644 index 014ea9e..0000000 --- a/DDrawCompat/Win32/FontSmoothing.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include - -namespace Win32 -{ - namespace FontSmoothing - { - struct SystemSettings - { - BOOL isEnabled; - UINT type; - UINT contrast; - UINT orientation; - - bool operator==(const SystemSettings& rhs) const; - bool operator!=(const SystemSettings& rhs) const; - }; - - extern SystemSettings g_origSystemSettings; - - SystemSettings getSystemSettings(); - void setSystemSettings(const SystemSettings& settings); - void setSystemSettingsForced(const SystemSettings& settings); - } -}