1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Emulate disabled font smoothing

This commit is contained in:
narzoul 2020-04-28 01:06:13 +02:00
parent e4f8cc97d9
commit 10f61c11e9
13 changed files with 196 additions and 242 deletions

View File

@ -1,82 +0,0 @@
#include <ddraw.h>
#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<WNDPROC>(GetWindowLongPtr(hwnd, GWLP_WNDPROC));
Compat::hookFunction(reinterpret_cast<void*&>(g_origDdWndProc), ddWndProc, "ddWndProc");
isDdWndProcHooked = true;
}
}
}
}

View File

@ -1,11 +0,0 @@
#pragma once
#include <Windows.h>
namespace DDraw
{
namespace ActivateAppHandler
{
void setCooperativeLevel(HWND hwnd, DWORD flags);
}
}

View File

@ -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 <Common/CompatPtr.h>
#include <D3dDdi/KernelModeThunks.h>
#include <DDraw/DirectDraw.h>
#include <DDraw/Surfaces/PrimarySurface.h>
#include <Win32/DisplayMode.h>
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 <typename TDirectDraw>
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::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 <typename TDirectDraw>
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::WaitForVerticalBlank(
TDirectDraw* This, DWORD dwFlags, HANDLE hEvent)

View File

@ -2,10 +2,10 @@
#include <ddraw.h>
#include "Common/CompatRef.h"
#include "Common/CompatVtable.h"
#include "DDraw/Visitors/DirectDrawVtblVisitor.h"
#include "DDraw/Types.h"
#include <Common/CompatRef.h>
#include <Common/CompatVtable.h>
#include <DDraw/Visitors/DirectDrawVtblVisitor.h>
#include <DDraw/Types.h>
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);
};
}

View File

@ -170,7 +170,6 @@
<ClInclude Include="D3dDdi\Visitors\AdapterFuncsVisitor.h" />
<ClInclude Include="D3dDdi\Visitors\DeviceCallbacksVisitor.h" />
<ClInclude Include="D3dDdi\Visitors\DeviceFuncsVisitor.h" />
<ClInclude Include="DDraw\ActivateAppHandler.h" />
<ClInclude Include="DDraw\Blitter.h" />
<ClInclude Include="DDraw\DirectDraw.h" />
<ClInclude Include="DDraw\DirectDrawClipper.h" />
@ -214,6 +213,7 @@
<ClInclude Include="Direct3d\Visitors\Direct3dVtblVisitor.h" />
<ClInclude Include="Dll\Procs.h" />
<ClInclude Include="Gdi\AccessGuard.h" />
<ClInclude Include="Gdi\Font.h" />
<ClInclude Include="Gdi\Gdi.h" />
<ClInclude Include="Gdi\Caret.h" />
<ClInclude Include="Gdi\Dc.h" />
@ -229,7 +229,6 @@
<ClInclude Include="Gdi\Window.h" />
<ClInclude Include="Gdi\WinProc.h" />
<ClInclude Include="Win32\DisplayMode.h" />
<ClInclude Include="Win32\FontSmoothing.h" />
<ClInclude Include="Win32\Log.h" />
<ClInclude Include="Win32\MsgHooks.h" />
<ClInclude Include="Win32\Registry.h" />
@ -255,7 +254,6 @@
<ClCompile Include="D3dDdi\Log\KernelModeThunksLog.cpp" />
<ClCompile Include="D3dDdi\Resource.cpp" />
<ClCompile Include="D3dDdi\ScopedCriticalSection.cpp" />
<ClCompile Include="DDraw\ActivateAppHandler.cpp" />
<ClCompile Include="DDraw\Blitter.cpp" />
<ClCompile Include="DDraw\DirectDraw.cpp" />
<ClCompile Include="DDraw\DirectDrawClipper.cpp" />
@ -285,6 +283,7 @@
<ClCompile Include="Dll\DllMain.cpp" />
<ClCompile Include="Dll\UnmodifiedProcs.cpp" />
<ClCompile Include="Gdi\AccessGuard.cpp" />
<ClCompile Include="Gdi\Font.cpp" />
<ClCompile Include="Gdi\Gdi.cpp" />
<ClCompile Include="Gdi\Caret.cpp" />
<ClCompile Include="Gdi\Dc.cpp" />
@ -300,7 +299,6 @@
<ClCompile Include="Gdi\Window.cpp" />
<ClCompile Include="Gdi\WinProc.cpp" />
<ClCompile Include="Win32\DisplayMode.cpp" />
<ClCompile Include="Win32\FontSmoothing.cpp" />
<ClCompile Include="Win32\Log.cpp" />
<ClCompile Include="Win32\MsgHooks.cpp" />
<ClCompile Include="Win32\Registry.cpp" />

View File

