diff --git a/DDrawCompat/Config/Config.cpp b/DDrawCompat/Config/Config.cpp index b5e3f8d..a13e93a 100644 --- a/DDrawCompat/Config/Config.cpp +++ b/DDrawCompat/Config/Config.cpp @@ -7,6 +7,7 @@ namespace Config Settings::CpuAffinity cpuAffinity; Settings::DesktopColorDepth desktopColorDepth; Settings::DisplayFilter displayFilter; + Settings::DisplayRefreshRate displayRefreshRate; Settings::DisplayResolution displayResolution; Settings::RenderColorDepth renderColorDepth; Settings::ResolutionScale resolutionScale; diff --git a/DDrawCompat/Config/Config.h b/DDrawCompat/Config/Config.h index 85b216c..6e498a1 100644 --- a/DDrawCompat/Config/Config.h +++ b/DDrawCompat/Config/Config.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,7 @@ namespace Config extern Settings::CpuAffinity cpuAffinity; extern Settings::DesktopColorDepth desktopColorDepth; extern Settings::DisplayFilter displayFilter; + extern Settings::DisplayRefreshRate displayRefreshRate; extern Settings::DisplayResolution displayResolution; extern Settings::RenderColorDepth renderColorDepth; extern Settings::ResolutionScale resolutionScale; diff --git a/DDrawCompat/Config/Settings/DisplayRefreshRate.cpp b/DDrawCompat/Config/Settings/DisplayRefreshRate.cpp new file mode 100644 index 0000000..3a75b5e --- /dev/null +++ b/DDrawCompat/Config/Settings/DisplayRefreshRate.cpp @@ -0,0 +1,36 @@ +#include + +namespace Config +{ + namespace Settings + { + DisplayRefreshRate::DisplayRefreshRate() + : MappedSetting("DisplayRefreshRate", "app", { {"app", APP}, {"desktop", DESKTOP} }) + { + } + + std::string DisplayRefreshRate::getValueStr() const + { + try + { + return MappedSetting::getValueStr(); + } + catch (const ParsingError&) + { + return std::to_string(m_value); + } + } + + void DisplayRefreshRate::setValue(const std::string& value) + { + try + { + MappedSetting::setValue(value); + } + catch (const ParsingError&) + { + m_value = Parser::parseInt(value, 1, MAXINT); + } + } + } +} diff --git a/DDrawCompat/Config/Settings/DisplayRefreshRate.h b/DDrawCompat/Config/Settings/DisplayRefreshRate.h new file mode 100644 index 0000000..0a49c15 --- /dev/null +++ b/DDrawCompat/Config/Settings/DisplayRefreshRate.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace Config +{ + namespace Settings + { + class DisplayRefreshRate : public MappedSetting + { + public: + static const int APP = 0; + static const int DESKTOP = -1; + + DisplayRefreshRate(); + + protected: + std::string getValueStr() const override; + void setValue(const std::string& value) override; + }; + } +} diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj index b6388a8..31d6abb 100644 --- a/DDrawCompat/DDrawCompat.vcxproj +++ b/DDrawCompat/DDrawCompat.vcxproj @@ -220,6 +220,7 @@ + @@ -343,6 +344,7 @@ + diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters index 845994c..9641688 100644 --- a/DDrawCompat/DDrawCompat.vcxproj.filters +++ b/DDrawCompat/DDrawCompat.vcxproj.filters @@ -516,6 +516,9 @@ Header Files\Gdi + + Header Files\Config\Settings + @@ -815,6 +818,9 @@ Source Files\Gdi + + Source Files\Config\Settings + diff --git a/DDrawCompat/Win32/DisplayMode.cpp b/DDrawCompat/Win32/DisplayMode.cpp index 19dcd51..8fc2dc8 100644 --- a/DDrawCompat/Win32/DisplayMode.cpp +++ b/DDrawCompat/Win32/DisplayMode.cpp @@ -63,6 +63,9 @@ namespace BOOL WINAPI dwm8And16BitIsShimAppliedCallOut(); BOOL WINAPI seComHookInterface(CLSID* clsid, GUID* iid, DWORD unk1, DWORD unk2); + template + DWORD getConfiguredRefreshRate(const Char* deviceName); + template SIZE getConfiguredResolution(const Char* deviceName); @@ -125,6 +128,11 @@ namespace targetDevMode.dmFields |= DM_PELSHEIGHT; targetDevMode.dmPelsHeight = currDevMode.dmPelsHeight; } + if (!(targetDevMode.dmFields & DM_DISPLAYFREQUENCY)) + { + targetDevMode.dmFields |= DM_DISPLAYFREQUENCY; + targetDevMode.dmDisplayFrequency = currDevMode.dmDisplayFrequency; + } emulatedResolution = makeSize(targetDevMode.dmPelsWidth, targetDevMode.dmPelsHeight); auto supportedDisplayModeMap(getSupportedDisplayModeMap(lpszDeviceName, 0)); @@ -137,23 +145,31 @@ namespace return DISP_CHANGE_BADMODE; } + DevMode dm = targetDevMode; SIZE resolutionOverride = getConfiguredResolution(lpszDeviceName); if (0 != resolutionOverride.cx) { - DevMode dm = {}; - dm.dmSize = sizeof(dm); - dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; dm.dmPelsWidth = resolutionOverride.cx; dm.dmPelsHeight = resolutionOverride.cy; + } + + DWORD refreshRateOverride = getConfiguredRefreshRate(lpszDeviceName); + if (0 != refreshRateOverride) + { + dm.dmDisplayFrequency = refreshRateOverride; + } + + if (0 != resolutionOverride.cx || 0 != refreshRateOverride) + { LONG result = origChangeDisplaySettingsEx(lpszDeviceName, &dm, nullptr, CDS_TEST, nullptr); if (DISP_CHANGE_SUCCESSFUL == result) { - targetDevMode.dmPelsWidth = resolutionOverride.cx; - targetDevMode.dmPelsHeight = resolutionOverride.cy; + targetDevMode = dm; } else { - LOG_ONCE("Failed to apply setting: DisplayResolution = " << dm.dmPelsWidth << 'x' << dm.dmPelsHeight); + LOG_ONCE("Failed to apply custom display mode: " + << dm.dmPelsWidth << 'x' << dm.dmPelsHeight << '@' << dm.dmDisplayFrequency); } } } @@ -352,6 +368,22 @@ namespace return CALL_ORIG_FUNC(GdiEntry13)() + g_displaySettingsUniquenessBias; } + template + DWORD getConfiguredRefreshRate(const Char* deviceName) + { + auto refreshRate = Config::displayRefreshRate.get(); + if (Config::Settings::DisplayRefreshRate::DESKTOP == refreshRate) + { + DevMode dm = {}; + dm.dmSize = sizeof(dm); + if (origEnumDisplaySettingsEx(deviceName, ENUM_REGISTRY_SETTINGS, &dm, 0)) + { + refreshRate = dm.dmDisplayFrequency; + } + } + return refreshRate; + } + template SIZE getConfiguredResolution(const Char* deviceName) {