diff --git a/DDrawCompat/Common/CompatVtable.h b/DDrawCompat/Common/CompatVtable.h index 9f6d9f6..e73c6f9 100644 --- a/DDrawCompat/Common/CompatVtable.h +++ b/DDrawCompat/Common/CompatVtable.h @@ -28,7 +28,7 @@ public: { static unsigned origVtableSize = 0; auto vtableSize = getVtableSize(version); - memcpy(const_cast(&vtable), &s_origVtable, min(vtableSize, origVtableSize)); + memcpy(const_cast(&vtable), &s_origVtable, std::min(vtableSize, origVtableSize)); class NullLock {}; hookVtable(vtable, version); diff --git a/DDrawCompat/Common/Vector.h b/DDrawCompat/Common/Vector.h new file mode 100644 index 0000000..5d00c8b --- /dev/null +++ b/DDrawCompat/Common/Vector.h @@ -0,0 +1,141 @@ +#pragma once + +#include +#include +#include + +#include + +template +class VectorRepresentation +{ +private: + Elem values[size]; +}; + +template +class VectorRepresentation +{ +public: + Elem x; + Elem y; +}; + +template +class Vector : public VectorRepresentation +{ +public: + template + Vector(Values... v) + { + asArray() = { static_cast(v)... }; + } + + Vector(SIZE s) : Vector(s.cx, s.cy) + { + } + + template + Vector(const Vector& other) + { + for (std::size_t i = 0; i < size; ++i) + { + (*this)[i] = static_cast(other[i]); + } + } + + template + Vector(Value v) + { + asArray().fill(static_cast(v)); + } + + Elem& operator[](std::size_t index) + { + return asArray()[index]; + } + + const Elem& operator[](std::size_t index) const + { + return const_cast(this)->asArray()[index]; + } + +#define DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(op) \ + Vector& operator##op##=(const Vector& other) \ + { \ + return *this = *this op other; \ + } + + DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(+); + DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(-); + DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(*); + DEFINE_COMPOUND_ASSIGNMENT_OPERATOR(/); + +#undef DEFINE_COMPOUND_ASSIGNMENT_OPERATOR + +private: + std::array& asArray() + { + return *reinterpret_cast*>(this); + } +}; + +template +Vector binaryOperation(Operator op, const Vector& lhs, const Vector& rhs) +{ + Vector result; + for (std::size_t i = 0; i < size; ++i) + { + result[i] = op(lhs[i], rhs[i]); + } + return result; +} + +template +Vector unaryOperation(Operator op, const Vector& vec) +{ + Vector result; + for (std::size_t i = 0; i < size; ++i) + { + result[i] = op(vec[i]); + } + return result; +} + +#define DEFINE_VECTOR_BINARY_OPERATOR(name, ...) \ + template \ + inline Vector name(const Vector& lhs, const Vector& rhs) \ + { \ + return binaryOperation([](Elem x, Elem y) { return __VA_ARGS__; }, lhs, rhs); \ + } + +#define DEFINE_VECTOR_UNARY_OPERATOR(name, ...) \ + template \ + inline Vector name(const Vector& vec) \ + { \ + return unaryOperation([](Elem x) { return __VA_ARGS__; }, vec); \ + } + +#define DEFINE_VECTOR_BUILTIN_BINARY_OPERATOR(op) DEFINE_VECTOR_BINARY_OPERATOR(operator ## op, x op y) +#define DEFINE_VECTOR_STD_BINARY_OPERATOR(op) DEFINE_VECTOR_BINARY_OPERATOR(op, std::op(x, y)) +#define DEFINE_VECTOR_STD_UNARY_OPERATOR(op) DEFINE_VECTOR_UNARY_OPERATOR(op, std::op(x)) + +DEFINE_VECTOR_BUILTIN_BINARY_OPERATOR(+); +DEFINE_VECTOR_BUILTIN_BINARY_OPERATOR(-); +DEFINE_VECTOR_BUILTIN_BINARY_OPERATOR(*); +DEFINE_VECTOR_BUILTIN_BINARY_OPERATOR(/); + +DEFINE_VECTOR_STD_BINARY_OPERATOR(max); +DEFINE_VECTOR_STD_BINARY_OPERATOR(min); + +DEFINE_VECTOR_STD_UNARY_OPERATOR(ceil); +DEFINE_VECTOR_STD_UNARY_OPERATOR(floor); + +#undef DEFINE_VECTOR_BINARY_OPERATOR +#undef DEFINE_VECTOR_UNARY_OPERATOR +#undef DEFINE_VECTOR_BUILTIN_BINARY_OPERATOR +#undef DEFINE_VECTOR_STD_BINARY_OPERATOR +#undef DEFINE_VECTOR_STD_UNARY_OPERATOR + +typedef Vector Float2; +typedef Vector Int2; diff --git a/DDrawCompat/Config/Config.cpp b/DDrawCompat/Config/Config.cpp index 9d310ce..56ec5a3 100644 --- a/DDrawCompat/Config/Config.cpp +++ b/DDrawCompat/Config/Config.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ namespace Config Settings::CpuAffinity cpuAffinity; Settings::CpuAffinityRotation cpuAffinityRotation; Settings::DepthFormat depthFormat; + Settings::DisplayAspectRatio displayAspectRatio; Settings::DesktopColorDepth desktopColorDepth; Settings::DisplayFilter displayFilter; Settings::DisplayRefreshRate displayRefreshRate; diff --git a/DDrawCompat/Config/Parser.cpp b/DDrawCompat/Config/Parser.cpp index a37e141..628c0b1 100644 --- a/DDrawCompat/Config/Parser.cpp +++ b/DDrawCompat/Config/Parser.cpp @@ -150,6 +150,23 @@ namespace Config } } + SIZE parseAspectRatio(const std::string& value) + { + try + { + auto pos = value.find(':'); + if (pos != std::string::npos) + { + return { parseInt(value.substr(0, pos), 1, MAXUINT16), parseInt(value.substr(pos + 1), 1, MAXUINT16) }; + } + } + catch (ParsingError&) + { + } + + throw ParsingError("invalid aspect ratio: '" + value + "'"); + } + int parseInt(const std::string& value, int min, int max) { if (value.empty() || std::string::npos != value.find_first_not_of("+-0123456789") || diff --git a/DDrawCompat/Config/Parser.h b/DDrawCompat/Config/Parser.h index 35973a0..9063542 100644 --- a/DDrawCompat/Config/Parser.h +++ b/DDrawCompat/Config/Parser.h @@ -20,8 +20,9 @@ namespace Config { std::filesystem::path getOverlayConfigPath(); void loadAllConfigFiles(const std::filesystem::path& processPath); - SIZE parseResolution(const std::string& value); + SIZE parseAspectRatio(const std::string& value); int parseInt(const std::string& value, int min, int max); + SIZE parseResolution(const std::string& value); void registerSetting(Setting& setting); std::string removeParam(const std::string& value); std::string tolower(const std::string& str); diff --git a/DDrawCompat/Config/Settings/DisplayAspectRatio.cpp b/DDrawCompat/Config/Settings/DisplayAspectRatio.cpp new file mode 100644 index 0000000..321463b --- /dev/null +++ b/DDrawCompat/Config/Settings/DisplayAspectRatio.cpp @@ -0,0 +1,39 @@ +#include + +namespace Config +{ + namespace Settings + { + DisplayAspectRatio::DisplayAspectRatio() + : MappedSetting("DisplayAspectRatio", "app", { {"app", APP}, {"display", DISPLAY} }) + { + } + + std::string DisplayAspectRatio::getValueStr() const + { + try + { + return MappedSetting::getValueStr(); + } + catch (const ParsingError&) + { + return std::to_string(m_value.cx) + ':' + std::to_string(m_value.cy); + } + } + + void DisplayAspectRatio::setValue(const std::string& value) + { + try + { + MappedSetting::setValue(value); + } + catch (const ParsingError&) + { + m_value = Parser::parseAspectRatio(value); + } + } + + const SIZE DisplayAspectRatio::APP = { 0, 0 }; + const SIZE DisplayAspectRatio::DISPLAY = { 1, 0 }; + } +} diff --git a/DDrawCompat/Config/Settings/DisplayAspectRatio.h b/DDrawCompat/Config/Settings/DisplayAspectRatio.h new file mode 100644 index 0000000..3bedb96 --- /dev/null +++ b/DDrawCompat/Config/Settings/DisplayAspectRatio.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +#include +#include + +namespace Config +{ + namespace Settings + { + class DisplayAspectRatio : public MappedSetting + { + public: + static const SIZE APP; + static const SIZE DISPLAY; + + DisplayAspectRatio(); + + protected: + std::string getValueStr() const override; + void setValue(const std::string& value) override; + }; + } + + extern Settings::DisplayAspectRatio displayAspectRatio; +} diff --git a/DDrawCompat/D3dDdi/Adapter.cpp b/DDrawCompat/D3dDdi/Adapter.cpp index 5b34cd1..7d4769d 100644 --- a/DDrawCompat/D3dDdi/Adapter.cpp +++ b/DDrawCompat/D3dDdi/Adapter.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include namespace { @@ -59,6 +61,25 @@ namespace D3dDdi { } + Int2 Adapter::getAspectRatio(Win32::DisplayMode::Resolution res) const + { + SIZE ar = Config::displayAspectRatio.get(); + if (Config::Settings::DisplayAspectRatio::APP == ar) + { + return 0 != res.app.cx ? res.app : Win32::DisplayMode::getAppResolution(m_deviceName); + } + else if (Config::Settings::DisplayAspectRatio::DISPLAY == ar) + { + return 0 != res.display.cx ? res.display : Win32::DisplayMode::getDisplayResolution(m_deviceName); + } + return ar; + } + + Int2 Adapter::getAspectRatio() const + { + return getAspectRatio({}); + } + const Adapter::AdapterInfo& Adapter::getInfo() const { auto it = s_adapterInfos.find(m_luid); @@ -122,14 +143,6 @@ namespace D3dDdi return result; } - float Adapter::getMaxScaleFactor(SIZE size) const - { - const auto& caps = getInfo().d3dExtendedCaps; - const float scaleX = static_cast(caps.dwMaxTextureWidth) / size.cx; - const float scaleY = static_cast(caps.dwMaxTextureHeight) / size.cy; - return min(scaleX, scaleY); - } - std::pair Adapter::getMultisampleConfig(D3DDDIFORMAT format) const { UINT samples = Config::antialiasing.get(); @@ -154,54 +167,62 @@ namespace D3dDdi levels.Format = D3DDDIFMT_X8R8G8B8; levels.MsType = static_cast(samples); getCaps(D3DDDICAPS_GETMULTISAMPLEQUALITYLEVELS, levels); - return { levels.MsType, min(static_cast(Config::antialiasing.getParam()), levels.QualityLevels - 1) }; + return { levels.MsType, std::min(static_cast(Config::antialiasing.getParam()), levels.QualityLevels - 1) }; } - SIZE Adapter::getScaledSize(SIZE size) const + SIZE Adapter::getScaledSize(Int2 size) const { - DEVMODEW dm = {}; - dm.dmSize = sizeof(dm); - EnumDisplaySettingsExW(m_deviceName.c_str(), ENUM_CURRENT_SETTINGS, &dm, 0); - - const SIZE emulatedDisplaySize = { static_cast(dm.dmPelsHeight), static_cast(dm.dmPelsHeight) }; - const float displayMaxScaleFactor = getMaxScaleFactor(emulatedDisplaySize); - const float resourceMaxScaleFactor = getMaxScaleFactor(size); - float maxScaleFactor = min(displayMaxScaleFactor, resourceMaxScaleFactor); - if (Config::resolutionScale.getParam() > 0) - { - maxScaleFactor = floor(maxScaleFactor); - } - - SIZE baseSize = Config::resolutionScale.get(); + const auto scaleFactor = getScaleFactor(); const int multiplier = Config::resolutionScale.getParam(); - - if (Config::Settings::ResolutionScale::APP == baseSize) - { - baseSize = emulatedDisplaySize; - } - else if (Config::Settings::ResolutionScale::DISPLAY == baseSize) - { - CALL_ORIG_FUNC(EnumDisplaySettingsExW)(m_deviceName.c_str(), ENUM_CURRENT_SETTINGS, &dm, 0); - baseSize = { static_cast(dm.dmPelsHeight), static_cast(dm.dmPelsHeight) }; - } - - float scaleX = static_cast(baseSize.cx) / emulatedDisplaySize.cx; - float scaleY = static_cast(baseSize.cy) / emulatedDisplaySize.cy; - float scale = min(scaleX, scaleY) * abs(multiplier); - if (multiplier > 0) - { - scale = ceil(scale); - } - scale = max(scale, 1.0f); - scale = min(scale, maxScaleFactor); - - size.cx = static_cast(size.cx * scale); - size.cy = static_cast(size.cy * scale); - const auto& caps = getInfo().d3dExtendedCaps; - size.cx = min(size.cx, static_cast(caps.dwMaxTextureWidth)); - size.cy = min(size.cy, static_cast(caps.dwMaxTextureHeight)); - return size; + + Int2 maxSize = { caps.dwMaxTextureWidth, caps.dwMaxTextureHeight }; + if (multiplier < 0) + { + maxSize = maxSize / size * size; + } + + Int2 scaledSize = Float2(size) * scaleFactor; + scaledSize = min(scaledSize, maxSize); + scaledSize = max(scaledSize, size); + return { scaledSize.x, scaledSize.y }; + } + + Float2 Adapter::getScaleFactor() const + { + const SIZE resolutionScale = Config::resolutionScale.get(); + const int multiplier = Config::resolutionScale.getParam(); + if (0 == multiplier || + Config::Settings::ResolutionScale::APP == resolutionScale && 1 == multiplier) + { + return 1; + } + + const auto res = Win32::DisplayMode::getResolution(m_deviceName); + Int2 targetResolution = resolutionScale; + if (Config::Settings::ResolutionScale::APP == resolutionScale) + { + targetResolution = res.app; + } + else if (Config::Settings::ResolutionScale::DISPLAY == resolutionScale) + { + targetResolution = res.display; + } + + targetResolution *= abs(multiplier); + + const Int2 ar = getAspectRatio(res); + if (targetResolution.y * ar.x / ar.y <= targetResolution.x) + { + targetResolution.x = targetResolution.y * ar.x / ar.y; + } + else + { + targetResolution.y = targetResolution.x * ar.y / ar.x; + } + + const auto scaleFactor = Float2(targetResolution) / Float2(res.app); + return multiplier < 0 ? scaleFactor : ceil(scaleFactor); } std::string Adapter::getSupportedMsaaModes(const std::map& formatOps) const diff --git a/DDrawCompat/D3dDdi/Adapter.h b/DDrawCompat/D3dDdi/Adapter.h index 97a78e8..6ec562d 100644 --- a/DDrawCompat/D3dDdi/Adapter.h +++ b/DDrawCompat/D3dDdi/Adapter.h @@ -8,7 +8,9 @@ #include #include +#include #include +#include namespace D3dDdi { @@ -31,12 +33,13 @@ namespace D3dDdi operator HANDLE() const { return m_adapter; } + Int2 getAspectRatio() const; const AdapterInfo& getInfo() const; LUID getLuid() const { return m_luid; } std::pair getMultisampleConfig(D3DDDIFORMAT format) const; const D3DDDI_ADAPTERFUNCS& getOrigVtable() const { return m_origVtable; } CompatWeakPtr getRepository() const { return m_repository; } - SIZE getScaledSize(SIZE size) const; + SIZE getScaledSize(Int2 size) const; HRESULT pfnCloseAdapter(); HRESULT pfnCreateDevice(D3DDDIARG_CREATEDEVICE* pCreateData); @@ -50,8 +53,9 @@ namespace D3dDdi template HRESULT getCaps(D3DDDICAPS_TYPE type, Data& data, UINT size = sizeof(Data)) const; + Int2 getAspectRatio(Win32::DisplayMode::Resolution res) const; std::map getFormatOps() const; - float getMaxScaleFactor(SIZE size) const; + Float2 getScaleFactor() const; std::string getSupportedMsaaModes(const std::map& formatOps) const; DWORD getSupportedZBufferBitDepths(const std::map& formatOps) const; diff --git a/DDrawCompat/D3dDdi/DeviceState.cpp b/DDrawCompat/D3dDdi/DeviceState.cpp index dd15817..cf6c5ba 100644 --- a/DDrawCompat/D3dDdi/DeviceState.cpp +++ b/DDrawCompat/D3dDdi/DeviceState.cpp @@ -223,7 +223,7 @@ namespace D3dDdi m_changedStates |= CS_TEXTURE_STAGE; m_changedTextureStageStates[stage].set(D3DDDITSS_ADDRESSU); m_changedTextureStageStates[stage].set(D3DDDITSS_ADDRESSV); - m_maxChangedTextureStage = max(stage, m_maxChangedTextureStage); + m_maxChangedTextureStage = std::max(stage, m_maxChangedTextureStage); } void DeviceState::flush() @@ -502,7 +502,7 @@ namespace D3dDdi m_changedRenderStates.set(D3DDDIRS_COLORKEYENABLE); m_changedTextureStageStates[stage].set(D3DDDITSS_ADDRESSU); m_changedTextureStageStates[stage].set(D3DDDITSS_ADDRESSV); - m_maxChangedTextureStage = max(stage, m_maxChangedTextureStage); + m_maxChangedTextureStage = std::max(stage, m_maxChangedTextureStage); return S_OK; } @@ -514,7 +514,7 @@ namespace D3dDdi m_app.textureStageState[data->Stage][D3DDDITSS_ADDRESSV] = data->Value; m_changedTextureStageStates[data->Stage].set(D3DDDITSS_ADDRESSU); m_changedTextureStageStates[data->Stage].set(D3DDDITSS_ADDRESSV); - m_maxChangedTextureStage = max(data->Stage, m_maxChangedTextureStage); + m_maxChangedTextureStage = std::max(data->Stage, m_maxChangedTextureStage); return S_OK; } @@ -531,7 +531,7 @@ namespace D3dDdi m_app.textureStageState[data->Stage][data->State] = data->Value; m_changedTextureStageStates[data->Stage].set(data->State); - m_maxChangedTextureStage = max(data->Stage, m_maxChangedTextureStage); + m_maxChangedTextureStage = std::max(data->Stage, m_maxChangedTextureStage); return S_OK; } @@ -775,7 +775,7 @@ namespace D3dDdi { setTexture(stage, texture); m_changedStates |= CS_TEXTURE_STAGE; - m_maxChangedTextureStage = max(stage, m_maxChangedTextureStage); + m_maxChangedTextureStage = std::max(stage, m_maxChangedTextureStage); } void DeviceState::setTempTextureStageState(const D3DDDIARG_TEXTURESTAGESTATE& tss) @@ -783,7 +783,7 @@ namespace D3dDdi setTextureStageState(tss); m_changedStates |= CS_TEXTURE_STAGE; m_changedTextureStageStates[tss.Stage].set(tss.State); - m_maxChangedTextureStage = max(tss.Stage, m_maxChangedTextureStage); + m_maxChangedTextureStage = std::max(tss.Stage, m_maxChangedTextureStage); } void DeviceState::setTempVertexShaderDecl(HANDLE decl) diff --git a/DDrawCompat/D3dDdi/KernelModeThunks.cpp b/DDrawCompat/D3dDdi/KernelModeThunks.cpp index 5e34b58..7e67006 100644 --- a/DDrawCompat/D3dDdi/KernelModeThunks.cpp +++ b/DDrawCompat/D3dDdi/KernelModeThunks.cpp @@ -222,13 +222,13 @@ namespace const ULONGLONG maxMem = 0x3FFF0000; if (info->DedicatedVideoMemorySize < maxMem) { - auto addedMem = min(maxMem - info->DedicatedVideoMemorySize, info->SharedSystemMemorySize); + auto addedMem = std::min(maxMem - info->DedicatedVideoMemorySize, info->SharedSystemMemorySize); info->DedicatedVideoMemorySize += addedMem; info->SharedSystemMemorySize -= addedMem; } - info->DedicatedVideoMemorySize = min(info->DedicatedVideoMemorySize, maxMem); - info->SharedSystemMemorySize = min(info->SharedSystemMemorySize, maxMem); + info->DedicatedVideoMemorySize = std::min(info->DedicatedVideoMemorySize, maxMem); + info->SharedSystemMemorySize = std::min(info->SharedSystemMemorySize, maxMem); break; } } diff --git a/DDrawCompat/D3dDdi/Resource.cpp b/DDrawCompat/D3dDdi/Resource.cpp index e833af2..7d238b0 100644 --- a/DDrawCompat/D3dDdi/Resource.cpp +++ b/DDrawCompat/D3dDdi/Resource.cpp @@ -59,11 +59,6 @@ namespace return rect; } - RECT calculatePresentationRect() - { - return calculateScaledRect(DDraw::PrimarySurface::getMonitorRect(), DDraw::RealPrimarySurface::getMonitorRect()); - } - LONG divCeil(LONG n, LONG d) { return (n + d - 1) / d; @@ -669,8 +664,8 @@ namespace D3dDdi { while (srcWidth > 2 * dstWidth || srcHeight > 2 * dstHeight) { - const LONG newSrcWidth = max(dstWidth, (srcWidth + 1) / 2); - const LONG newSrcHeight = max(dstHeight, (srcHeight + 1) / 2); + const LONG newSrcWidth = std::max(dstWidth, (srcWidth + 1) / 2); + const LONG newSrcHeight = std::max(dstHeight, (srcHeight + 1) / 2); auto& nextRt = getNextRenderTarget(rt, newSrcWidth, newSrcHeight); if (!nextRt.resource) { @@ -1444,7 +1439,8 @@ namespace D3dDdi if (isFullscreen) { - g_presentationRect = calculatePresentationRect(); + const Int2 ar = m_device.getAdapter().getAspectRatio(); + g_presentationRect = calculateScaledRect({ 0, 0, ar.x, ar.y }, DDraw::RealPrimarySurface::getMonitorRect()); auto& si = m_origData.pSurfList[0]; RECT primaryRect = { 0, 0, static_cast(si.Width), static_cast(si.Height) }; diff --git a/DDrawCompat/D3dDdi/SurfaceRepository.cpp b/DDrawCompat/D3dDdi/SurfaceRepository.cpp index c84fc6b..7e82924 100644 --- a/DDrawCompat/D3dDdi/SurfaceRepository.cpp +++ b/DDrawCompat/D3dDdi/SurfaceRepository.cpp @@ -261,7 +261,8 @@ namespace D3dDdi SurfaceRepository::Surface& SurfaceRepository::getTempSurface(Surface& surface, DWORD width, DWORD height, D3DDDIFORMAT format, DWORD caps, UINT surfaceCount) { - return getSurface(surface, max(width, surface.width), max(height, surface.height), format, caps, surfaceCount); + return getSurface(surface, std::max(width, surface.width), std::max(height, surface.height), + format, caps, surfaceCount); } SurfaceRepository::Surface& SurfaceRepository::getTempSysMemSurface(DWORD width, DWORD height) diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj index cebe649..4b9bf29 100644 --- a/DDrawCompat/DDrawCompat.vcxproj +++ b/DDrawCompat/DDrawCompat.vcxproj @@ -63,7 +63,7 @@ Level4 - WIN32_LEAN_AND_MEAN;CINTERFACE;_NO_DDRAWINT_NO_COM;PSAPI_VERSION=1;WIN32;_DEBUG;_WINDOWS;_USRDLL;DDRAWCOMPAT_EXPORTS;%(PreprocessorDefinitions) + WIN32_LEAN_AND_MEAN;NOMINMAX;CINTERFACE;_NO_DDRAWINT_NO_COM;PSAPI_VERSION=1;WIN32;_DEBUG;_WINDOWS;_USRDLL;DDRAWCOMPAT_EXPORTS;%(PreprocessorDefinitions) MultiThreadedDebug true $(IntDir)%(RelativeDir) @@ -101,7 +101,7 @@ Level4 - WIN32_LEAN_AND_MEAN;CINTERFACE;_NO_DDRAWINT_NO_COM;PSAPI_VERSION=1;WIN32;NDEBUG;_WINDOWS;_USRDLL;DDRAWCOMPAT_EXPORTS;%(PreprocessorDefinitions) + WIN32_LEAN_AND_MEAN;NOMINMAX;CINTERFACE;_NO_DDRAWINT_NO_COM;PSAPI_VERSION=1;WIN32;NDEBUG;_WINDOWS;_USRDLL;DDRAWCOMPAT_EXPORTS;%(PreprocessorDefinitions) MultiThreaded true $(IntDir)%(RelativeDir) @@ -146,6 +146,7 @@ + @@ -169,6 +170,7 @@ + @@ -330,6 +332,7 @@ + diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters index c092d4a..072379a 100644 --- a/DDrawCompat/DDrawCompat.vcxproj.filters +++ b/DDrawCompat/DDrawCompat.vcxproj.filters @@ -651,6 +651,12 @@ Header Files\Config\Settings + + Header Files\Config\Settings + + + Header Files\Common + @@ -1028,6 +1034,9 @@ Source Files\Config\Settings + + Source Files\Config\Settings + diff --git a/DDrawCompat/Gdi/User32WndProcs.cpp b/DDrawCompat/Gdi/User32WndProcs.cpp index d480d37..ae30ad7 100644 --- a/DDrawCompat/Gdi/User32WndProcs.cpp +++ b/DDrawCompat/Gdi/User32WndProcs.cpp @@ -339,7 +339,7 @@ namespace { RECT parentRect = {}; GetWindowRect(parent, &parentRect); - wp.x = max(parentRect.left + 3 - wp.cx, 0); + wp.x = std::max(parentRect.left + 3 - wp.cx, 0); } else { diff --git a/DDrawCompat/Gdi/VirtualScreen.cpp b/DDrawCompat/Gdi/VirtualScreen.cpp index 3ff6e2d..99083fb 100644 --- a/DDrawCompat/Gdi/VirtualScreen.cpp +++ b/DDrawCompat/Gdi/VirtualScreen.cpp @@ -42,19 +42,16 @@ namespace BOOL CALLBACK addMonitorRectToRegion( HMONITOR hMonitor, HDC /*hdcMonitor*/, LPRECT lprcMonitor, LPARAM dwData) { - MONITORINFOEX mi = {}; + MONITORINFOEXW mi = {}; mi.cbSize = sizeof(mi); - CALL_ORIG_FUNC(GetMonitorInfoA)(hMonitor, &mi); - - DEVMODE dm = {}; - dm.dmSize = sizeof(dm); - CALL_ORIG_FUNC(EnumDisplaySettingsExA)(mi.szDevice, ENUM_CURRENT_SETTINGS, &dm, 0); + CALL_ORIG_FUNC(GetMonitorInfoW)(hMonitor, &mi); + auto res = Win32::DisplayMode::getDisplayResolution(mi.szDevice); RECT rect = *lprcMonitor; - if (0 != dm.dmPelsWidth && 0 != dm.dmPelsHeight) + if (0 != res.cx && 0 != res.cy) { - rect.right = rect.left + dm.dmPelsWidth; - rect.bottom = rect.top + dm.dmPelsHeight; + rect.right = rect.left + res.cx; + rect.bottom = rect.top + res.cy; } Gdi::Region& virtualScreenRegion = *reinterpret_cast(dwData); diff --git a/DDrawCompat/Input/Input.cpp b/DDrawCompat/Input/Input.cpp index afefc0f..1d436fc 100644 --- a/DDrawCompat/Input/Input.cpp +++ b/DDrawCompat/Input/Input.cpp @@ -120,8 +120,8 @@ namespace auto& llHook = *reinterpret_cast(lParam); cp.x += (llHook.pt.x - origCp.x); cp.y += (llHook.pt.y - origCp.y); - cp.x = min(max(g_monitorRect.left, cp.x), g_monitorRect.right); - cp.y = min(max(g_monitorRect.top, cp.y), g_monitorRect.bottom); + cp.x = std::min(std::max(g_monitorRect.left, cp.x), g_monitorRect.right); + cp.y = std::min(std::max(g_monitorRect.top, cp.y), g_monitorRect.bottom); g_cursorPos = cp; DDraw::RealPrimarySurface::scheduleOverlayUpdate(); } diff --git a/DDrawCompat/Overlay/ScrollBarControl.cpp b/DDrawCompat/Overlay/ScrollBarControl.cpp index 2fecbae..12fd1cb 100644 --- a/DDrawCompat/Overlay/ScrollBarControl.cpp +++ b/DDrawCompat/Overlay/ScrollBarControl.cpp @@ -116,8 +116,8 @@ namespace Overlay { const auto minPos = m_leftArrow.right + ARROW_SIZE / 2; const auto maxPos = m_rightArrow.left - ARROW_SIZE / 2; - pos.x = max(pos.x, minPos); - pos.x = min(pos.x, maxPos); + pos.x = std::max(pos.x, minPos); + pos.x = std::min(pos.x, maxPos); setPos(m_min + roundDiv((pos.x - minPos) * (m_max - m_min), maxPos - minPos)); } @@ -128,8 +128,8 @@ namespace Overlay void ScrollBarControl::setPos(int pos) { - pos = max(pos, m_min); - pos = min(pos, m_max); + pos = std::max(pos, m_min); + pos = std::min(pos, m_max); if (pos != m_pos) { m_pos = pos; diff --git a/DDrawCompat/Overlay/Window.cpp b/DDrawCompat/Overlay/Window.cpp index b222849..3983bd8 100644 --- a/DDrawCompat/Overlay/Window.cpp +++ b/DDrawCompat/Overlay/Window.cpp @@ -206,8 +206,8 @@ namespace Overlay int scaleX = (monitorRect.right - monitorRect.left) / 640; int scaleY = (monitorRect.bottom - monitorRect.top) / 480; - m_scaleFactor = min(scaleX, scaleY); - m_scaleFactor = max(1, m_scaleFactor); + m_scaleFactor = std::min(scaleX, scaleY); + m_scaleFactor = std::max(1, m_scaleFactor); m_rect = calculateRect({ monitorRect.left / m_scaleFactor, monitorRect.top / m_scaleFactor, monitorRect.right / m_scaleFactor, monitorRect.bottom / m_scaleFactor }); diff --git a/DDrawCompat/Win32/DisplayMode.cpp b/DDrawCompat/Win32/DisplayMode.cpp index 32f2bf5..9be0f98 100644 --- a/DDrawCompat/Win32/DisplayMode.cpp +++ b/DDrawCompat/Win32/DisplayMode.cpp @@ -370,6 +370,18 @@ namespace return CALL_ORIG_FUNC(GdiEntry13)() + g_displaySettingsUniquenessBias; } + SIZE getAppResolution(const std::wstring& deviceName, SIZE displayResolution = {}) + { + { + Compat::ScopedSrwLockShared srwLock(g_srwLock); + if (deviceName == g_emulatedDisplayMode.deviceName) + { + return { static_cast(g_emulatedDisplayMode.width), static_cast(g_emulatedDisplayMode.height) }; + } + } + return 0 != displayResolution.cx ? displayResolution : Win32::DisplayMode::getDisplayResolution(deviceName); + } + template DWORD getConfiguredRefreshRate(const Char* deviceName) { @@ -722,11 +734,24 @@ namespace Win32 { namespace DisplayMode { + SIZE getAppResolution(const std::wstring& deviceName) + { + return ::getAppResolution(deviceName); + } + DWORD getBpp() { return getEmulatedDisplayMode().bpp; } + SIZE getDisplayResolution(const std::wstring& deviceName) + { + DEVMODEW dm = {}; + dm.dmSize = sizeof(dm); + CALL_ORIG_FUNC(EnumDisplaySettingsExW)(deviceName.c_str(), ENUM_CURRENT_SETTINGS, &dm, 0); + return { static_cast(dm.dmPelsWidth), static_cast(dm.dmPelsHeight) }; + } + EmulatedDisplayMode getEmulatedDisplayMode() { Compat::ScopedSrwLockShared lock(g_srwLock); @@ -741,6 +766,14 @@ namespace Win32 return mi; } + Resolution getResolution(const std::wstring& deviceName) + { + Resolution res = {}; + res.display = getDisplayResolution(deviceName); + res.app = ::getAppResolution(deviceName, res.display); + return res; + } + ULONG queryDisplaySettingsUniqueness() { return CALL_ORIG_FUNC(GdiEntry13)(); diff --git a/DDrawCompat/Win32/DisplayMode.h b/DDrawCompat/Win32/DisplayMode.h index d472c8f..16f579c 100644 --- a/DDrawCompat/Win32/DisplayMode.h +++ b/DDrawCompat/Win32/DisplayMode.h @@ -25,9 +25,18 @@ namespace Win32 SIZE diff; }; + struct Resolution + { + SIZE app; + SIZE display; + }; + + SIZE getAppResolution(const std::wstring& deviceName); DWORD getBpp(); + SIZE getDisplayResolution(const std::wstring& deviceName); EmulatedDisplayMode getEmulatedDisplayMode(); MONITORINFOEXW getMonitorInfo(const std::wstring& deviceName); + Resolution getResolution(const std::wstring& deviceName); ULONG queryDisplaySettingsUniqueness(); void installHooks(); diff --git a/DDrawCompat/Win32/Log.cpp b/DDrawCompat/Win32/Log.cpp index 6fa9a3c..d349f41 100644 --- a/DDrawCompat/Win32/Log.cpp +++ b/DDrawCompat/Win32/Log.cpp @@ -93,7 +93,7 @@ namespace std::ostream& logOsVersionInfo(std::ostream& os, const OsVersionInfo& vi) { OsVersionInfoEx viEx = {}; - memcpy(&viEx, &vi, min(sizeof(viEx), vi.dwOSVersionInfoSize)); + memcpy(&viEx, &vi, std::min(sizeof(viEx), vi.dwOSVersionInfoSize)); return logOsVersionInfoEx(os, viEx); } } diff --git a/DDrawCompat/Win32/Thread.cpp b/DDrawCompat/Win32/Thread.cpp index 662ee66..ec71f8f 100644 --- a/DDrawCompat/Win32/Thread.cpp +++ b/DDrawCompat/Win32/Thread.cpp @@ -140,7 +140,7 @@ namespace oss << i + 1 << ", "; } } - return oss.str().substr(0, max(0, oss.str().length() - 2)); + return oss.str().substr(0, std::max(0, oss.str().length() - 2)); } DWORD rotateMask(DWORD mask)