@ -117,9 +117,6 @@
<ClInclude Include="DDraw\RealPrimarySurface.h">
<Filter>Header Files\DDraw</Filter>
</ClInclude>
<ClInclude Include="DDraw\ActivateAppHandler.h">
<Filter>Header Files\DDraw</Filter>
</ClInclude>
<ClInclude Include="DDraw\Hooks.h">
<Filter>Header Files\DDraw</Filter>
</ClInclude>
@ -225,9 +222,6 @@
<ClInclude Include="Direct3d\Visitors\Direct3dVtblVisitor.h">
<Filter>Header Files\Direct3d\Visitors</Filter>
</ClInclude>
<ClInclude Include="Win32\FontSmoothing.h">
<Filter>Header Files\Win32</Filter>
</ClInclude>
<ClInclude Include="Win32\MsgHooks.h">
<Filter>Header Files\Win32</Filter>
</ClInclude>
@ -387,6 +381,9 @@
<ClInclude Include="Direct3d\Direct3dExecuteBuffer.h">
<Filter>Header Files\Direct3d</Filter>
</ClInclude>
<ClInclude Include="Gdi\Font.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Gdi\Gdi.cpp">
@ -425,9 +422,6 @@
<ClCompile Include="DDraw\RealPrimarySurface.cpp">
<Filter>Source Files\DDraw</Filter>
</ClCompile>
<ClCompile Include="DDraw\ActivateAppHandler.cpp">
<Filter>Source Files\DDraw</Filter>
</ClCompile>
<ClCompile Include="DDraw\Hooks.cpp">
<Filter>Source Files\DDraw</Filter>
</ClCompile>
@ -476,9 +470,6 @@
<ClCompile Include="Common\Log.cpp">
<Filter>Source Files\Common</Filter>
</ClCompile>
<ClCompile Include="Win32\FontSmoothing.cpp">
<Filter>Source Files\Win32</Filter>
</ClCompile>
<ClCompile Include="Win32\MsgHooks.cpp">
<Filter>Source Files\Win32</Filter>
</ClCompile>
@ -596,6 +587,9 @@
<ClCompile Include="Direct3d\Direct3dExecuteBuffer.cpp">
<Filter>Source Files\Direct3d</Filter>
</ClCompile>
<ClCompile Include="Gdi\Font.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="Dll\DDrawCompat.def">

View File

@ -15,7 +15,6 @@
#include <Gdi/Gdi.h>
#include <Gdi/VirtualScreen.h>
#include <Win32/DisplayMode.h>
#include <Win32/FontSmoothing.h>
#include <Win32/MsgHooks.h>
#include <Win32/Registry.h>
#include <Win32/TimeFunctions.h>
@ -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";
}

View File

@ -1,15 +1,16 @@
#include <unordered_map>
#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 <Common/Hook.h>
#include <Common/Log.h>
#include <Gdi/AccessGuard.h>
#include <Gdi/Dc.h>
#include <Gdi/DcFunctions.h>
#include <Gdi/Font.h>
#include <Gdi/Gdi.h>
#include <Gdi/Region.h>
#include <Gdi/VirtualScreen.h>
#include <Gdi/Window.h>
#include <Win32/DisplayMode.h>
namespace
{
@ -164,6 +165,13 @@ namespace
return LOG_RESULT(TRUE);
}
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename Result, typename... Params>
Result WINAPI compatGdiTextDcFunc(HDC dc, Params... params)
{
Gdi::Font::Mapper fontMapper(dc);
return compatGdiDcFunc<OrigFuncPtr, origFunc, Result>(dc, params...);
}
HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy)
{
LOG_FUNC("CreateCompatibleBitmap", hdc, cx, cy);
@ -230,6 +238,12 @@ namespace
return &compatGdiDcFunc<OrigFuncPtr, origFunc, Result, Params...>;
}
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename Result, typename... Params>
OrigFuncPtr getCompatGdiTextDcFuncPtr(FuncPtr<Result, HDC, Params...>)
{
return &compatGdiTextDcFunc<OrigFuncPtr, origFunc, Result, Params...>;
}
HDC getFirstDc()
{
return nullptr;
@ -289,6 +303,17 @@ namespace
moduleName, funcName, getCompatGdiDcFuncPtr<OrigFuncPtr, origFunc>(origFunc));
}
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
void hookGdiTextDcFunction(const char* moduleName, const char* funcName)
{
#ifdef DEBUGLOGS
g_funcNames[origFunc] = funcName;
#endif
Compat::hookFunction<OrigFuncPtr, origFunc>(
moduleName, funcName, getCompatGdiTextDcFuncPtr<OrigFuncPtr, origFunc>(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<decltype(&func), &func>(#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<decltype(&func##A), &func##A>(#module, #func "A"); \
hookGdiTextDcFunction<decltype(&func##W), &func##W>(#module, #func "W")
namespace Gdi
{

107
DDrawCompat/Gdi/Font.cpp Normal file
View File

@ -0,0 +1,107 @@
#include <Common/Hook.h>
#include <Common/Log.h>
#include <Gdi/Font.h>
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<BOOL*>(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<HFONT>(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<HFONT>(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;
}
}
}

22
DDrawCompat/Gdi/Font.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include <Windows.h>
namespace Gdi
{
namespace Font
{
class Mapper
{
public:
Mapper(HDC dc);
~Mapper();
private:
HDC m_dc;
HFONT m_origFont;
};
void installHooks();
}
}

View File

@ -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 <DDraw/Surfaces/PrimarySurface.h>
#include <Gdi/Caret.h>
#include <Gdi/Dc.h>
#include <Gdi/DcCache.h>
#include <Gdi/DcFunctions.h>
#include <Gdi/Font.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>
namespace
{
@ -47,6 +48,7 @@ namespace Gdi
Window::installHooks();
WinProc::installHooks();
Caret::installHooks();
Font::installHooks();
}
bool isDisplayDc(HDC dc)

View File

@ -1,57 +0,0 @@
#include <Windows.h>
#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<void*>(settings.type), 0);
SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0,
reinterpret_cast<void*>(settings.contrast), 0);
SystemParametersInfo(SPI_SETFONTSMOOTHINGORIENTATION, 0,
reinterpret_cast<void*>(settings.orientation), 0);
const char* regKey = "FontSmoothing";
PostMessage(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETFONTSMOOTHING, reinterpret_cast<LPARAM>(regKey));
RedrawWindow(nullptr, nullptr, nullptr, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
}
}
}

View File

@ -1,26 +0,0 @@
#pragma once
#include <Windows.h>
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);
}
}