mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added DisplayAspectRatio setting
This commit is contained in:
parent
6425c6c767
commit
d6f07bac76
@ -28,7 +28,7 @@ public:
|
||||
{
|
||||
static unsigned origVtableSize = 0;
|
||||
auto vtableSize = getVtableSize(version);
|
||||
memcpy(const_cast<Vtable*>(&vtable), &s_origVtable, min(vtableSize, origVtableSize));
|
||||
memcpy(const_cast<Vtable*>(&vtable), &s_origVtable, std::min(vtableSize, origVtableSize));
|
||||
|
||||
class NullLock {};
|
||||
hookVtable<NullLock>(vtable, version);
|
||||
|
141
DDrawCompat/Common/Vector.h
Normal file
141
DDrawCompat/Common/Vector.h
Normal file
@ -0,0 +1,141 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
template <typename Elem, std::size_t size>
|
||||
class VectorRepresentation
|
||||
{
|
||||
private:
|
||||
Elem values[size];
|
||||
};
|
||||
|
||||
template <typename Elem>
|
||||
class VectorRepresentation<Elem, 2>
|
||||
{
|
||||
public:
|
||||
Elem x;
|
||||
Elem y;
|
||||
};
|
||||
|
||||
template <typename Elem, std::size_t size>
|
||||
class Vector : public VectorRepresentation<Elem, size>
|
||||
{
|
||||
public:
|
||||
template <typename... Values>
|
||||
Vector(Values... v)
|
||||
{
|
||||
asArray() = { static_cast<Elem>(v)... };
|
||||
}
|
||||
|
||||
Vector(SIZE s) : Vector(s.cx, s.cy)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename OtherElem>
|
||||
Vector(const Vector<OtherElem, size>& other)
|
||||
{
|
||||
for (std::size_t i = 0; i < size; ++i)
|
||||
{
|
||||
(*this)[i] = static_cast<Elem>(other[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Value>
|
||||
Vector(Value v)
|
||||
{
|
||||
asArray().fill(static_cast<Elem>(v));
|
||||
}
|
||||
|
||||
Elem& operator[](std::size_t index)
|
||||
{
|
||||
return asArray()[index];
|
||||
}
|
||||
|
||||
const Elem& operator[](std::size_t index) const
|
||||
{
|
||||
return const_cast<Vector*>(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<Elem, size>& asArray()
|
||||
{
|
||||
return *reinterpret_cast<std::array<Elem, size>*>(this);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Elem, std::size_t size, typename Operator>
|
||||
Vector<Elem, size> binaryOperation(Operator op, const Vector<Elem, size>& lhs, const Vector<Elem, size>& rhs)
|
||||
{
|
||||
Vector<Elem, size> result;
|
||||
for (std::size_t i = 0; i < size; ++i)
|
||||
{
|
||||
result[i] = op(lhs[i], rhs[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Elem, std::size_t size, typename Operator>
|
||||
Vector<Elem, size> unaryOperation(Operator op, const Vector<Elem, size>& vec)
|
||||
{
|
||||
Vector<Elem, size> result;
|
||||
for (std::size_t i = 0; i < size; ++i)
|
||||
{
|
||||
result[i] = op(vec[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#define DEFINE_VECTOR_BINARY_OPERATOR(name, ...) \
|
||||
template <typename Elem, std::size_t size> \
|
||||
inline Vector<Elem, size> name(const Vector<Elem, size>& lhs, const Vector<Elem, size>& rhs) \
|
||||
{ \
|
||||
return binaryOperation([](Elem x, Elem y) { return __VA_ARGS__; }, lhs, rhs); \
|
||||
}
|
||||
|
||||
#define DEFINE_VECTOR_UNARY_OPERATOR(name, ...) \
|
||||
template <typename Elem, std::size_t size> \
|
||||
inline Vector<Elem, size> name(const Vector<Elem, size>& 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<float, 2> Float2;
|
||||
typedef Vector<int, 2> Int2;
|
@ -8,6 +8,7 @@
|
||||
#include <Config/Settings/CpuAffinityRotation.h>
|
||||
#include <Config/Settings/DepthFormat.h>
|
||||
#include <Config/Settings/DesktopColorDepth.h>
|
||||
#include <Config/Settings/DisplayAspectRatio.h>
|
||||
#include <Config/Settings/DisplayFilter.h>
|
||||
#include <Config/Settings/DisplayRefreshRate.h>
|
||||
#include <Config/Settings/DisplayResolution.h>
|
||||
@ -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;
|
||||
|
@ -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") ||
|
||||
|
@ -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);
|
||||
|
39
DDrawCompat/Config/Settings/DisplayAspectRatio.cpp
Normal file
39
DDrawCompat/Config/Settings/DisplayAspectRatio.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include <Config/Settings/DisplayAspectRatio.h>
|
||||
|
||||
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 };
|
||||
}
|
||||
}
|
27
DDrawCompat/Config/Settings/DisplayAspectRatio.h
Normal file
27
DDrawCompat/Config/Settings/DisplayAspectRatio.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include <Common/Comparison.h>
|
||||
#include <Config/MappedSetting.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
class DisplayAspectRatio : public MappedSetting<SIZE>
|
||||
{
|
||||
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;
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
#include <Common/Comparison.h>
|
||||
#include <Common/CompatVtable.h>
|
||||
#include <Config/Settings/Antialiasing.h>
|
||||
#include <Config/Settings/DisplayAspectRatio.h>
|
||||
#include <Config/Settings/PalettizedTextures.h>
|
||||
#include <Config/Settings/ResolutionScale.h>
|
||||
#include <Config/Settings/SupportedDepthFormats.h>
|
||||
@ -15,6 +16,7 @@
|
||||
#include <D3dDdi/DeviceFuncs.h>
|
||||
#include <D3dDdi/FormatInfo.h>
|
||||
#include <D3dDdi/KernelModeThunks.h>
|
||||
#include <Win32/DisplayMode.h>
|
||||
|
||||
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<float>(caps.dwMaxTextureWidth) / size.cx;
|
||||
const float scaleY = static_cast<float>(caps.dwMaxTextureHeight) / size.cy;
|
||||
return min(scaleX, scaleY);
|
||||
}
|
||||
|
||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> Adapter::getMultisampleConfig(D3DDDIFORMAT format) const
|
||||
{
|
||||
UINT samples = Config::antialiasing.get();
|
||||
@ -154,54 +167,62 @@ namespace D3dDdi
|
||||
levels.Format = D3DDDIFMT_X8R8G8B8;
|
||||
levels.MsType = static_cast<D3DDDIMULTISAMPLE_TYPE>(samples);
|
||||
getCaps(D3DDDICAPS_GETMULTISAMPLEQUALITYLEVELS, levels);
|
||||
return { levels.MsType, min(static_cast<UINT>(Config::antialiasing.getParam()), levels.QualityLevels - 1) };
|
||||
return { levels.MsType, std::min(static_cast<UINT>(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<long>(dm.dmPelsHeight), static_cast<long>(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<long>(dm.dmPelsHeight), static_cast<long>(dm.dmPelsHeight) };
|
||||
}
|
||||
|
||||
float scaleX = static_cast<float>(baseSize.cx) / emulatedDisplaySize.cx;
|
||||
float scaleY = static_cast<float>(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<LONG>(size.cx * scale);
|
||||
size.cy = static_cast<LONG>(size.cy * scale);
|
||||
|
||||
const auto& caps = getInfo().d3dExtendedCaps;
|
||||
size.cx = min(size.cx, static_cast<LONG>(caps.dwMaxTextureWidth));
|
||||
size.cy = min(size.cy, static_cast<LONG>(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<D3DDDIFORMAT, FORMATOP>& formatOps) const
|
||||
|
@ -8,7 +8,9 @@
|
||||
#include <d3dumddi.h>
|
||||
|
||||
#include <Common/CompatPtr.h>
|
||||
#include <Common/Vector.h>
|
||||
#include <DDraw/DirectDraw.h>
|
||||
#include <Win32/DisplayMode.h>
|
||||
|
||||
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<D3DDDIMULTISAMPLE_TYPE, UINT> getMultisampleConfig(D3DDDIFORMAT format) const;
|
||||
const D3DDDI_ADAPTERFUNCS& getOrigVtable() const { return m_origVtable; }
|
||||
CompatWeakPtr<IDirectDraw7> 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 <typename Data>
|
||||
HRESULT getCaps(D3DDDICAPS_TYPE type, Data& data, UINT size = sizeof(Data)) const;
|
||||
|
||||
Int2 getAspectRatio(Win32::DisplayMode::Resolution res) const;
|
||||
std::map<D3DDDIFORMAT, FORMATOP> getFormatOps() const;
|
||||
float getMaxScaleFactor(SIZE size) const;
|
||||
Float2 getScaleFactor() const;
|
||||
std::string getSupportedMsaaModes(const std::map<D3DDDIFORMAT, FORMATOP>& formatOps) const;
|
||||
DWORD getSupportedZBufferBitDepths(const std::map<D3DDDIFORMAT, FORMATOP>& formatOps) const;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<LONG>(si.Width), static_cast<LONG>(si.Height) };
|
||||
|
||||
|
@ -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)
|
||||
|
@ -63,7 +63,7 @@
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;CINTERFACE;_NO_DDRAWINT_NO_COM;PSAPI_VERSION=1;WIN32;_DEBUG;_WINDOWS;_USRDLL;DDRAWCOMPAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;NOMINMAX;CINTERFACE;_NO_DDRAWINT_NO_COM;PSAPI_VERSION=1;WIN32;_DEBUG;_WINDOWS;_USRDLL;DDRAWCOMPAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
|
||||
@ -101,7 +101,7 @@
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;CINTERFACE;_NO_DDRAWINT_NO_COM;PSAPI_VERSION=1;WIN32;NDEBUG;_WINDOWS;_USRDLL;DDRAWCOMPAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;NOMINMAX;CINTERFACE;_NO_DDRAWINT_NO_COM;PSAPI_VERSION=1;WIN32;NDEBUG;_WINDOWS;_USRDLL;DDRAWCOMPAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
|
||||
@ -146,6 +146,7 @@
|
||||
<ClInclude Include="Common\Rect.h" />
|
||||
<ClInclude Include="Common\ScopedSrwLock.h" />
|
||||
<ClInclude Include="Common\ScopedThreadPriority.h" />
|
||||
<ClInclude Include="Common\Vector.h" />
|
||||
<ClInclude Include="Common\VtableHookVisitor.h" />
|
||||
<ClInclude Include="Common\VtableSizeVisitor.h" />
|
||||
<ClInclude Include="Common\VtableVisitor.h" />
|
||||
@ -169,6 +170,7 @@
|
||||
<ClInclude Include="Config\Settings\CpuAffinityRotation.h" />
|
||||
<ClInclude Include="Config\Settings\DepthFormat.h" />
|
||||
<ClInclude Include="Config\Settings\DesktopColorDepth.h" />
|
||||
<ClInclude Include="Config\Settings\DisplayAspectRatio.h" />
|
||||
<ClInclude Include="Config\Settings\DisplayFilter.h" />
|
||||
<ClInclude Include="Config\Settings\DisplayRefreshRate.h" />
|
||||
<ClInclude Include="Config\Settings\DisplayResolution.h" />
|
||||
@ -330,6 +332,7 @@
|
||||
<ClCompile Include="Config\Setting.cpp" />
|
||||
<ClCompile Include="Config\Settings\Antialiasing.cpp" />
|
||||
<ClCompile Include="Config\Settings\CpuAffinity.cpp" />
|
||||
<ClCompile Include="Config\Settings\DisplayAspectRatio.cpp" />
|
||||
<ClCompile Include="Config\Settings\DisplayFilter.cpp" />
|
||||
<ClCompile Include="Config\Settings\DisplayRefreshRate.cpp" />
|
||||
<ClCompile Include="Config\Settings\DisplayResolution.cpp" />
|
||||
|
@ -651,6 +651,12 @@
|
||||
<ClInclude Include="Config\Settings\DepthFormat.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\Settings\DisplayAspectRatio.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\Vector.h">
|
||||
<Filter>Header Files\Common</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
@ -1028,6 +1034,9 @@
|
||||
<ClCompile Include="Config\Settings\SupportedDepthFormats.cpp">
|
||||
<Filter>Source Files\Config\Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Config\Settings\DisplayAspectRatio.cpp">
|
||||
<Filter>Source Files\Config\Settings</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="DDrawCompat.rc">
|
||||
|
@ -339,7 +339,7 @@ namespace
|
||||
{
|
||||
RECT parentRect = {};
|
||||
GetWindowRect(parent, &parentRect);
|
||||
wp.x = max(parentRect.left + 3 - wp.cx, 0);
|
||||
wp.x = std::max<int>(parentRect.left + 3 - wp.cx, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -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<Gdi::Region*>(dwData);
|
||||
|
@ -120,8 +120,8 @@ namespace
|
||||
auto& llHook = *reinterpret_cast<MSLLHOOKSTRUCT*>(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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 });
|
||||
|
||||
|
@ -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<LONG>(g_emulatedDisplayMode.width), static_cast<LONG>(g_emulatedDisplayMode.height) };
|
||||
}
|
||||
}
|
||||
return 0 != displayResolution.cx ? displayResolution : Win32::DisplayMode::getDisplayResolution(deviceName);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
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<LONG>(dm.dmPelsWidth), static_cast<LONG>(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)();
|
||||
|
@ -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();
|
||||
|
@ -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<DWORD>(sizeof(viEx), vi.dwOSVersionInfoSize));
|
||||
return logOsVersionInfoEx(os, viEx);
|
||||
}
|
||||
}
|
||||
|
@ -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<std::size_t>(0, oss.str().length() - 2));
|
||||
}
|
||||
|
||||
DWORD rotateMask(DWORD mask)
|
||||
|
Loading…
x
Reference in New Issue
Block a user