mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added ResolutionScale setting
This commit is contained in:
parent
8b393ea498
commit
c714383613
@ -9,6 +9,7 @@ namespace Config
|
||||
Settings::DisplayFilter displayFilter;
|
||||
Settings::DisplayResolution displayResolution;
|
||||
Settings::RenderColorDepth renderColorDepth;
|
||||
Settings::ResolutionScale resolutionScale;
|
||||
Settings::SupportedResolutions supportedResolutions;
|
||||
Settings::TextureFilter textureFilter;
|
||||
Settings::ThreadPriorityBoost threadPriorityBoost;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <Config/Settings/DisplayFilter.h>
|
||||
#include <Config/Settings/DisplayResolution.h>
|
||||
#include <Config/Settings/RenderColorDepth.h>
|
||||
#include <Config/Settings/ResolutionScale.h>
|
||||
#include <Config/Settings/SupportedResolutions.h>
|
||||
#include <Config/Settings/TextureFilter.h>
|
||||
#include <Config/Settings/ThreadPriorityBoost.h>
|
||||
@ -24,6 +25,7 @@ namespace Config
|
||||
extern Settings::DisplayFilter displayFilter;
|
||||
extern Settings::DisplayResolution displayResolution;
|
||||
extern Settings::RenderColorDepth renderColorDepth;
|
||||
extern Settings::ResolutionScale resolutionScale;
|
||||
extern Settings::SupportedResolutions supportedResolutions;
|
||||
extern Settings::TextureFilter textureFilter;
|
||||
extern Settings::ThreadPriorityBoost threadPriorityBoost;
|
||||
|
44
DDrawCompat/Config/Settings/ResolutionScale.cpp
Normal file
44
DDrawCompat/Config/Settings/ResolutionScale.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include <Config/Settings/ResolutionScale.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
ResolutionScale::ResolutionScale()
|
||||
: MappedSetting("ResolutionScale", "app", { {"app", APP}, {"display", DISPLAY} })
|
||||
{
|
||||
}
|
||||
|
||||
std::string ResolutionScale::getValueStr() const
|
||||
{
|
||||
try
|
||||
{
|
||||
return MappedSetting::getValueStr();
|
||||
}
|
||||
catch (const ParsingError&)
|
||||
{
|
||||
return std::to_string(m_value.cx) + 'x' + std::to_string(m_value.cy);
|
||||
}
|
||||
}
|
||||
|
||||
Setting::ParamInfo ResolutionScale::getParamInfo() const
|
||||
{
|
||||
return { "Multiplier", APP == m_value ? 1 : -16, 16, 1, m_param };
|
||||
}
|
||||
|
||||
void ResolutionScale::setValue(const std::string& value)
|
||||
{
|
||||
try
|
||||
{
|
||||
MappedSetting::setValue(value);
|
||||
}
|
||||
catch (const ParsingError&)
|
||||
{
|
||||
m_value = Parser::parseResolution(value);
|
||||
}
|
||||
}
|
||||
|
||||
const SIZE ResolutionScale::APP = { 0, 0 };
|
||||
const SIZE ResolutionScale::DISPLAY = { 1, 0 };
|
||||
}
|
||||
}
|
27
DDrawCompat/Config/Settings/ResolutionScale.h
Normal file
27
DDrawCompat/Config/Settings/ResolutionScale.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 ResolutionScale : public MappedSetting<SIZE>
|
||||
{
|
||||
public:
|
||||
static const SIZE APP;
|
||||
static const SIZE DISPLAY;
|
||||
|
||||
ResolutionScale();
|
||||
|
||||
virtual ParamInfo getParamInfo() const override;
|
||||
|
||||
protected:
|
||||
std::string getValueStr() const override;
|
||||
void setValue(const std::string& value) override;
|
||||
};
|
||||
}
|
||||
}
|
@ -37,6 +37,7 @@ namespace D3dDdi
|
||||
, m_runtimeVersion(data.Version)
|
||||
, m_driverVersion(data.DriverVersion)
|
||||
, m_luid(KernelModeThunks::getLastOpenAdapterInfo().luid)
|
||||
, m_deviceName(KernelModeThunks::getLastOpenAdapterInfo().monitorInfo.szDevice)
|
||||
, m_repository{}
|
||||
{
|
||||
}
|
||||
@ -56,6 +57,11 @@ namespace D3dDdi
|
||||
|
||||
Compat::Log() << "Supported z-buffer bit depths: " << bitDepthsToString(info.supportedZBufferBitDepths);
|
||||
Compat::Log() << "Supported MSAA modes: " << getSupportedMsaaModes(info.formatOps);
|
||||
LOG_DEBUG << "Supported resource formats:";
|
||||
for (const auto& formatOp : info.formatOps)
|
||||
{
|
||||
LOG_DEBUG << " " << formatOp.second;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
@ -86,6 +92,14 @@ 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();
|
||||
@ -113,6 +127,53 @@ namespace D3dDdi
|
||||
return { levels.MsType, min(static_cast<UINT>(Config::antialiasing.getParam()), levels.QualityLevels - 1) };
|
||||
}
|
||||
|
||||
SIZE Adapter::getScaledSize(SIZE 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 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;
|
||||
}
|
||||
|
||||
std::string Adapter::getSupportedMsaaModes(const std::map<D3DDDIFORMAT, FORMATOP>& formatOps) const
|
||||
{
|
||||
auto it = formatOps.find(D3DDDIFMT_X8R8G8B8);
|
||||
|
@ -35,6 +35,7 @@ namespace D3dDdi
|
||||
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;
|
||||
|
||||
HRESULT pfnCloseAdapter();
|
||||
HRESULT pfnCreateDevice(D3DDDIARG_CREATEDEVICE* pCreateData);
|
||||
@ -49,6 +50,7 @@ namespace D3dDdi
|
||||
HRESULT getCaps(D3DDDICAPS_TYPE type, Data& data, UINT size = sizeof(Data)) const;
|
||||
|
||||
std::map<D3DDDIFORMAT, FORMATOP> getFormatOps() const;
|
||||
float getMaxScaleFactor(SIZE size) const;
|
||||
std::string getSupportedMsaaModes(const std::map<D3DDDIFORMAT, FORMATOP>& formatOps) const;
|
||||
DWORD getSupportedZBufferBitDepths(const std::map<D3DDDIFORMAT, FORMATOP>& formatOps) const;
|
||||
|
||||
@ -57,6 +59,7 @@ namespace D3dDdi
|
||||
UINT m_runtimeVersion;
|
||||
UINT m_driverVersion;
|
||||
LUID m_luid;
|
||||
std::wstring m_deviceName;
|
||||
CompatWeakPtr<IDirectDraw7> m_repository;
|
||||
|
||||
static std::map<HANDLE, Adapter> s_adapters;
|
||||
|
@ -18,6 +18,7 @@ namespace
|
||||
{
|
||||
HANDLE g_gdiResourceHandle = nullptr;
|
||||
D3dDdi::Resource* g_gdiResource = nullptr;
|
||||
bool g_isConfigUpdatePending = false;
|
||||
}
|
||||
|
||||
namespace D3dDdi
|
||||
@ -163,12 +164,22 @@ namespace D3dDdi
|
||||
{
|
||||
prepareForGpuWrite();
|
||||
}
|
||||
|
||||
if (m_renderTarget && rect)
|
||||
{
|
||||
std::vector<RECT> scaledRect(rect, rect + numRect);
|
||||
for (UINT i = 0; i < numRect; ++i)
|
||||
{
|
||||
m_renderTarget->scaleRect(scaledRect[i]);
|
||||
}
|
||||
return m_origVtable.pfnClear(m_device, data, numRect, scaledRect.data());
|
||||
}
|
||||
|
||||
return m_origVtable.pfnClear(m_device, data, numRect, rect);
|
||||
}
|
||||
|
||||
HRESULT Device::pfnColorFill(const D3DDDIARG_COLORFILL* data)
|
||||
{
|
||||
flushPrimitives();
|
||||
auto it = m_resources.find(data->hResource);
|
||||
if (it != m_resources.end())
|
||||
{
|
||||
@ -309,7 +320,10 @@ namespace D3dDdi
|
||||
{
|
||||
d.hSrcResource = resource->prepareForGpuRead(data->SrcSubResourceIndex);
|
||||
}
|
||||
return m_origVtable.pfnPresent(m_device, &d);
|
||||
|
||||
HRESULT result = m_origVtable.pfnPresent(m_device, &d);
|
||||
updateAllConfigNow();
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT Device::pfnPresent1(D3DDDIARG_PRESENT1* data)
|
||||
@ -325,7 +339,10 @@ namespace D3dDdi
|
||||
srcResources[i].hResource = resource->prepareForGpuRead(srcResources[i].SubResourceIndex);
|
||||
}
|
||||
}
|
||||
return m_origVtable.pfnPresent1(m_device, data);
|
||||
|
||||
HRESULT result = m_origVtable.pfnPresent1(m_device, data);
|
||||
updateAllConfigNow();
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT Device::pfnUnlock(const D3DDDIARG_UNLOCK* data)
|
||||
@ -341,11 +358,18 @@ namespace D3dDdi
|
||||
|
||||
void Device::updateAllConfig()
|
||||
{
|
||||
DDraw::ScopedThreadLock ddLock;
|
||||
D3dDdi::ScopedCriticalSection lock;
|
||||
for (auto& device : s_devices)
|
||||
g_isConfigUpdatePending = true;
|
||||
}
|
||||
|
||||
void Device::updateAllConfigNow()
|
||||
{
|
||||
if (g_isConfigUpdatePending)
|
||||
{
|
||||
device.second.updateConfig();
|
||||
g_isConfigUpdatePending = false;
|
||||
for (auto& device : s_devices)
|
||||
{
|
||||
device.second.updateConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,8 @@ namespace D3dDdi
|
||||
static void updateAllConfig();
|
||||
|
||||
private:
|
||||
static void updateAllConfigNow();
|
||||
|
||||
D3DDDI_DEVICEFUNCS m_origVtable;
|
||||
Adapter& m_adapter;
|
||||
HANDLE m_device;
|
||||
|
@ -239,17 +239,13 @@ namespace D3dDdi
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_changedStates & CS_MISC)
|
||||
{
|
||||
updateMisc();
|
||||
}
|
||||
if (m_changedStates & CS_RENDER_STATE)
|
||||
{
|
||||
updateRenderStates();
|
||||
}
|
||||
if (m_changedStates & CS_RENDER_TARGET)
|
||||
{
|
||||
updateRenderTargets();
|
||||
updateRenderTarget();
|
||||
}
|
||||
if (m_changedStates & CS_SHADER)
|
||||
{
|
||||
@ -449,21 +445,21 @@ namespace D3dDdi
|
||||
HRESULT DeviceState::pfnSetViewport(const D3DDDIARG_VIEWPORTINFO* data)
|
||||
{
|
||||
m_app.viewport = *data;
|
||||
m_changedStates |= CS_MISC;
|
||||
m_changedStates |= CS_RENDER_TARGET;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnSetZRange(const D3DDDIARG_ZRANGE* data)
|
||||
{
|
||||
m_app.zRange = *data;
|
||||
m_changedStates |= CS_MISC;
|
||||
m_changedStates |= CS_RENDER_TARGET;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DeviceState::pfnUpdateWInfo(const D3DDDIARG_WINFO* data)
|
||||
{
|
||||
m_app.wInfo = *data;
|
||||
m_changedStates |= CS_MISC;
|
||||
m_changedStates |= CS_RENDER_TARGET;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -528,11 +524,10 @@ namespace D3dDdi
|
||||
|
||||
void DeviceState::setRenderTarget(const D3DDDIARG_SETRENDERTARGET& renderTarget)
|
||||
{
|
||||
if (setData(renderTarget, m_current.renderTarget, m_device.getOrigVtable().pfnSetRenderTarget))
|
||||
{
|
||||
m_device.setRenderTarget(m_app.renderTarget);
|
||||
LOG_DS << renderTarget;
|
||||
}
|
||||
m_device.flushPrimitives();
|
||||
m_device.getOrigVtable().pfnSetRenderTarget(m_device, &renderTarget);
|
||||
m_current.renderTarget = renderTarget;
|
||||
LOG_DS << renderTarget;
|
||||
}
|
||||
|
||||
bool DeviceState::setShader(HANDLE shader, HANDLE& currentShader,
|
||||
@ -600,6 +595,7 @@ namespace D3dDdi
|
||||
void DeviceState::setTempRenderTarget(const D3DDDIARG_SETRENDERTARGET& renderTarget)
|
||||
{
|
||||
setRenderTarget(renderTarget);
|
||||
m_device.setRenderTarget({});
|
||||
m_changedStates |= CS_RENDER_TARGET;
|
||||
}
|
||||
|
||||
@ -644,6 +640,7 @@ namespace D3dDdi
|
||||
|
||||
void DeviceState::setTempVertexShaderDecl(HANDLE decl)
|
||||
{
|
||||
m_current.vertexShaderDecl = DELETED_RESOURCE;
|
||||
setVertexShaderDecl(decl);
|
||||
m_changedStates |= CS_SHADER;
|
||||
}
|
||||
@ -651,19 +648,19 @@ namespace D3dDdi
|
||||
void DeviceState::setTempViewport(const D3DDDIARG_VIEWPORTINFO& viewport)
|
||||
{
|
||||
setViewport(viewport);
|
||||
m_changedStates |= CS_MISC;
|
||||
m_changedStates |= CS_RENDER_TARGET;
|
||||
}
|
||||
|
||||
void DeviceState::setTempWInfo(const D3DDDIARG_WINFO& wInfo)
|
||||
{
|
||||
setWInfo(wInfo);
|
||||
m_changedStates |= CS_MISC;
|
||||
m_changedStates |= CS_RENDER_TARGET;
|
||||
}
|
||||
|
||||
void DeviceState::setTempZRange(const D3DDDIARG_ZRANGE& zRange)
|
||||
{
|
||||
setZRange(zRange);
|
||||
m_changedStates |= CS_MISC;
|
||||
m_changedStates |= CS_RENDER_TARGET;
|
||||
}
|
||||
|
||||
bool DeviceState::setTexture(UINT stage, HANDLE texture)
|
||||
@ -762,26 +759,6 @@ namespace D3dDdi
|
||||
m_changedTextureStageStates[i].set(D3DDDITSS_MAXANISOTROPY);
|
||||
}
|
||||
m_maxChangedTextureStage = m_changedTextureStageStates.size() - 1;
|
||||
updateVertexFixupConstants();
|
||||
}
|
||||
|
||||
void DeviceState::updateMisc()
|
||||
{
|
||||
bool updateConstants = setViewport(m_app.viewport);
|
||||
|
||||
auto wInfo = m_app.wInfo;
|
||||
if (1.0f == wInfo.WNear && 1.0f == wInfo.WFar)
|
||||
{
|
||||
wInfo.WNear = 0.0f;
|
||||
}
|
||||
setWInfo(wInfo);
|
||||
|
||||
updateConstants |= setZRange(m_app.zRange);
|
||||
|
||||
if (updateConstants)
|
||||
{
|
||||
updateVertexFixupConstants();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceState::updateRenderStates()
|
||||
@ -794,23 +771,42 @@ namespace D3dDdi
|
||||
m_changedRenderStates.reset();
|
||||
}
|
||||
|
||||
void DeviceState::updateRenderTargets()
|
||||
void DeviceState::updateRenderTarget()
|
||||
{
|
||||
auto vp = m_app.viewport;
|
||||
auto renderTarget = m_app.renderTarget;
|
||||
auto depthStencil = m_app.depthStencil;
|
||||
|
||||
Resource* resource = m_device.getResource(renderTarget.hRenderTarget);
|
||||
if (resource && resource->getCustomResource())
|
||||
{
|
||||
resource->scaleRect(reinterpret_cast<RECT&>(vp));
|
||||
renderTarget.hRenderTarget = *resource->getCustomResource();
|
||||
|
||||
resource = m_device.getResource(depthStencil.hZBuffer);
|
||||
if (resource && resource->getCustomResource())
|
||||
{
|
||||
depthStencil.hZBuffer = *resource->getCustomResource();
|
||||
}
|
||||
}
|
||||
setRenderTarget(renderTarget);
|
||||
|
||||
auto depthStencil = m_app.depthStencil;
|
||||
resource = m_device.getResource(depthStencil.hZBuffer);
|
||||
if (resource && resource->getCustomResource())
|
||||
{
|
||||
depthStencil.hZBuffer = *resource->getCustomResource();
|
||||
}
|
||||
setRenderTarget(renderTarget);
|
||||
m_current.vertexShaderFunc = DELETED_RESOURCE;
|
||||
m_changedStates |= CS_SHADER;
|
||||
m_device.setRenderTarget(m_app.renderTarget);
|
||||
setDepthStencil(depthStencil);
|
||||
setViewport(vp);
|
||||
|
||||
auto wInfo = m_app.wInfo;
|
||||
if (1.0f == wInfo.WNear && 1.0f == wInfo.WFar)
|
||||
{
|
||||
wInfo.WNear = 0.0f;
|
||||
}
|
||||
setWInfo(wInfo);
|
||||
|
||||
setZRange(m_app.zRange);
|
||||
|
||||
updateVertexFixupConstants();
|
||||
}
|
||||
|
||||
void DeviceState::updateShaders()
|
||||
@ -902,14 +898,19 @@ namespace D3dDdi
|
||||
data.Count = 2;
|
||||
|
||||
const float apc = Config::alternatePixelCenter.get();
|
||||
const auto& vp = m_current.viewport;
|
||||
const auto& vp = m_app.viewport;
|
||||
const auto& zr = m_current.zRange;
|
||||
const float sx = static_cast<float>(m_current.viewport.Width) / m_app.viewport.Width;
|
||||
const float sy = static_cast<float>(m_current.viewport.Height) / m_app.viewport.Height;
|
||||
|
||||
ShaderConstF registers[2] = {
|
||||
{ apc - vp.X - vp.Width / 2, apc - vp.Y - vp.Height / 2, -zr.MinZ, 0.0f },
|
||||
{ 0.5f + apc - 0.5f / sx - vp.X - vp.Width / 2, 0.5f + apc - 0.5f / sy - vp.Y - vp.Height / 2, -zr.MinZ, 0.0f },
|
||||
{ 2.0f / vp.Width, -2.0f / vp.Height, 1.0f / (zr.MaxZ - zr.MinZ), 1.0f }
|
||||
};
|
||||
|
||||
m_device.getOrigVtable().pfnSetVertexShaderConst(m_device, &data, registers);
|
||||
if (0 != memcmp(registers, &m_vertexShaderConst[data.Register], sizeof(registers)))
|
||||
{
|
||||
pfnSetVertexShaderConst(&data, registers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ namespace D3dDdi
|
||||
void setTempZRange(const D3DDDIARG_ZRANGE& zRange);
|
||||
|
||||
void flush();
|
||||
HANDLE getVertexFixupDecl() const { return m_vsVertexFixup.get(); }
|
||||
void onDestroyResource(HANDLE resource);
|
||||
void updateConfig();
|
||||
|
||||
@ -106,12 +107,11 @@ namespace D3dDdi
|
||||
|
||||
enum ChangedState
|
||||
{
|
||||
CS_MISC = 1 << 0,
|
||||
CS_RENDER_STATE = 1 << 1,
|
||||
CS_RENDER_TARGET = 1 << 2,
|
||||
CS_SHADER = 1 << 3,
|
||||
CS_STREAM_SOURCE = 1 << 4,
|
||||
CS_TEXTURE_STAGE = 1 << 5
|
||||
CS_RENDER_STATE = 1 << 0,
|
||||
CS_RENDER_TARGET = 1 << 1,
|
||||
CS_SHADER = 1 << 2,
|
||||
CS_STREAM_SOURCE = 1 << 3,
|
||||
CS_TEXTURE_STAGE = 1 << 4
|
||||
};
|
||||
|
||||
struct State
|
||||
@ -170,9 +170,8 @@ namespace D3dDdi
|
||||
void setWInfo(const D3DDDIARG_WINFO& wInfo);
|
||||
bool setZRange(const D3DDDIARG_ZRANGE& zRange);
|
||||
|
||||
void updateMisc();
|
||||
void updateRenderStates();
|
||||
void updateRenderTargets();
|
||||
void updateRenderTarget();
|
||||
void updateShaders();
|
||||
void updateStreamSource();
|
||||
void updateTextureColorKey(UINT stage);
|
||||
|
@ -87,3 +87,13 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_GETCAPS& data)
|
||||
<< data.pData
|
||||
<< data.DataSize;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const FORMATOP& data)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< data.Format
|
||||
<< Compat::hex(data.Operations)
|
||||
<< Compat::hex(data.FlipMsTypes)
|
||||
<< Compat::hex(data.BltMsTypes)
|
||||
<< data.PrivateFormatBitCount;
|
||||
}
|
||||
|
@ -10,3 +10,4 @@
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATEDEVICE& data);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_GETCAPS& data);
|
||||
std::ostream& operator<<(std::ostream& os, D3DDDICAPS_TYPE data);
|
||||
std::ostream& operator<<(std::ostream& os, const FORMATOP& data);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <type_traits>
|
||||
|
||||
#include <Common/Comparison.h>
|
||||
#include <Common/HResultException.h>
|
||||
#include <Common/Log.h>
|
||||
#include <Common/Time.h>
|
||||
@ -18,6 +19,7 @@
|
||||
#include <Gdi/Palette.h>
|
||||
#include <Gdi/VirtualScreen.h>
|
||||
#include <Gdi/Window.h>
|
||||
#include <Win32/DisplayMode.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -25,16 +27,12 @@ namespace
|
||||
|
||||
const UINT g_resourceTypeFlags = getResourceTypeFlags().Value;
|
||||
RECT g_presentationRect = {};
|
||||
RECT g_primaryRect = {};
|
||||
|
||||
D3DDDIFORMAT g_formatOverride = D3DDDIFMT_UNKNOWN;
|
||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> g_msaaOverride = {};
|
||||
|
||||
RECT calculatePresentationRect()
|
||||
RECT calculateScaledRect(const RECT& srcRect, const RECT& dstRect)
|
||||
{
|
||||
const RECT srcRect = DDraw::PrimarySurface::getMonitorRect();
|
||||
const RECT dstRect = DDraw::RealPrimarySurface::getMonitorRect();
|
||||
|
||||
const int srcWidth = srcRect.right - srcRect.left;
|
||||
const int srcHeight = srcRect.bottom - srcRect.top;
|
||||
const int dstWidth = dstRect.right - dstRect.left;
|
||||
@ -54,6 +52,11 @@ namespace
|
||||
return rect;
|
||||
}
|
||||
|
||||
RECT calculatePresentationRect()
|
||||
{
|
||||
return calculateScaledRect(DDraw::PrimarySurface::getMonitorRect(), DDraw::RealPrimarySurface::getMonitorRect());
|
||||
}
|
||||
|
||||
LONG divCeil(LONG n, LONG d)
|
||||
{
|
||||
return (n + d - 1) / d;
|
||||
@ -113,6 +116,7 @@ namespace D3dDdi
|
||||
, m_msaaResolvedSurface{}
|
||||
, m_formatConfig(D3DDDIFMT_UNKNOWN)
|
||||
, m_multiSampleConfig{ D3DDDIMULTISAMPLE_NONE, 0 }
|
||||
, m_scaledSize{}
|
||||
, m_isSurfaceRepoResource(SurfaceRepository::inCreateSurface())
|
||||
{
|
||||
if (m_origData.Flags.VertexBuffer &&
|
||||
@ -126,10 +130,10 @@ namespace D3dDdi
|
||||
{
|
||||
g_presentationRect = calculatePresentationRect();
|
||||
auto& si = m_origData.pSurfList[0];
|
||||
g_primaryRect = { 0, 0, static_cast<LONG>(si.Width), static_cast<LONG>(si.Height) };
|
||||
RECT primaryRect = { 0, 0, static_cast<LONG>(si.Width), static_cast<LONG>(si.Height) };
|
||||
|
||||
Gdi::Cursor::setMonitorClipRect(DDraw::PrimarySurface::getMonitorRect());
|
||||
if (!EqualRect(&g_presentationRect, &g_primaryRect))
|
||||
if (!EqualRect(&g_presentationRect, &primaryRect))
|
||||
{
|
||||
Gdi::Cursor::setEmulated(true);
|
||||
}
|
||||
@ -139,6 +143,7 @@ namespace D3dDdi
|
||||
fixResourceData();
|
||||
m_formatInfo = getFormatInfo(m_fixedData.Format);
|
||||
m_formatConfig = m_fixedData.Format;
|
||||
m_scaledSize = { static_cast<LONG>(m_fixedData.pSurfList[0].Width), static_cast<LONG>(m_fixedData.pSurfList[0].Height) };
|
||||
|
||||
HRESULT result = m_device.createPrivateResource(m_fixedData);
|
||||
if (FAILED(result))
|
||||
@ -243,15 +248,17 @@ namespace D3dDdi
|
||||
{
|
||||
LOG_FUNC("Resource::bltLock", data);
|
||||
|
||||
loadSysMemResource(data.SubResourceIndex);
|
||||
if (data.Flags.ReadOnly)
|
||||
{
|
||||
prepareForCpuRead(data.SubResourceIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
prepareForCpuWrite(data.SubResourceIndex);
|
||||
}
|
||||
|
||||
auto& lockData = m_lockData[data.SubResourceIndex];
|
||||
lockData.qpcLastForcedLock = Time::queryPerformanceCounter();
|
||||
if (!data.Flags.ReadOnly)
|
||||
{
|
||||
clearUpToDateFlags(data.SubResourceIndex);
|
||||
lockData.isSysMemUpToDate = true;
|
||||
}
|
||||
|
||||
unsigned char* ptr = static_cast<unsigned char*>(lockData.data);
|
||||
if (data.Flags.AreaValid)
|
||||
@ -292,25 +299,7 @@ namespace D3dDdi
|
||||
if (m_lockResource)
|
||||
{
|
||||
auto& lockData = m_lockData[data.SubResourceIndex];
|
||||
|
||||
if (lockData.isVidMemUpToDate)
|
||||
{
|
||||
m_device.getOrigVtable().pfnColorFill(m_device, &data);
|
||||
}
|
||||
|
||||
if (lockData.isMsaaUpToDate)
|
||||
{
|
||||
data.hResource = *m_msaaSurface.resource;
|
||||
m_device.getOrigVtable().pfnColorFill(m_device, &data);
|
||||
}
|
||||
|
||||
if (lockData.isMsaaResolvedUpToDate)
|
||||
{
|
||||
data.hResource = *m_msaaResolvedSurface.resource;
|
||||
m_device.getOrigVtable().pfnColorFill(m_device, &data);
|
||||
}
|
||||
|
||||
if (lockData.isSysMemUpToDate)
|
||||
if (lockData.isSysMemUpToDate && !lockData.isVidMemUpToDate)
|
||||
{
|
||||
auto dstBuf = static_cast<BYTE*>(lockData.data) +
|
||||
data.DstRect.top * lockData.pitch + data.DstRect.left * m_formatInfo.bytesPerPixel;
|
||||
@ -318,21 +307,25 @@ namespace D3dDdi
|
||||
DDraw::Blitter::colorFill(dstBuf, lockData.pitch,
|
||||
data.DstRect.right - data.DstRect.left, data.DstRect.bottom - data.DstRect.top,
|
||||
m_formatInfo.bytesPerPixel, colorConvert(m_formatInfo, data.Color));
|
||||
}
|
||||
|
||||
return LOG_RESULT(S_OK);
|
||||
return LOG_RESULT(S_OK);
|
||||
}
|
||||
}
|
||||
|
||||
prepareForBltDst(data.hResource, data.SubResourceIndex, data.DstRect);
|
||||
return LOG_RESULT(m_device.getOrigVtable().pfnColorFill(m_device, &data));
|
||||
}
|
||||
|
||||
HRESULT Resource::copySubResource(Resource& dstResource, Resource& srcResource, UINT subResourceIndex)
|
||||
{
|
||||
return copySubResourceRegion(dstResource, subResourceIndex, dstResource.getRect(subResourceIndex),
|
||||
srcResource, subResourceIndex, srcResource.getRect(subResourceIndex));
|
||||
}
|
||||
|
||||
HRESULT Resource::copySubResource(HANDLE dstResource, HANDLE srcResource, UINT subResourceIndex)
|
||||
{
|
||||
RECT rect = {};
|
||||
rect.right = m_fixedData.pSurfList[subResourceIndex].Width;
|
||||
rect.bottom = m_fixedData.pSurfList[subResourceIndex].Height;
|
||||
|
||||
return copySubResourceRegion(dstResource, subResourceIndex, rect, srcResource, subResourceIndex, rect);
|
||||
return copySubResourceRegion(dstResource, subResourceIndex, getRect(subResourceIndex),
|
||||
srcResource, subResourceIndex, getRect(subResourceIndex));
|
||||
}
|
||||
|
||||
HRESULT Resource::copySubResourceRegion(HANDLE dst, UINT dstIndex, const RECT& dstRect,
|
||||
@ -540,6 +533,24 @@ namespace D3dDdi
|
||||
return { D3DDDIMULTISAMPLE_NONE, 0 };
|
||||
}
|
||||
|
||||
RECT Resource::getRect(UINT subResourceIndex)
|
||||
{
|
||||
const auto& si = m_fixedData.pSurfList[subResourceIndex];
|
||||
return { 0, 0, static_cast<LONG>(si.Width), static_cast<LONG>(si.Height) };
|
||||
}
|
||||
|
||||
SIZE Resource::getScaledSize()
|
||||
{
|
||||
SIZE size = { static_cast<LONG>(m_fixedData.pSurfList[0].Width), static_cast<LONG>(m_fixedData.pSurfList[0].Height) };
|
||||
if ((m_fixedData.Flags.RenderTarget && !m_fixedData.Flags.Texture && !m_fixedData.Flags.Primary ||
|
||||
m_fixedData.Flags.ZBuffer) &&
|
||||
D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool)
|
||||
{
|
||||
return m_device.getAdapter().getScaledSize(size);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool Resource::isOversized() const
|
||||
{
|
||||
return m_fixedData.SurfCount != m_origData.SurfCount;
|
||||
@ -564,7 +575,7 @@ namespace D3dDdi
|
||||
else
|
||||
{
|
||||
loadVidMemResource(subResourceIndex);
|
||||
copySubResource(*m_msaaSurface.resource, m_handle, subResourceIndex);
|
||||
copySubResource(*m_msaaSurface.resource, *this, subResourceIndex);
|
||||
}
|
||||
m_lockData[subResourceIndex].isMsaaUpToDate = true;
|
||||
}
|
||||
@ -581,7 +592,7 @@ namespace D3dDdi
|
||||
else
|
||||
{
|
||||
loadVidMemResource(subResourceIndex);
|
||||
copySubResource(*m_msaaResolvedSurface.resource, m_handle, subResourceIndex);
|
||||
copySubResource(*m_msaaResolvedSurface.resource, *this, subResourceIndex);
|
||||
}
|
||||
m_lockData[subResourceIndex].isMsaaResolvedUpToDate = true;
|
||||
}
|
||||
@ -592,7 +603,7 @@ namespace D3dDdi
|
||||
if (!m_lockData[subResourceIndex].isSysMemUpToDate)
|
||||
{
|
||||
loadVidMemResource(subResourceIndex);
|
||||
copySubResource(m_lockResource.get(), m_handle, subResourceIndex);
|
||||
copySubResource(m_lockResource.get(), *this, subResourceIndex);
|
||||
notifyLock(subResourceIndex);
|
||||
m_lockData[subResourceIndex].isSysMemUpToDate = true;
|
||||
}
|
||||
@ -607,16 +618,16 @@ namespace D3dDdi
|
||||
if (m_msaaResolvedSurface.resource)
|
||||
{
|
||||
loadMsaaResolvedResource(subResourceIndex);
|
||||
copySubResource(m_handle, *m_msaaResolvedSurface.resource, subResourceIndex);
|
||||
copySubResource(*this, *m_msaaResolvedSurface.resource, subResourceIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
copySubResource(m_handle, *m_msaaSurface.resource, subResourceIndex);
|
||||
copySubResource(*this, *m_msaaSurface.resource, subResourceIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copySubResource(m_handle, m_lockResource.get(), subResourceIndex);
|
||||
copySubResource(*this, m_lockResource.get(), subResourceIndex);
|
||||
notifyLock(subResourceIndex);
|
||||
}
|
||||
m_lockData[subResourceIndex].isVidMemUpToDate = true;
|
||||
@ -686,28 +697,35 @@ namespace D3dDdi
|
||||
}
|
||||
|
||||
Resource& Resource::prepareForBltDst(D3DDDIARG_BLT& data)
|
||||
{
|
||||
return prepareForBltDst(data.hDstResource, data.DstSubResourceIndex, data.DstRect);
|
||||
}
|
||||
|
||||
Resource& Resource::prepareForBltDst(HANDLE& resource, UINT& subResourceIndex, RECT& rect)
|
||||
{
|
||||
if (m_lockResource)
|
||||
{
|
||||
if (m_lockData[data.DstSubResourceIndex].isMsaaUpToDate)
|
||||
if (m_lockData[subResourceIndex].isMsaaUpToDate)
|
||||
{
|
||||
data.hDstResource = *m_msaaSurface.resource;
|
||||
clearUpToDateFlags(data.DstSubResourceIndex);
|
||||
m_lockData[data.DstSubResourceIndex].isMsaaUpToDate = true;
|
||||
resource = *m_msaaSurface.resource;
|
||||
clearUpToDateFlags(subResourceIndex);
|
||||
m_lockData[subResourceIndex].isMsaaUpToDate = true;
|
||||
scaleRect(rect);
|
||||
return *m_msaaSurface.resource;
|
||||
}
|
||||
else if (m_lockData[data.DstSubResourceIndex].isMsaaResolvedUpToDate)
|
||||
else if (m_lockData[subResourceIndex].isMsaaResolvedUpToDate)
|
||||
{
|
||||
data.hDstResource = *m_msaaResolvedSurface.resource;
|
||||
clearUpToDateFlags(data.DstSubResourceIndex);
|
||||
m_lockData[data.DstSubResourceIndex].isMsaaResolvedUpToDate = true;
|
||||
resource = *m_msaaResolvedSurface.resource;
|
||||
clearUpToDateFlags(subResourceIndex);
|
||||
m_lockData[subResourceIndex].isMsaaResolvedUpToDate = true;
|
||||
scaleRect(rect);
|
||||
return *m_msaaResolvedSurface.resource;
|
||||
}
|
||||
else
|
||||
{
|
||||
loadVidMemResource(data.DstSubResourceIndex);
|
||||
clearUpToDateFlags(data.DstSubResourceIndex);
|
||||
m_lockData[data.DstSubResourceIndex].isVidMemUpToDate = true;
|
||||
loadVidMemResource(subResourceIndex);
|
||||
clearUpToDateFlags(subResourceIndex);
|
||||
m_lockData[subResourceIndex].isVidMemUpToDate = true;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
@ -782,7 +800,9 @@ namespace D3dDdi
|
||||
{
|
||||
srcResource->m_lockData[0].isVidMemUpToDate = false;
|
||||
}
|
||||
data.hSrcResource = srcResource->prepareForGpuRead(0);
|
||||
|
||||
srcResource = &srcResource->prepareForGpuRead(0);
|
||||
data.hSrcResource = *srcResource;
|
||||
}
|
||||
|
||||
const bool isPalettized = D3DDDIFMT_P8 == srcResource->m_origData.Format;
|
||||
@ -793,14 +813,18 @@ namespace D3dDdi
|
||||
const RECT monitorRect = DDraw::PrimarySurface::getMonitorRect();
|
||||
const bool isLayeredPresentNeeded = Gdi::Window::presentLayered(nullptr, monitorRect);
|
||||
|
||||
const LONG srcWidth = srcResource->m_fixedData.pSurfList[0].Width;
|
||||
const LONG srcHeight = srcResource->m_fixedData.pSurfList[0].Height;
|
||||
data.SrcRect = { 0, 0, srcWidth, srcHeight };
|
||||
|
||||
UINT presentationFilter = Config::displayFilter.get();
|
||||
UINT presentationFilterParam = Config::displayFilter.getParam();
|
||||
if (Config::Settings::DisplayFilter::BILINEAR == presentationFilter &&
|
||||
(g_presentationRect.right - g_presentationRect.left == g_primaryRect.right &&
|
||||
g_presentationRect.bottom - g_presentationRect.top == g_primaryRect.bottom) ||
|
||||
(g_presentationRect.right - g_presentationRect.left == srcWidth &&
|
||||
g_presentationRect.bottom - g_presentationRect.top == srcHeight) ||
|
||||
(0 == presentationFilterParam &&
|
||||
0 == (g_presentationRect.right - g_presentationRect.left) % g_primaryRect.right &&
|
||||
0 == (g_presentationRect.bottom - g_presentationRect.top) % g_primaryRect.bottom))
|
||||
0 == (g_presentationRect.right - g_presentationRect.left) % srcWidth &&
|
||||
0 == (g_presentationRect.bottom - g_presentationRect.top) % srcHeight))
|
||||
{
|
||||
presentationFilter = Config::Settings::DisplayFilter::POINT;
|
||||
}
|
||||
@ -808,8 +832,7 @@ namespace D3dDdi
|
||||
if (isPalettized || isCursorEmulated || isLayeredPresentNeeded ||
|
||||
Config::Settings::DisplayFilter::POINT != presentationFilter)
|
||||
{
|
||||
const auto& si = srcResource->m_fixedData.pSurfList[0];
|
||||
const auto& dst(SurfaceRepository::get(m_device.getAdapter()).getTempRenderTarget(si.Width, si.Height));
|
||||
const auto& dst(SurfaceRepository::get(m_device.getAdapter()).getTempRenderTarget(srcWidth, srcHeight));
|
||||
if (!dst.resource)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
@ -859,6 +882,17 @@ namespace D3dDdi
|
||||
return m_device.getOrigVtable().pfnBlt(m_device, &data);
|
||||
}
|
||||
|
||||
void Resource::scaleRect(RECT& rect)
|
||||
{
|
||||
const LONG origWidth = m_fixedData.pSurfList[0].Width;
|
||||
const LONG origHeight = m_fixedData.pSurfList[0].Height;
|
||||
|
||||
rect.left = rect.left * m_scaledSize.cx / origWidth;
|
||||
rect.top = rect.top * m_scaledSize.cy / origHeight;
|
||||
rect.right = rect.right * m_scaledSize.cx / origWidth;
|
||||
rect.bottom = rect.bottom * m_scaledSize.cy / origHeight;
|
||||
}
|
||||
|
||||
void Resource::setAsGdiResource(bool isGdiResource)
|
||||
{
|
||||
m_lockResource.reset();
|
||||
@ -1097,7 +1131,8 @@ namespace D3dDdi
|
||||
}
|
||||
}
|
||||
|
||||
if (m_fixedData.Flags.RenderTarget || data.Flags.SrcColorKey || data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown)
|
||||
if (D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool &&
|
||||
(m_fixedData.Flags.RenderTarget || data.Flags.SrcColorKey || data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown))
|
||||
{
|
||||
if (SUCCEEDED(shaderBlt(data, srcResource)))
|
||||
{
|
||||
@ -1163,12 +1198,14 @@ namespace D3dDdi
|
||||
|
||||
const auto msaa = getMultisampleConfig();
|
||||
const auto formatConfig = getFormatConfig();
|
||||
if (m_multiSampleConfig == msaa && m_formatConfig == formatConfig)
|
||||
const auto scaledSize = getScaledSize();
|
||||
if (m_multiSampleConfig == msaa && m_formatConfig == formatConfig && m_scaledSize == scaledSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_multiSampleConfig = msaa;
|
||||
m_formatConfig = formatConfig;
|
||||
m_scaledSize = scaledSize;
|
||||
|
||||
if (m_fixedData.Flags.RenderTarget &&
|
||||
(m_msaaSurface.resource || m_msaaResolvedSurface.resource))
|
||||
@ -1187,9 +1224,10 @@ namespace D3dDdi
|
||||
m_msaaSurface = {};
|
||||
m_msaaResolvedSurface = {};
|
||||
|
||||
if (D3DDDIMULTISAMPLE_NONE != msaa.first || m_fixedData.Format != formatConfig)
|
||||
if (D3DDDIMULTISAMPLE_NONE != msaa.first || m_fixedData.Format != formatConfig ||
|
||||
static_cast<LONG>(m_fixedData.pSurfList[0].Width) != m_scaledSize.cx ||
|
||||
static_cast<LONG>(m_fixedData.pSurfList[0].Height) != m_scaledSize.cy)
|
||||
{
|
||||
g_formatOverride = formatConfig;
|
||||
if (m_fixedData.Flags.ZBuffer)
|
||||
{
|
||||
DDPIXELFORMAT pf = {};
|
||||
@ -1198,10 +1236,12 @@ namespace D3dDdi
|
||||
pf.dwZBufferBitDepth = 16;
|
||||
pf.dwZBitMask = 0xFFFF;
|
||||
|
||||
g_formatOverride = formatConfig;
|
||||
g_msaaOverride = msaa;
|
||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaSurface,
|
||||
m_fixedData.surfaceData[0].Width, m_fixedData.surfaceData[0].Height, pf,
|
||||
scaledSize.cx, scaledSize.cy, pf,
|
||||
DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
||||
g_formatOverride = D3DDDIFMT_UNKNOWN;
|
||||
g_msaaOverride = {};
|
||||
}
|
||||
else
|
||||
@ -1210,18 +1250,15 @@ namespace D3dDdi
|
||||
{
|
||||
g_msaaOverride = msaa;
|
||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaSurface,
|
||||
m_fixedData.surfaceData[0].Width, m_fixedData.surfaceData[0].Height,
|
||||
DDraw::DirectDraw::getRgbPixelFormat(32),
|
||||
DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY);
|
||||
scaledSize.cx, scaledSize.cy, getPixelFormat(formatConfig),
|
||||
DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
||||
g_msaaOverride = {};
|
||||
}
|
||||
|
||||
SurfaceRepository::get(m_device.getAdapter()).getSurface(m_msaaResolvedSurface,
|
||||
m_fixedData.surfaceData[0].Width, m_fixedData.surfaceData[0].Height,
|
||||
DDraw::DirectDraw::getRgbPixelFormat(32),
|
||||
DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY);
|
||||
scaledSize.cx, scaledSize.cy, getPixelFormat(formatConfig),
|
||||
DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY, m_fixedData.SurfCount);
|
||||
}
|
||||
g_formatOverride = D3DDDIFMT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,10 +37,12 @@ namespace D3dDdi
|
||||
void onDestroyResource(HANDLE resource);
|
||||
Resource& prepareForBltSrc(const D3DDDIARG_BLT& data);
|
||||
Resource& prepareForBltDst(D3DDDIARG_BLT& data);
|
||||
Resource& prepareForBltDst(HANDLE& resource, UINT& subResourceIndex, RECT& rect);
|
||||
void prepareForCpuRead(UINT subResourceIndex);
|
||||
void prepareForCpuWrite(UINT subResourceIndex);
|
||||
Resource& prepareForGpuRead(UINT subResourceIndex);
|
||||
void prepareForGpuWrite(UINT subResourceIndex);
|
||||
void scaleRect(RECT& rect);
|
||||
void setAsGdiResource(bool isGdiResource);
|
||||
HRESULT unlock(const D3DDDIARG_UNLOCK& data);
|
||||
void updateConfig();
|
||||
@ -74,6 +76,7 @@ namespace D3dDdi
|
||||
HRESULT bltLock(D3DDDIARG_LOCK& data);
|
||||
void clearUpToDateFlags(UINT subResourceIndex);
|
||||
void clipRect(UINT subResourceIndex, RECT& rect);
|
||||
HRESULT copySubResource(Resource& dstResource, Resource& srcResource, UINT subResourceIndex);
|
||||
HRESULT copySubResource(HANDLE dstResource, HANDLE srcResource, UINT subResourceIndex);
|
||||
HRESULT copySubResourceRegion(HANDLE dst, UINT dstIndex, const RECT& dstRect,
|
||||
HANDLE src, UINT srcIndex, const RECT& srcRect);
|
||||
@ -83,6 +86,8 @@ namespace D3dDdi
|
||||
void fixResourceData();
|
||||
D3DDDIFORMAT getFormatConfig();
|
||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> getMultisampleConfig();
|
||||
RECT getRect(UINT subResourceIndex);
|
||||
SIZE getScaledSize();
|
||||
bool isOversized() const;
|
||||
bool isValidRect(UINT subResourceIndex, const RECT& rect);
|
||||
void loadMsaaResource(UINT subResourceIndex);
|
||||
@ -112,6 +117,7 @@ namespace D3dDdi
|
||||
SurfaceRepository::Surface m_msaaResolvedSurface;
|
||||
D3DDDIFORMAT m_formatConfig;
|
||||
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> m_multiSampleConfig;
|
||||
SIZE m_scaledSize;
|
||||
bool m_isSurfaceRepoResource;
|
||||
};
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ namespace D3dDdi
|
||||
}
|
||||
|
||||
const auto& srcSurface = srcResource.getFixedDesc().pSurfList[srcSubResourceIndex];
|
||||
const auto& dstSurface = dstResource.getFixedDesc().pSurfList[dstSubResourceIndex];
|
||||
|
||||
auto& state = m_device.getState();
|
||||
state.setTempRenderState({ D3DDDIRS_SCENECAPTURE, TRUE });
|
||||
@ -45,8 +46,7 @@ namespace D3dDdi
|
||||
state.setTempPixelShader(pixelShader);
|
||||
state.setTempRenderTarget({ 0, dstResource, dstSubResourceIndex });
|
||||
state.setTempDepthStencil({ nullptr });
|
||||
state.setTempViewport({ static_cast<DWORD>(dstRect.left), static_cast<DWORD>(dstRect.top),
|
||||
static_cast<DWORD>(dstRect.right - dstRect.left), static_cast<DWORD>(dstRect.bottom - dstRect.top) });
|
||||
state.setTempViewport({ 0, 0, dstSurface.Width, dstSurface.Height });
|
||||
state.setTempZRange({ 0, 1 });
|
||||
|
||||
state.setTempRenderState({ D3DDDIRS_ZENABLE, D3DZB_FALSE });
|
||||
|
@ -241,7 +241,7 @@ namespace D3dDdi
|
||||
|
||||
const SurfaceRepository::Surface& SurfaceRepository::getTempRenderTarget(DWORD width, DWORD height)
|
||||
{
|
||||
return getTempSurface(m_renderTarget, width, height, DDraw::DirectDraw::getRgbPixelFormat(32),
|
||||
return getTempSurface(m_renderTarget, width, height, getPixelFormat(D3DDDIFMT_A8R8G8B8),
|
||||
DDSCAPS_3DDEVICE | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY);
|
||||
}
|
||||
|
||||
|
@ -92,6 +92,7 @@ namespace DDraw
|
||||
}
|
||||
|
||||
data->restore();
|
||||
D3dDdi::Device::updateAllConfig();
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
|
@ -221,6 +221,7 @@
|
||||
<ClInclude Include="Config\Settings\DisplayFilter.h" />
|
||||
<ClInclude Include="Config\Settings\DisplayResolution.h" />
|
||||
<ClInclude Include="Config\Settings\RenderColorDepth.h" />
|
||||
<ClInclude Include="Config\Settings\ResolutionScale.h" />
|
||||
<ClInclude Include="Config\Settings\SupportedResolutions.h" />
|
||||
<ClInclude Include="Config\Settings\TextureFilter.h" />
|
||||
<ClInclude Include="Config\Settings\ThreadPriorityBoost.h" />
|
||||
@ -340,6 +341,7 @@
|
||||
<ClCompile Include="Config\Settings\CpuAffinity.cpp" />
|
||||
<ClCompile Include="Config\Settings\DisplayFilter.cpp" />
|
||||
<ClCompile Include="Config\Settings\DisplayResolution.cpp" />
|
||||
<ClCompile Include="Config\Settings\ResolutionScale.cpp" />
|
||||
<ClCompile Include="Config\Settings\SupportedResolutions.cpp" />
|
||||
<ClCompile Include="Config\Settings\TextureFilter.cpp" />
|
||||
<ClCompile Include="D3dDdi\Adapter.cpp" />
|
||||
|
@ -507,6 +507,9 @@
|
||||
<ClInclude Include="DDraw\Comparison.h">
|
||||
<Filter>Header Files\DDraw</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\Settings\ResolutionScale.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
@ -797,6 +800,9 @@
|
||||
<ClCompile Include="D3dDdi\Log\AdapterCallbacksLog.cpp">
|
||||
<Filter>Source Files\D3dDdi\Log</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Config\Settings\ResolutionScale.cpp">
|
||||
<Filter>Source Files\Config\Settings</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="DDrawCompat.rc">
|
||||
|
@ -54,17 +54,6 @@ namespace
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_ACTIVATEAPP:
|
||||
if (!wParam)
|
||||
{
|
||||
auto configWindow = Gdi::PresentationWindow::getConfigWindow();
|
||||
if (configWindow)
|
||||
{
|
||||
configWindow->setVisible(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DISPLAYCHANGE:
|
||||
{
|
||||
if (0 != wParam)
|
||||
@ -100,6 +89,18 @@ namespace
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_ACTIVATEAPP:
|
||||
if (!wParam)
|
||||
{
|
||||
auto configWindow = Gdi::PresentationWindow::getConfigWindow();
|
||||
if (configWindow)
|
||||
{
|
||||
configWindow->setVisible(false);
|
||||
}
|
||||
CALL_ORIG_FUNC(ClipCursor)(nullptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CTLCOLORSCROLLBAR:
|
||||
if (reinterpret_cast<HWND>(lParam) != hwnd &&
|
||||
isUser32ScrollBar(reinterpret_cast<HWND>(lParam)))
|
||||
|
@ -12,6 +12,7 @@ namespace Overlay
|
||||
addControl(Config::antialiasing);
|
||||
addControl(Config::displayFilter);
|
||||
addControl(Config::renderColorDepth);
|
||||
addControl(Config::resolutionScale);
|
||||
addControl(Config::textureFilter);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,24 @@
|
||||
#include <Overlay/ComboBoxControl.h>
|
||||
#include <Overlay/SettingControl.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::vector<std::string> getValueStrings(Config::Setting& setting)
|
||||
{
|
||||
auto values(setting.getDefaultValueStrings());
|
||||
const auto currentValue = setting.getValueStr();
|
||||
for (const auto& value : values)
|
||||
{
|
||||
if (Config::Parser::removeParam(value) == Config::Parser::removeParam(currentValue))
|
||||
{
|
||||
return values;
|
||||
}
|
||||
}
|
||||
values.push_back(currentValue);
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Overlay
|
||||
{
|
||||
SettingControl::SettingControl(Control& parent, const RECT& rect, Config::Setting& setting)
|
||||
@ -17,7 +35,7 @@ namespace Overlay
|
||||
rect.left + SETTING_LABEL_WIDTH + SETTING_CONTROL_WIDTH, rect.bottom - BORDER / 2 };
|
||||
m_valueControl.reset(new ComboBoxControl(*this, r));
|
||||
getValueComboBox().setValue(setting.getValueStr());
|
||||
getValueComboBox().setValues(setting.getDefaultValueStrings());
|
||||
getValueComboBox().setValues(getValueStrings(setting));
|
||||
onValueChanged();
|
||||
updateValuesParam();
|
||||
}
|
||||
@ -40,6 +58,7 @@ namespace Overlay
|
||||
|
||||
if (&Config::antialiasing == &m_setting ||
|
||||
&Config::renderColorDepth == &m_setting ||
|
||||
&Config::resolutionScale == &m_setting ||
|
||||
&Config::textureFilter == &m_setting)
|
||||
{
|
||||
D3dDdi::Device::updateAllConfig();
|
||||
|
@ -18,7 +18,7 @@ namespace Overlay
|
||||
class SettingControl : public Control
|
||||
{
|
||||
public:
|
||||
static const int PARAM_LABEL_WIDTH = 50;
|
||||
static const int PARAM_LABEL_WIDTH = 70;
|
||||
static const int PARAM_CONTROL_WIDTH = 151;
|
||||
static const int SETTING_LABEL_WIDTH = 120;
|
||||
static const int SETTING_CONTROL_WIDTH = 151;
|
||||
|
@ -205,10 +205,10 @@ namespace
|
||||
|
||||
g_emulatedDisplayMode.deviceName = getDeviceName(lpszDeviceName);
|
||||
g_emulatedDisplayMode.rect = getMonitorInfo(g_emulatedDisplayMode.deviceName).rcMonitor;
|
||||
g_emulatedDisplayMode.rect.right = g_emulatedDisplayMode.rect.left + lpDevMode->dmPelsWidth;
|
||||
g_emulatedDisplayMode.rect.bottom = g_emulatedDisplayMode.rect.top + lpDevMode->dmPelsHeight;
|
||||
g_emulatedDisplayMode.diff.cx = lpDevMode->dmPelsWidth - currDevMode.dmPelsWidth;
|
||||
g_emulatedDisplayMode.diff.cy = lpDevMode->dmPelsHeight - currDevMode.dmPelsHeight;
|
||||
g_emulatedDisplayMode.rect.right = g_emulatedDisplayMode.rect.left + emulatedResolution.cx;
|
||||
g_emulatedDisplayMode.rect.bottom = g_emulatedDisplayMode.rect.top + emulatedResolution.cy;
|
||||
g_emulatedDisplayMode.diff.cx = emulatedResolution.cx - currDevMode.dmPelsWidth;
|
||||
g_emulatedDisplayMode.diff.cy = emulatedResolution.cy - currDevMode.dmPelsHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user