mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
4598013310 | ||
|
f78a96a334 | ||
|
16b062d17d | ||
|
76dfc38645 | ||
|
f1ae0c7147 | ||
|
cc2cc7510d | ||
|
2e9f55a2f0 | ||
|
ae10673b3e | ||
|
c8c6bd0ce9 | ||
|
1c4445717a | ||
|
142b13e032 | ||
|
97249c9b47 |
@ -50,6 +50,7 @@
|
||||
#include <Config/Settings/ThreadPriorityBoost.h>
|
||||
#include <Config/Settings/VertexBufferMemoryType.h>
|
||||
#include <Config/Settings/VertexFixup.h>
|
||||
#include <Config/Settings/ViewportEdgeFix.h>
|
||||
#include <Config/Settings/VSync.h>
|
||||
#include <Config/Settings/WinVersionLie.h>
|
||||
|
||||
@ -107,6 +108,7 @@ namespace Config
|
||||
Settings::ThreadPriorityBoost threadPriorityBoost;
|
||||
Settings::VertexBufferMemoryType vertexBufferMemoryType;
|
||||
Settings::VertexFixup vertexFixup;
|
||||
Settings::ViewportEdgeFix viewportEdgeFix;
|
||||
Settings::VSync vSync;
|
||||
Settings::WinVersionLie winVersionLie;
|
||||
}
|
||||
|
@ -1,16 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <Config/BoolSetting.h>
|
||||
#include <Config/EnumSetting.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
class ForceD3D9On12 : public BoolSetting
|
||||
class ForceD3D9On12 : public EnumSetting
|
||||
{
|
||||
public:
|
||||
enum Values { FORCEOFF, OFF, ON };
|
||||
|
||||
ForceD3D9On12()
|
||||
: BoolSetting("ForceD3D9On12", "off")
|
||||
: EnumSetting("ForceD3D9On12", "off", { "forceoff", "off", "on" })
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -23,6 +23,9 @@ namespace Config
|
||||
LOCKCOUNT,
|
||||
LOCKRATE,
|
||||
LOCKTIME,
|
||||
VBLANKCOUNT,
|
||||
VBLANKRATE,
|
||||
VBLANKTIME,
|
||||
DDIUSAGE,
|
||||
GDIOBJECTS,
|
||||
DEBUG,
|
||||
@ -45,6 +48,9 @@ namespace Config
|
||||
"lockcount",
|
||||
"lockrate",
|
||||
"locktime",
|
||||
"vblankcount",
|
||||
"vblankrate",
|
||||
"vblanktime",
|
||||
"ddiusage",
|
||||
"gdiobjects",
|
||||
"debug"
|
||||
|
@ -8,13 +8,13 @@ namespace Config
|
||||
namespace Settings
|
||||
{
|
||||
VSync::VSync()
|
||||
: EnumSetting("VSync", "app", { "app", "off", "on" })
|
||||
: EnumSetting("VSync", "app", { "app", "off", "on", "wait"})
|
||||
{
|
||||
}
|
||||
|
||||
Setting::ParamInfo VSync::getParamInfo() const
|
||||
{
|
||||
if (ON == m_value)
|
||||
if (ON == m_value || WAIT == m_value)
|
||||
{
|
||||
return { "Interval", 1, 16, 1 };
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ namespace Config
|
||||
class VSync : public EnumSetting
|
||||
{
|
||||
public:
|
||||
enum Values { APP, OFF, ON };
|
||||
enum Values { APP, OFF, ON, WAIT };
|
||||
|
||||
VSync();
|
||||
|
||||
|
32
DDrawCompat/Config/Settings/ViewportEdgeFix.h
Normal file
32
DDrawCompat/Config/Settings/ViewportEdgeFix.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <Config/EnumSetting.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
class ViewportEdgeFix : public EnumSetting
|
||||
{
|
||||
public:
|
||||
enum Values { OFF, SCALE };
|
||||
|
||||
ViewportEdgeFix()
|
||||
: EnumSetting("ViewportEdgeFix", "off", { "off", "scale" })
|
||||
{
|
||||
}
|
||||
|
||||
virtual ParamInfo getParamInfo() const override
|
||||
{
|
||||
switch (m_value)
|
||||
{
|
||||
case SCALE:
|
||||
return { "Gap", 1, 100, 50 };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
extern Settings::ViewportEdgeFix viewportEdgeFix;
|
||||
}
|
@ -437,7 +437,7 @@ namespace D3dDdi
|
||||
pCreateData->Interface = origInterface;
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
DeviceFuncs::hookVtable(*pCreateData->pDeviceFuncs, m_driverVersion);
|
||||
DeviceFuncs::hookVtable(*pCreateData->pDeviceFuncs, std::min(m_runtimeVersion, m_driverVersion));
|
||||
Device::add(*this, pCreateData->hDevice);
|
||||
}
|
||||
return result;
|
||||
|
@ -586,33 +586,6 @@ namespace D3dDdi
|
||||
m_state.updateConfig();
|
||||
}
|
||||
|
||||
void Device::waitForIdle()
|
||||
{
|
||||
D3dDdi::ScopedCriticalSection lock;
|
||||
flushPrimitives();
|
||||
D3DDDIARG_ISSUEQUERY issueQuery = {};
|
||||
issueQuery.hQuery = m_eventQuery;
|
||||
issueQuery.Flags.End = 1;
|
||||
m_origVtable.pfnIssueQuery(m_device, &issueQuery);
|
||||
|
||||
if (m_origVtable.pfnFlush1)
|
||||
{
|
||||
m_origVtable.pfnFlush1(m_device, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_origVtable.pfnFlush(m_device);
|
||||
}
|
||||
|
||||
BOOL result = FALSE;
|
||||
D3DDDIARG_GETQUERYDATA getQueryData = {};
|
||||
getQueryData.hQuery = m_eventQuery;
|
||||
getQueryData.pData = &result;
|
||||
while (S_FALSE == m_origVtable.pfnGetQueryData(m_device, &getQueryData))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
std::map<HANDLE, Device> Device::s_devices;
|
||||
bool Device::s_isFlushEnabled = true;
|
||||
}
|
||||
|
@ -72,7 +72,6 @@ namespace D3dDdi
|
||||
void setDepthStencil(HANDLE resource);
|
||||
void setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data);
|
||||
void updateConfig();
|
||||
void waitForIdle();
|
||||
|
||||
static void add(Adapter& adapter, HANDLE device);
|
||||
static Device& get(HANDLE device) { return s_devices.find(device)->second; }
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <D3dDdi/ShaderAssembler.h>
|
||||
#include <Overlay/Steam.h>
|
||||
#include <Shaders/VertexFixup.h>
|
||||
#include <Config/Settings/ViewportEdgeFix.h>
|
||||
|
||||
#define LOG_DS LOG_DEBUG << "DeviceState::" << __func__ << ": "
|
||||
|
||||
@ -549,10 +550,18 @@ namespace D3dDdi
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT result = m_device.getOrigVtable().pfnCreateVertexShaderDecl(m_device, data, ve.data());
|
||||
HRESULT result = m_device.getOrigVtable().pfnCreateVertexShaderDecl(m_device, data, vertexElements);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
m_vertexShaderDecls[data->ShaderHandle] = decl;
|
||||
if (decl.isTransformed)
|
||||
{
|
||||
D3DDDIARG_CREATEVERTEXSHADERDECL d = *data;
|
||||
d.ShaderHandle = nullptr;
|
||||
m_device.getOrigVtable().pfnCreateVertexShaderDecl(m_device, &d, ve.data());
|
||||
decl.untransformedDecl = std::unique_ptr<void, ResourceDeleter>(
|
||||
d.ShaderHandle, ResourceDeleter(m_device, m_device.getOrigVtable().pfnDeleteVertexShaderDecl));
|
||||
}
|
||||
m_vertexShaderDecls.emplace(data->ShaderHandle, std::move(decl));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -893,7 +902,7 @@ namespace D3dDdi
|
||||
if (spriteMode != m_spriteMode)
|
||||
{
|
||||
m_spriteMode = spriteMode;
|
||||
m_changedStates |= CS_RENDER_STATE | CS_TEXTURE_STAGE;
|
||||
m_changedStates |= CS_RENDER_STATE | CS_RENDER_TARGET | CS_TEXTURE_STAGE;
|
||||
m_changedRenderStates.set(D3DDDIRS_MULTISAMPLEANTIALIAS);
|
||||
if (Config::Settings::SpriteTexCoord::ROUND == Config::spriteTexCoord.get())
|
||||
{
|
||||
@ -1236,15 +1245,17 @@ namespace D3dDdi
|
||||
void DeviceState::updateShaders()
|
||||
{
|
||||
setPixelShader(mapPixelShader(m_app.pixelShader));
|
||||
setVertexShaderDecl(m_app.vertexShaderDecl);
|
||||
|
||||
auto& vertexDecl = getVertexDecl();
|
||||
if (Config::Settings::VertexFixup::GPU == m_vertexFixupConfig &&
|
||||
getVertexDecl().isTransformed)
|
||||
vertexDecl.isTransformed)
|
||||
{
|
||||
setVertexShaderDecl(vertexDecl.untransformedDecl.get());
|
||||
setVertexShaderFunc(getVsVertexFixup());
|
||||
}
|
||||
else
|
||||
{
|
||||
setVertexShaderDecl(m_app.vertexShaderDecl);
|
||||
setVertexShaderFunc(m_app.vertexShaderFunc);
|
||||
}
|
||||
}
|
||||
@ -1343,17 +1354,21 @@ namespace D3dDdi
|
||||
const float apc = Config::alternatePixelCenter.get();
|
||||
const auto& zr = m_current.zRange;
|
||||
|
||||
const float viewportEdgeGap = m_spriteMode ? 0 : (Config::viewportEdgeFix.getParam() / 100.0f);
|
||||
const float w = width - viewportEdgeGap;
|
||||
const float h = height - viewportEdgeGap;
|
||||
|
||||
m_vertexFixupData.texCoordAdj[2] = stc;
|
||||
m_vertexFixupData.texCoordAdj[3] = stc;
|
||||
|
||||
if (Config::Settings::VertexFixup::GPU == m_vertexFixupConfig)
|
||||
{
|
||||
m_vertexFixupData.offset[0] = 0.5f + apc - 0.5f / sx - width / 2;
|
||||
m_vertexFixupData.offset[1] = 0.5f + apc - 0.5f / sy - height / 2;
|
||||
m_vertexFixupData.offset[0] = 0.5f + apc - 0.5f / sx - w / 2;
|
||||
m_vertexFixupData.offset[1] = 0.5f + apc - 0.5f / sy - h / 2;
|
||||
m_vertexFixupData.offset[2] = -zr.MinZ;
|
||||
|
||||
m_vertexFixupData.multiplier[0] = 2.0f / width;
|
||||
m_vertexFixupData.multiplier[1] = -2.0f / height;
|
||||
m_vertexFixupData.multiplier[0] = 2.0f / w;
|
||||
m_vertexFixupData.multiplier[1] = -2.0f / h;
|
||||
m_vertexFixupData.multiplier[2] = 1.0f / (zr.MaxZ - zr.MinZ);
|
||||
}
|
||||
else
|
||||
@ -1361,8 +1376,8 @@ namespace D3dDdi
|
||||
m_vertexFixupData.offset[0] = 0.5f + apc - 0.5f / sx;
|
||||
m_vertexFixupData.offset[1] = 0.5f + apc - 0.5f / sy;
|
||||
|
||||
m_vertexFixupData.multiplier[0] = sx;
|
||||
m_vertexFixupData.multiplier[1] = sy;
|
||||
m_vertexFixupData.multiplier[0] = sx * width / w;
|
||||
m_vertexFixupData.multiplier[1] = sy * height / h;
|
||||
}
|
||||
|
||||
m_changedStates |= CS_VERTEX_FIXUP;
|
||||
|
@ -103,6 +103,7 @@ namespace D3dDdi
|
||||
|
||||
struct VertexDecl
|
||||
{
|
||||
std::unique_ptr<void, ResourceDeleter> untransformedDecl;
|
||||
std::vector<D3DDDIVERTEXELEMENT> elements;
|
||||
std::array<UINT, 8> texCoordOffset;
|
||||
std::array<UINT, 8> texCoordType;
|
||||
|
@ -213,7 +213,7 @@ namespace D3dDdi
|
||||
bool DrawPrimitive::appendPrimitives(D3DPRIMITIVETYPE primitiveType, INT baseVertexIndex, UINT primitiveCount,
|
||||
const UINT16* indices, UINT minIndex, UINT maxIndex)
|
||||
{
|
||||
if (m_batched.primitiveCount + primitiveCount > D3DMAXNUMPRIMITIVES)
|
||||
if ((m_batched.primitiveCount + primitiveCount) * 3 > D3DMAXNUMVERTICES)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ namespace
|
||||
pOpenData->Interface = origInterface;
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
D3dDdi::AdapterFuncs::hookVtable(*pOpenData->pAdapterFuncs, pOpenData->DriverVersion);
|
||||
D3dDdi::AdapterFuncs::hookVtable(*pOpenData->pAdapterFuncs, std::min(pOpenData->Version, pOpenData->DriverVersion));
|
||||
D3dDdi::Adapter::add(*pOpenData);
|
||||
}
|
||||
return result;
|
||||
|
@ -19,8 +19,10 @@
|
||||
#include <DDraw/RealPrimarySurface.h>
|
||||
#include <DDraw/ScopedThreadLock.h>
|
||||
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||
#include <Gdi/GuiThread.h>
|
||||
#include <Gdi/Palette.h>
|
||||
#include <Gdi/Window.h>
|
||||
#include <Overlay/StatsWindow.h>
|
||||
#include <Win32/DisplayMode.h>
|
||||
#include <Win32/DpiAwareness.h>
|
||||
|
||||
@ -161,7 +163,7 @@ namespace
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return data.ScanLine;
|
||||
return data.InVerticalBlank ? 0 : data.ScanLine;
|
||||
}
|
||||
|
||||
void getVidPnSource(D3DKMT_HANDLE& adapter, UINT& vidPnSourceId)
|
||||
@ -210,7 +212,7 @@ namespace
|
||||
switch (pData->Type)
|
||||
{
|
||||
case KMTQAITYPE_UMDRIVERNAME:
|
||||
if (Config::forceD3D9On12.get() &&
|
||||
if (Config::Settings::ForceD3D9On12::ON == Config::forceD3D9On12.get() &&
|
||||
KMTUMDVERSION_DX9 == static_cast<D3DKMT_UMDFILENAMEINFO*>(pData->pPrivateDriverData)->Version)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
@ -237,7 +239,7 @@ namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!Config::forceD3D9On12.get() &&
|
||||
else if (Config::Settings::ForceD3D9On12::FORCEOFF == Config::forceD3D9On12.get() &&
|
||||
KMTQAITYPE_UMDRIVERNAME == pData->Type &&
|
||||
KMTUMDVERSION_DX9 == static_cast<D3DKMT_UMDFILENAMEINFO*>(pData->pPrivateDriverData)->Version)
|
||||
{
|
||||
@ -365,6 +367,13 @@ namespace
|
||||
}
|
||||
|
||||
WakeAllConditionVariable(&g_vsyncCounterCv);
|
||||
|
||||
auto statsWindow = Gdi::GuiThread::getStatsWindow();
|
||||
if (statsWindow)
|
||||
{
|
||||
statsWindow->m_vblank.add();
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1851,4 +1851,46 @@ namespace D3dDdi
|
||||
m_palettizedTexture->m_isPalettizedTextureUpToDate = true;
|
||||
m_paletteColorKeyIndex = paletteColorKeyIndex;
|
||||
}
|
||||
|
||||
void Resource::waitForIdle(UINT subResourceIndex)
|
||||
{
|
||||
m_device.flushPrimitives();
|
||||
Resource* srcResource = this;
|
||||
RECT rect = { 0, 0, 1, 1 };
|
||||
|
||||
if (m_lockResource)
|
||||
{
|
||||
if (m_lockData[subResourceIndex].isMsaaUpToDate ||
|
||||
m_lockData[subResourceIndex].isMsaaResolvedUpToDate)
|
||||
{
|
||||
if (!m_lockData[subResourceIndex].isMsaaResolvedUpToDate)
|
||||
{
|
||||
copySubResourceRegion(*m_msaaResolvedSurface.resource, subResourceIndex, rect,
|
||||
*m_msaaSurface.resource, subResourceIndex, rect);
|
||||
}
|
||||
srcResource = m_msaaResolvedSurface.resource;
|
||||
}
|
||||
else if (!m_lockData[subResourceIndex].isVidMemUpToDate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto& syncSurface = m_device.getRepo().getSyncSurface(srcResource->m_fixedData.Format);
|
||||
if (!syncSurface.resource)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
copySubResourceRegion(*syncSurface.resource, 0, rect, *srcResource, subResourceIndex, rect);
|
||||
|
||||
D3DDDIARG_LOCK lock = {};
|
||||
lock.hResource = *syncSurface.resource;
|
||||
lock.Flags.ReadOnly = 1;
|
||||
m_device.getOrigVtable().pfnLock(m_device, &lock);
|
||||
|
||||
D3DDDIARG_UNLOCK unlock = {};
|
||||
unlock.hResource = *syncSurface.resource;
|
||||
m_device.getOrigVtable().pfnUnlock(m_device, &unlock);
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ namespace D3dDdi
|
||||
HRESULT unlock(const D3DDDIARG_UNLOCK& data);
|
||||
void updateConfig();
|
||||
void updatePalettizedTexture(UINT stage);
|
||||
void waitForIdle(UINT subResourceIndex);
|
||||
|
||||
static void enableConfig(bool enable);
|
||||
static void setFormatOverride(D3DDDIFORMAT format);
|
||||
|
@ -333,6 +333,11 @@ namespace D3dDdi
|
||||
return surface;
|
||||
}
|
||||
|
||||
SurfaceRepository::Surface& SurfaceRepository::getSyncSurface(D3DDDIFORMAT format)
|
||||
{
|
||||
return getSurface(m_syncSurface[format], 16, 16, format, DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY);
|
||||
}
|
||||
|
||||
SurfaceRepository::Surface& SurfaceRepository::getTempSurface(Surface& surface, DWORD width, DWORD height,
|
||||
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount)
|
||||
{
|
||||
|
@ -49,6 +49,7 @@ namespace D3dDdi
|
||||
const Resource* currentSrcRt = nullptr, const Resource* currentDstRt = nullptr);
|
||||
Surface& getSurface(Surface& surface, DWORD width, DWORD height,
|
||||
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1, DWORD caps2 = 0);
|
||||
Surface& getSyncSurface(D3DDDIFORMAT format);
|
||||
Surface& getTempSysMemSurface(DWORD width, DWORD height);
|
||||
Surface& getTempSurface(Surface& surface, DWORD width, DWORD height,
|
||||
D3DDDIFORMAT format, DWORD caps, UINT surfaceCount = 1);
|
||||
@ -89,6 +90,7 @@ namespace D3dDdi
|
||||
std::array<Surface, 3> m_hqRenderTargets;
|
||||
std::map<D3DDDIFORMAT, Surface> m_textures;
|
||||
std::vector<Surface> m_releasedSurfaces;
|
||||
std::map<D3DDDIFORMAT, Surface> m_syncSurface;
|
||||
Surface m_sysMemSurface;
|
||||
Surface m_windowedBackBuffer;
|
||||
CompatPtr<IDirectDrawSurface7> m_windowedPrimary;
|
||||
|
@ -99,10 +99,13 @@ namespace
|
||||
|
||||
UINT getFlipInterval(DWORD flags)
|
||||
{
|
||||
auto vSync = Config::vSync.get();
|
||||
if (Config::Settings::VSync::APP != vSync)
|
||||
switch (Config::vSync.get())
|
||||
{
|
||||
return Config::Settings::VSync::OFF == vSync ? 0 : Config::vSync.getParam();
|
||||
case Config::Settings::VSync::OFF:
|
||||
case Config::Settings::VSync::WAIT:
|
||||
return 0;
|
||||
case Config::Settings::VSync::ON:
|
||||
return Config::vSync.getParam();
|
||||
}
|
||||
|
||||
if (flags & DDFLIP_NOVSYNC)
|
||||
@ -509,10 +512,9 @@ namespace DDraw
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
HRESULT RealPrimarySurface::flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags)
|
||||
void RealPrimarySurface::flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags)
|
||||
{
|
||||
const DWORD flipInterval = getFlipInterval(flags);
|
||||
PrimarySurface::waitForIdle();
|
||||
|
||||
Compat::ScopedCriticalSection lock(g_presentCs);
|
||||
scheduleUpdate();
|
||||
@ -527,8 +529,6 @@ namespace DDraw
|
||||
{
|
||||
g_lastFlipSurface = nullptr;
|
||||
}
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
int RealPrimarySurface::flush()
|
||||
@ -737,12 +737,17 @@ namespace DDraw
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isUpdateReady = g_isUpdateReady;
|
||||
auto qpcStart = Time::queryPerformanceCounter();
|
||||
auto vsyncCount = D3dDdi::KernelModeThunks::getVsyncCounter();
|
||||
while (static_cast<int>(vsyncCount - g_flipEndVsyncCount) < 0)
|
||||
{
|
||||
++vsyncCount;
|
||||
D3dDdi::KernelModeThunks::waitForVsyncCounter(vsyncCount);
|
||||
if (isUpdateReady)
|
||||
{
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
Compat::ScopedCriticalSection lock(g_presentCs);
|
||||
@ -767,10 +772,10 @@ namespace DDraw
|
||||
g_qpcPrevWaitEnd = qpcWaitEnd;
|
||||
|
||||
Compat::ScopedThreadPriority prio(THREAD_PRIORITY_TIME_CRITICAL);
|
||||
auto qpcStart = Time::queryPerformanceCounter();
|
||||
while (Time::qpcToMs(qpcWaitEnd - qpcNow) > 0)
|
||||
{
|
||||
Time::waitForNextTick();
|
||||
flush();
|
||||
qpcNow = Time::queryPerformanceCounter();
|
||||
}
|
||||
|
||||
@ -778,12 +783,5 @@ namespace DDraw
|
||||
{
|
||||
qpcNow = Time::queryPerformanceCounter();
|
||||
}
|
||||
|
||||
Compat::ScopedCriticalSection lock(g_presentCs);
|
||||
auto qpcEnd = Time::queryPerformanceCounter();
|
||||
if (g_isUpdatePending)
|
||||
{
|
||||
g_qpcUpdateStart += qpcEnd - qpcStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace DDraw
|
||||
{
|
||||
public:
|
||||
static HRESULT create(CompatRef<IDirectDraw> dd);
|
||||
static HRESULT flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags);
|
||||
static void flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags);
|
||||
static int flush();
|
||||
static HRESULT getGammaRamp(DDGAMMARAMP* rampData);
|
||||
static HWND getPresentationWindow();
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <D3dDdi/Device.h>
|
||||
#include <D3dDdi/KernelModeThunks.h>
|
||||
#include <D3dDdi/Resource.h>
|
||||
#include <D3dDdi/ScopedCriticalSection.h>
|
||||
#include <D3dDdi/SurfaceRepository.h>
|
||||
#include <DDraw/DirectDraw.h>
|
||||
#include <DDraw/DirectDrawSurface.h>
|
||||
@ -17,10 +18,10 @@
|
||||
namespace
|
||||
{
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_primarySurface;
|
||||
D3dDdi::Device* g_device = nullptr;
|
||||
HANDLE g_gdiDriverResource = nullptr;
|
||||
HANDLE g_gdiRuntimeResource = nullptr;
|
||||
HANDLE g_frontResource = nullptr;
|
||||
D3dDdi::Resource* g_frontResource = nullptr;
|
||||
UINT g_frontResourceIndex = 0;
|
||||
DWORD g_origCaps = 0;
|
||||
HWND g_deviceWindow = nullptr;
|
||||
HPALETTE g_palette = nullptr;
|
||||
@ -34,10 +35,10 @@ namespace DDraw
|
||||
{
|
||||
LOG_FUNC("PrimarySurface::~PrimarySurface");
|
||||
|
||||
g_device = nullptr;
|
||||
g_gdiRuntimeResource = nullptr;
|
||||
g_gdiDriverResource = nullptr;
|
||||
g_frontResource = nullptr;
|
||||
g_frontResourceIndex = 0;
|
||||
g_primarySurface = nullptr;
|
||||
g_origCaps = 0;
|
||||
g_deviceWindow = nullptr;
|
||||
@ -111,7 +112,6 @@ namespace DDraw
|
||||
ResizePalette(g_palette, 256);
|
||||
}
|
||||
|
||||
g_device = D3dDdi::Device::findDeviceByResource(DirectDrawSurface::getDriverResourceHandle(*surface));
|
||||
data->restore();
|
||||
D3dDdi::Device::updateAllConfig();
|
||||
return LOG_RESULT(DD_OK);
|
||||
@ -215,7 +215,7 @@ namespace DDraw
|
||||
|
||||
HANDLE PrimarySurface::getFrontResource()
|
||||
{
|
||||
return g_frontResource;
|
||||
return *g_frontResource;
|
||||
}
|
||||
|
||||
HANDLE PrimarySurface::getGdiResource()
|
||||
@ -260,7 +260,7 @@ namespace DDraw
|
||||
g_gdiRuntimeResource = DirectDrawSurface::getRuntimeResourceHandle(*g_primarySurface);
|
||||
|
||||
updateFrontResource();
|
||||
g_gdiDriverResource = g_frontResource;
|
||||
g_gdiDriverResource = *g_frontResource;
|
||||
D3dDdi::Device::setGdiResourceHandle(g_gdiDriverResource);
|
||||
|
||||
DDSCAPS2 caps = {};
|
||||
@ -324,7 +324,8 @@ namespace DDraw
|
||||
|
||||
void PrimarySurface::updateFrontResource()
|
||||
{
|
||||
g_frontResource = DirectDrawSurface::getDriverResourceHandle(*g_primarySurface);
|
||||
g_frontResource = D3dDdi::Device::findResource(DirectDrawSurface::getDriverResourceHandle(*g_primarySurface));
|
||||
g_frontResourceIndex = DirectDrawSurface::getSubResourceIndex(*g_primarySurface);
|
||||
}
|
||||
|
||||
void PrimarySurface::updatePalette()
|
||||
@ -360,10 +361,8 @@ namespace DDraw
|
||||
|
||||
void PrimarySurface::waitForIdle()
|
||||
{
|
||||
if (g_device)
|
||||
{
|
||||
g_device->waitForIdle();
|
||||
}
|
||||
D3dDdi::ScopedCriticalSection lock;
|
||||
g_frontResource->waitForIdle(g_frontResourceIndex);
|
||||
}
|
||||
|
||||
CompatWeakPtr<IDirectDrawPalette> PrimarySurface::s_palette;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <Common/CompatPtr.h>
|
||||
#include <Config/Settings/FpsLimiter.h>
|
||||
#include <Config/Settings/VSync.h>
|
||||
#include <D3dDdi/KernelModeThunks.h>
|
||||
#include <D3dDdi/ScopedCriticalSection.h>
|
||||
#include <DDraw/DirectDrawClipper.h>
|
||||
@ -177,18 +178,22 @@ namespace DDraw
|
||||
caps.dwCaps = DDSCAPS_BACKBUFFER;
|
||||
getOrigVtable(This).GetAttachedSurface(This, &caps, &surfaceTargetOverride.getRef());
|
||||
}
|
||||
HRESULT result = Blt(This, nullptr, surfaceTargetOverride.get(), nullptr, DDBLT_WAIT, nullptr);
|
||||
if (SUCCEEDED(result) && Config::Settings::FpsLimiter::FLIPEND == Config::fpsLimiter.get())
|
||||
{
|
||||
RealPrimarySurface::waitForFlipFpsLimit();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT result = SurfaceImpl::Flip(This, surfaceTargetOverride, DDFLIP_WAIT);
|
||||
if (FAILED(result))
|
||||
HRESULT result = SurfaceImpl::Blt(This, nullptr, surfaceTargetOverride.get(), nullptr, DDBLT_WAIT, nullptr);
|
||||
if (FAILED(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
dwFlags = DDFLIP_NOVSYNC;
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
HRESULT result = SurfaceImpl::Flip(This, surfaceTargetOverride, DDFLIP_WAIT);
|
||||
if (FAILED(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
auto statsWindow = Gdi::GuiThread::getStatsWindow();
|
||||
@ -198,13 +203,41 @@ namespace DDraw
|
||||
}
|
||||
|
||||
PrimarySurface::updateFrontResource();
|
||||
result = RealPrimarySurface::flip(surfaceTargetOverride, dwFlags);
|
||||
if (SUCCEEDED(result) && Config::Settings::FpsLimiter::FLIPEND == Config::fpsLimiter.get())
|
||||
RealPrimarySurface::flip(surfaceTargetOverride, dwFlags);
|
||||
|
||||
if (Config::Settings::VSync::WAIT == Config::vSync.get())
|
||||
{
|
||||
static UINT lastFlipEnd = 0;
|
||||
lastFlipEnd += Config::vSync.getParam();
|
||||
UINT vsyncCount = D3dDdi::KernelModeThunks::getVsyncCounter();
|
||||
if (static_cast<INT>(vsyncCount - lastFlipEnd) > 0)
|
||||
{
|
||||
lastFlipEnd = vsyncCount;
|
||||
}
|
||||
|
||||
RealPrimarySurface::setUpdateReady();
|
||||
if (0 != RealPrimarySurface::flush())
|
||||
{
|
||||
PrimarySurface::waitForIdle();
|
||||
}
|
||||
|
||||
while (static_cast<INT>(vsyncCount - lastFlipEnd) < 0)
|
||||
{
|
||||
++vsyncCount;
|
||||
D3dDdi::KernelModeThunks::waitForVsyncCounter(vsyncCount);
|
||||
RealPrimarySurface::flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PrimarySurface::waitForIdle();
|
||||
}
|
||||
|
||||
if (Config::Settings::FpsLimiter::FLIPEND == Config::fpsLimiter.get())
|
||||
{
|
||||
DDraw::RealPrimarySurface::waitForFlip(m_data->getDDS());
|
||||
RealPrimarySurface::waitForFlipFpsLimit();
|
||||
}
|
||||
return result;
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
|
@ -72,7 +72,7 @@
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntDir)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>dwmapi.lib;dxguid.lib;imm32.lib;msimg32.lib;oleacc.lib;uxtheme.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dwmapi.lib;dxguid.lib;imm32.lib;msimg32.lib;oleacc.lib;uxtheme.lib;version.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
@ -110,7 +110,7 @@
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(IntDir)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>dwmapi.lib;dxguid.lib;imm32.lib;msimg32.lib;oleacc.lib;uxtheme.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dwmapi.lib;dxguid.lib;imm32.lib;msimg32.lib;oleacc.lib;uxtheme.lib;version.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
@ -216,6 +216,7 @@
|
||||
<ClInclude Include="Config\Settings\ThreadPriorityBoost.h" />
|
||||
<ClInclude Include="Config\Settings\VertexBufferMemoryType.h" />
|
||||
<ClInclude Include="Config\Settings\VertexFixup.h" />
|
||||
<ClInclude Include="Config\Settings\ViewportEdgeFix.h" />
|
||||
<ClInclude Include="Config\Settings\VSync.h" />
|
||||
<ClInclude Include="Config\Settings\WinVersionLie.h" />
|
||||
<ClInclude Include="D3dDdi\Adapter.h" />
|
||||
|
@ -723,6 +723,9 @@
|
||||
<ClInclude Include="Config\Settings\GdiStretchBltMode.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\Settings\ViewportEdgeFix.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
|
@ -215,7 +215,7 @@ namespace Gdi
|
||||
|
||||
POINT pos = {};
|
||||
CALL_ORIG_FUNC(GetCursorPos)(&pos);
|
||||
CALL_ORIG_FUNC(SetCursorPos)(pos.x, pos.y);
|
||||
SetCursorPos(pos.x, pos.y);
|
||||
}
|
||||
|
||||
void setMonitorClipRect(const RECT& rect)
|
||||
|
@ -23,6 +23,8 @@ namespace
|
||||
case SPI_SETFONTSMOOTHING:
|
||||
g_isFontSmoothingEnabled = 0 != uiParam;
|
||||
return TRUE;
|
||||
case SPI_SETSHOWIMEUI:
|
||||
return TRUE;
|
||||
}
|
||||
return LOG_RESULT(origSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni));
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <Overlay/Steam.h>
|
||||
#include <Overlay/Window.h>
|
||||
#include <Win32/DisplayMode.h>
|
||||
#include <Win32/DpiAwareness.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -29,7 +30,6 @@ namespace
|
||||
HOOKPROC origHookProc;
|
||||
LPARAM origHookStruct;
|
||||
MSLLHOOKSTRUCT hookStruct;
|
||||
DWORD dpiScale;
|
||||
};
|
||||
|
||||
struct HotKeyData
|
||||
@ -43,7 +43,6 @@ namespace
|
||||
SIZE g_bmpArrowSize = {};
|
||||
Overlay::Control* g_capture = nullptr;
|
||||
POINT g_cursorPos = {};
|
||||
POINT g_origCursorPos = { MAXLONG, MAXLONG };
|
||||
HWND g_cursorWindow = nullptr;
|
||||
std::map<Input::HotKey, HotKeyData> g_hotKeys;
|
||||
RECT g_monitorRect = {};
|
||||
@ -56,7 +55,7 @@ namespace
|
||||
|
||||
LRESULT CALLBACK lowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT CALLBACK lowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
POINT physicalToLogicalPoint(POINT pt, DWORD dpiScale);
|
||||
POINT physicalToLogicalPoint(POINT pt);
|
||||
|
||||
LRESULT CALLBACK cursorWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
@ -106,7 +105,22 @@ namespace
|
||||
|
||||
if (WM_MOUSEMOVE == wParam)
|
||||
{
|
||||
data.hookStruct.pt = physicalToLogicalPoint(data.hookStruct.pt, data.dpiScale);
|
||||
if (Win32::DpiAwareness::isMixedModeSupported())
|
||||
{
|
||||
POINT logicalCursorPos = {};
|
||||
GetCursorPos(&logicalCursorPos);
|
||||
|
||||
Win32::ScopedDpiAwareness dpiAwareness;
|
||||
POINT physicalCursorPos = {};
|
||||
GetCursorPos(&physicalCursorPos);
|
||||
|
||||
data.hookStruct.pt.x = logicalCursorPos.x + data.hookStruct.pt.x - physicalCursorPos.x;
|
||||
data.hookStruct.pt.y = logicalCursorPos.y + data.hookStruct.pt.y - physicalCursorPos.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.hookStruct.pt = physicalToLogicalPoint(data.hookStruct.pt);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -118,13 +132,6 @@ namespace
|
||||
return g_dinputMouseHookData.origHookProc(nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
DWORD getDpiScaleForCursorPos()
|
||||
{
|
||||
POINT cp = {};
|
||||
CALL_ORIG_FUNC(GetCursorPos)(&cp);
|
||||
return Win32::DisplayMode::getMonitorInfo(cp).dpiScale;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK lowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (HC_ACTION == nCode &&
|
||||
@ -178,25 +185,23 @@ namespace
|
||||
|
||||
if (WM_MOUSEMOVE == wParam)
|
||||
{
|
||||
if (MAXLONG == g_origCursorPos.y)
|
||||
POINT origCursorPos = {};
|
||||
POINT newCursorPos = llHook.pt;
|
||||
if (Win32::DpiAwareness::isMixedModeSupported())
|
||||
{
|
||||
if (llHook.flags & LLMHF_INJECTED)
|
||||
{
|
||||
if (MAXLONG == g_origCursorPos.x)
|
||||
{
|
||||
g_origCursorPos.x = llHook.pt.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_origCursorPos.y = llHook.pt.y;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
Win32::ScopedDpiAwareness dpiAwareness;
|
||||
CALL_ORIG_FUNC(GetCursorPos)(&origCursorPos);
|
||||
llHook.pt = {};
|
||||
}
|
||||
else
|
||||
{
|
||||
CALL_ORIG_FUNC(GetCursorPos)(&origCursorPos);
|
||||
newCursorPos = physicalToLogicalPoint(llHook.pt);
|
||||
}
|
||||
|
||||
POINT cp = g_cursorPos;
|
||||
cp.x += llHook.pt.x - g_origCursorPos.x;
|
||||
cp.y += llHook.pt.y - g_origCursorPos.y;
|
||||
cp.x += newCursorPos.x - origCursorPos.x;
|
||||
cp.y += newCursorPos.y - origCursorPos.y;
|
||||
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;
|
||||
@ -240,13 +245,14 @@ namespace
|
||||
TerminateProcess(GetCurrentProcess(), 0);
|
||||
}
|
||||
|
||||
POINT physicalToLogicalPoint(POINT pt, DWORD dpiScale)
|
||||
POINT physicalToLogicalPoint(POINT pt)
|
||||
{
|
||||
if (g_physicalToLogicalPointForPerMonitorDPI)
|
||||
{
|
||||
g_physicalToLogicalPointForPerMonitorDPI(nullptr, &pt);
|
||||
return pt;
|
||||
}
|
||||
auto dpiScale = Win32::DisplayMode::getMonitorInfo(pt).dpiScale;
|
||||
return { MulDiv(pt.x, 100, dpiScale), MulDiv(pt.y, 100, dpiScale) };
|
||||
}
|
||||
|
||||
@ -287,46 +293,28 @@ namespace
|
||||
});
|
||||
}
|
||||
|
||||
void resetMouseHookFunc()
|
||||
{
|
||||
if (g_mouseHook)
|
||||
{
|
||||
UnhookWindowsHookEx(g_mouseHook);
|
||||
}
|
||||
|
||||
g_origCursorPos = { MAXLONG, MAXLONG };
|
||||
g_mouseHook = CALL_ORIG_FUNC(SetWindowsHookExA)(
|
||||
WH_MOUSE_LL, &lowLevelMouseProc, Dll::g_origDDrawModule, 0);
|
||||
|
||||
if (g_mouseHook)
|
||||
{
|
||||
INPUT inputs[2] = {};
|
||||
inputs[0].mi.dy = 1;
|
||||
inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE;
|
||||
inputs[1].mi.dx = 1;
|
||||
inputs[1].mi.dwFlags = MOUSEEVENTF_MOVE;
|
||||
SendInput(2, inputs, sizeof(INPUT));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ONCE("ERROR: Failed to install low level mouse hook, error code: " << GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
void resetMouseHook()
|
||||
{
|
||||
Gdi::GuiThread::executeAsyncFunc(resetMouseHookFunc);
|
||||
}
|
||||
Gdi::GuiThread::execute([]()
|
||||
{
|
||||
if (!g_capture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL WINAPI setCursorPos(int X, int Y)
|
||||
{
|
||||
LOG_FUNC("SetCursorPos", X, Y);
|
||||
auto result = CALL_ORIG_FUNC(SetCursorPos)(X, Y);
|
||||
if (result && g_mouseHook)
|
||||
{
|
||||
resetMouseHook();
|
||||
}
|
||||
return LOG_RESULT(result);
|
||||
if (g_mouseHook)
|
||||
{
|
||||
UnhookWindowsHookEx(g_mouseHook);
|
||||
}
|
||||
|
||||
g_mouseHook = CALL_ORIG_FUNC(SetWindowsHookExA)(
|
||||
WH_MOUSE_LL, &lowLevelMouseProc, Dll::g_origDDrawModule, 0);
|
||||
|
||||
if (!g_mouseHook)
|
||||
{
|
||||
LOG_ONCE("ERROR: Failed to install low level mouse hook, error code: " << GetLastError());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
HHOOK setWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId,
|
||||
@ -345,11 +333,6 @@ namespace
|
||||
(0 == _stricmp(moduleName.c_str(), "dinput") || 0 == _stricmp(moduleName.c_str(), "dinput8")))
|
||||
{
|
||||
g_dinputMouseHookData.origHookProc = lpfn;
|
||||
if (!g_physicalToLogicalPointForPerMonitorDPI)
|
||||
{
|
||||
g_dinputMouseHookData.dpiScale = getDpiScaleForCursorPos();
|
||||
}
|
||||
|
||||
lpfn = dinputLowLevelMouseProc;
|
||||
Compat::hookIatFunction(hmod, "CallNextHookEx", dinputCallNextHookEx);
|
||||
}
|
||||
@ -441,7 +424,6 @@ namespace Input
|
||||
GetProcAddress(GetModuleHandle("user32"), "PhysicalToLogicalPointForPerMonitorDPI"));
|
||||
|
||||
HOOK_FUNCTION(user32, RegisterRawInputDevices, registerRawInputDevices);
|
||||
HOOK_FUNCTION(user32, SetCursorPos, setCursorPos);
|
||||
HOOK_FUNCTION(user32, SetWindowsHookExA, setWindowsHookExA);
|
||||
HOOK_FUNCTION(user32, SetWindowsHookExW, setWindowsHookExW);
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <Config/Settings/StatsTransparency.h>
|
||||
#include <Config/Settings/TextureFilter.h>
|
||||
#include <Config/Settings/VertexFixup.h>
|
||||
#include <Config/Settings/ViewportEdgeFix.h>
|
||||
#include <Config/Settings/VSync.h>
|
||||
#include <D3dDdi/Device.h>
|
||||
#include <Gdi/Gdi.h>
|
||||
@ -71,6 +72,7 @@ namespace
|
||||
{ &Config::statsTransparency, [&]() { Gdi::GuiThread::getStatsWindow()->setAlpha(Config::statsTransparency.get()); }},
|
||||
{ &Config::textureFilter, &D3dDdi::Device::updateAllConfig },
|
||||
{ &Config::vertexFixup, &D3dDdi::Device::updateAllConfig },
|
||||
{ &Config::viewportEdgeFix },
|
||||
{ &Config::vSync }
|
||||
};
|
||||
}
|
||||
|
@ -110,6 +110,9 @@ namespace Overlay
|
||||
m_statsRows.push_back({ "Lock count", UpdateStats(m_lock.m_count), &m_lock.m_count });
|
||||
m_statsRows.push_back({ "Lock rate", UpdateStats(m_lock.m_rate), &m_lock.m_rate });
|
||||
m_statsRows.push_back({ "Lock time", UpdateStats(m_lock.m_time), &m_lock.m_time });
|
||||
m_statsRows.push_back({ "VBlank count", UpdateStats(m_vblank.m_count), &m_vblank.m_count });
|
||||
m_statsRows.push_back({ "VBlank rate", UpdateStats(m_vblank.m_rate), &m_vblank.m_rate });
|
||||
m_statsRows.push_back({ "VBlank time", UpdateStats(m_vblank.m_time), &m_vblank.m_time });
|
||||
m_statsRows.push_back({ "DDI usage", UpdateStats(m_ddiUsage), &m_ddiUsage });
|
||||
m_statsRows.push_back({ "GDI objects", UpdateStats(m_gdiObjects), &m_gdiObjects });
|
||||
m_statsRows.push_back({ "", &getDebugInfo, nullptr, WS_VISIBLE | WS_GROUP });
|
||||
@ -135,6 +138,7 @@ namespace Overlay
|
||||
m_flip.enable();
|
||||
m_blit.enable();
|
||||
m_lock.enable();
|
||||
m_vblank.enable();
|
||||
}
|
||||
|
||||
StatsControl& StatsWindow::addControl(const std::string& name, StatsControl::UpdateFunc updateFunc, DWORD style)
|
||||
|
@ -28,6 +28,7 @@ namespace Overlay
|
||||
StatsEventGroup m_flip;
|
||||
StatsEventGroup m_blit;
|
||||
StatsEventGroup m_lock;
|
||||
StatsEventGroup m_vblank;
|
||||
StatsTimer m_ddiUsage;
|
||||
StatsQueue m_gdiObjects;
|
||||
|
||||
|
@ -318,7 +318,7 @@ namespace
|
||||
LSTATUS WINAPI regEnumValueW(HKEY hKey, DWORD dwIndex, LPWSTR lpValueName, LPDWORD lpcchValueName,
|
||||
LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
|
||||
{
|
||||
LOG_FUNC("RegEnumValueW", hKey, dwIndex, lpValueName, lpcchValueName, lpReserved, lpType, lpData, lpcbData);
|
||||
LOG_FUNC("RegEnumValueW", hKey, dwIndex, Compat::out(lpValueName), lpcchValueName, lpReserved, lpType, lpData, lpcbData);
|
||||
if (lpValueName && lpcchValueName && !lpReserved && !lpType && !lpData && !lpcbData)
|
||||
{
|
||||
auto keyName(getKeyName(hKey));
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
#include <Common/Hook.h>
|
||||
#include <Common/Log.h>
|
||||
#include <Common/Path.h>
|
||||
#include <Config/Settings/WinVersionLie.h>
|
||||
#include <Dll/Dll.h>
|
||||
|
||||
#include <Win32/Version.h>
|
||||
|
||||
@ -10,6 +12,55 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
DWORD getModuleFileName(HMODULE mod, char* filename, DWORD size)
|
||||
{
|
||||
return GetModuleFileNameA(mod, filename, size);
|
||||
}
|
||||
|
||||
DWORD getModuleFileName(HMODULE mod, wchar_t* filename, DWORD size)
|
||||
{
|
||||
return GetModuleFileNameW(mod, filename, size);
|
||||
}
|
||||
|
||||
HMODULE getModuleHandle(const char* moduleName)
|
||||
{
|
||||
return GetModuleHandleA(moduleName);
|
||||
}
|
||||
|
||||
HMODULE getModuleHandle(const wchar_t* moduleName)
|
||||
{
|
||||
return GetModuleHandleW(moduleName);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void fixVersionInfoFileName(const Char*& filename)
|
||||
{
|
||||
if (getModuleHandle(filename) == Dll::g_currentModule)
|
||||
{
|
||||
static Char path[MAX_PATH];
|
||||
if (0 != getModuleFileName(Dll::g_origDDrawModule, path, MAX_PATH))
|
||||
{
|
||||
filename = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <auto func, typename Result, typename Char, typename... Params>
|
||||
Result WINAPI getFileVersionInfoFunc(const Char* filename ,Params... params)
|
||||
{
|
||||
LOG_FUNC(Compat::g_origFuncName<func>.c_str(), filename, params...);
|
||||
fixVersionInfoFileName(filename);
|
||||
return LOG_RESULT(CALL_ORIG_FUNC(func)(filename, params...));
|
||||
}
|
||||
|
||||
template <auto func, typename Result, typename Char, typename... Params>
|
||||
Result WINAPI getFileVersionInfoFunc(DWORD flags, const Char* filename, Params... params)
|
||||
{
|
||||
LOG_FUNC(Compat::g_origFuncName<func>.c_str(), filename, params...);
|
||||
fixVersionInfoFileName(filename);
|
||||
return LOG_RESULT(CALL_ORIG_FUNC(func)(flags, filename, params...));
|
||||
}
|
||||
|
||||
DWORD WINAPI getVersion()
|
||||
{
|
||||
LOG_FUNC("GetVersion");
|
||||
@ -64,14 +115,53 @@ namespace
|
||||
{
|
||||
return getVersionInfo<OSVERSIONINFOEXW>(lpVersionInformation, CALL_ORIG_FUNC(GetVersionExW), "GetVersionExW");
|
||||
}
|
||||
|
||||
template <auto origFunc>
|
||||
bool hookVersionInfoFunc(const char* moduleName, const char* funcName)
|
||||
{
|
||||
HMODULE mod = GetModuleHandle(moduleName);
|
||||
if (mod)
|
||||
{
|
||||
FARPROC func = Compat::getProcAddress(mod, funcName);
|
||||
if (func)
|
||||
{
|
||||
Compat::hookFunction<origFunc>(moduleName, funcName, getFileVersionInfoFunc<origFunc>);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <auto origFunc>
|
||||
void hookVersionInfoFunc(const char* funcName)
|
||||
{
|
||||
hookVersionInfoFunc<origFunc>("kernelbase", funcName) || hookVersionInfoFunc<origFunc>("version", funcName);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Compat
|
||||
{
|
||||
template<> decltype(&GetFileVersionInfoExA) g_origFuncPtr<GetFileVersionInfoExA> = nullptr;
|
||||
template<> decltype(&GetFileVersionInfoSizeExA) g_origFuncPtr<GetFileVersionInfoSizeExA> = nullptr;
|
||||
}
|
||||
|
||||
#define HOOK_VERSION_INFO_FUNCTION(func) hookVersionInfoFunc<func>(#func)
|
||||
|
||||
namespace Win32
|
||||
{
|
||||
namespace Version
|
||||
{
|
||||
void installHooks()
|
||||
{
|
||||
HOOK_VERSION_INFO_FUNCTION(GetFileVersionInfoA);
|
||||
HOOK_VERSION_INFO_FUNCTION(GetFileVersionInfoW);
|
||||
HOOK_VERSION_INFO_FUNCTION(GetFileVersionInfoExA);
|
||||
HOOK_VERSION_INFO_FUNCTION(GetFileVersionInfoExW);
|
||||
HOOK_VERSION_INFO_FUNCTION(GetFileVersionInfoSizeA);
|
||||
HOOK_VERSION_INFO_FUNCTION(GetFileVersionInfoSizeW);
|
||||
HOOK_VERSION_INFO_FUNCTION(GetFileVersionInfoSizeExA);
|
||||
HOOK_VERSION_INFO_FUNCTION(GetFileVersionInfoSizeExW);
|
||||
|
||||
HOOK_FUNCTION(kernel32, GetVersion, getVersion);
|
||||
HOOK_FUNCTION(kernel32, GetVersionExA, getVersionExA);
|
||||
HOOK_FUNCTION(kernel32, GetVersionExW, getVersionExW);
|
||||
|
@ -22,10 +22,11 @@
|
||||
# ForceD3D9On12 = off
|
||||
# FpsLimiter = off
|
||||
# FullscreenMode = borderless
|
||||
# GdiStretchBltMode = app
|
||||
# LogLevel = info
|
||||
# PalettizedTextures = off
|
||||
# RemoveBorders = off
|
||||
# RenderColorDepth = appd8
|
||||
# RenderColorDepth = 32
|
||||
# ResolutionScale = app(1)
|
||||
# ResolutionScaleFilter = point
|
||||
# SoftwareDevice = rgb
|
||||
@ -37,15 +38,18 @@
|
||||
# StatsHotKey = shift+f12
|
||||
# StatsPosX = right
|
||||
# StatsPosY = top
|
||||
# StatsRows = label, presentrate, fliprate, blitcount, lockcount, ddiusage
|
||||
# StatsRows = label, presentrate, fliprate, blitcount, lockcount
|
||||
# StatsTransparency = alpha(75)
|
||||
# StatsUpdateRate = 5
|
||||
# SupportedDepthFormats = all
|
||||
# SupportedResolutions = native, 640x480, 800x600, 1024x768
|
||||
# SupportedTextureFormats = all
|
||||
# SurfacePatches = none
|
||||
# TerminateHotKey = ctrl+alt+end
|
||||
# TextureFilter = app
|
||||
# ThreadPriorityBoost = off
|
||||
# VSync = app
|
||||
# VertexBufferMemoryType = sysmem
|
||||
# VertexFixup = gpu
|
||||
# ViewportEdgeFix = off
|
||||
# WinVersionLie = off
|
||||
|
Loading…
x
Reference in New Issue
Block a user