1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Added FpsLimiter setting

This commit is contained in:
narzoul 2022-06-19 22:59:05 +02:00
parent bf58555d22
commit 8fc97386b6
16 changed files with 264 additions and 11 deletions

View File

@ -0,0 +1,24 @@
#pragma once
#include <Windows.h>
namespace Compat
{
class ScopedThreadPriority
{
public:
ScopedThreadPriority(int priority)
: m_prevPriority(GetThreadPriority(GetCurrentThread()))
{
SetThreadPriority(GetCurrentThread(), priority);
}
~ScopedThreadPriority()
{
SetThreadPriority(GetCurrentThread(), m_prevPriority);
}
private:
int m_prevPriority;
};
}

View File

@ -5,24 +5,23 @@
namespace Time namespace Time
{ {
long long g_qpcFrequency = 0; long long g_qpcFrequency = 0;
HANDLE g_waitableTimer = nullptr;
void init() void init()
{ {
LARGE_INTEGER qpc; LARGE_INTEGER qpc;
QueryPerformanceFrequency(&qpc); QueryPerformanceFrequency(&qpc);
g_qpcFrequency = qpc.QuadPart; g_qpcFrequency = qpc.QuadPart;
g_waitableTimer = CreateWaitableTimer(nullptr, FALSE, nullptr);
} }
void waitForNextTick() void waitForNextTick()
{ {
thread_local HANDLE waitableTimer = CreateWaitableTimer(nullptr, FALSE, nullptr);
LARGE_INTEGER due = {}; LARGE_INTEGER due = {};
due.QuadPart = -1; due.QuadPart = -1;
if (!g_waitableTimer || if (!waitableTimer ||
!SetWaitableTimer(g_waitableTimer, &due, 0, nullptr, nullptr, FALSE) || !SetWaitableTimer(waitableTimer, &due, 0, nullptr, nullptr, FALSE) ||
WAIT_OBJECT_0 != WaitForSingleObject(g_waitableTimer, INFINITE)) WAIT_OBJECT_0 != WaitForSingleObject(waitableTimer, INFINITE))
{ {
Sleep(1); Sleep(1);
} }

View File

@ -15,6 +15,7 @@ namespace Config
Settings::DisplayResolution displayResolution; Settings::DisplayResolution displayResolution;
Settings::DpiAwareness dpiAwareness; Settings::DpiAwareness dpiAwareness;
Settings::ForceD3D9On12 forceD3D9On12; Settings::ForceD3D9On12 forceD3D9On12;
Settings::FpsLimiter fpsLimiter;
Settings::FullscreenMode fullscreenMode; Settings::FullscreenMode fullscreenMode;
Settings::LogLevel logLevel; Settings::LogLevel logLevel;
Settings::RemoveBorders removeBorders; Settings::RemoveBorders removeBorders;

View File

@ -13,6 +13,7 @@
#include <Config/Settings/DisplayResolution.h> #include <Config/Settings/DisplayResolution.h>
#include <Config/Settings/DpiAwareness.h> #include <Config/Settings/DpiAwareness.h>
#include <Config/Settings/ForceD3D9On12.h> #include <Config/Settings/ForceD3D9On12.h>
#include <Config/Settings/FpsLimiter.h>
#include <Config/Settings/FullscreenMode.h> #include <Config/Settings/FullscreenMode.h>
#include <Config/Settings/LogLevel.h> #include <Config/Settings/LogLevel.h>
#include <Config/Settings/RemoveBorders.h> #include <Config/Settings/RemoveBorders.h>
@ -42,6 +43,7 @@ namespace Config
extern Settings::DisplayResolution displayResolution; extern Settings::DisplayResolution displayResolution;
extern Settings::DpiAwareness dpiAwareness; extern Settings::DpiAwareness dpiAwareness;
extern Settings::ForceD3D9On12 forceD3D9On12; extern Settings::ForceD3D9On12 forceD3D9On12;
extern Settings::FpsLimiter fpsLimiter;
extern Settings::FullscreenMode fullscreenMode; extern Settings::FullscreenMode fullscreenMode;
extern Settings::LogLevel logLevel; extern Settings::LogLevel logLevel;
extern Settings::RemoveBorders removeBorders; extern Settings::RemoveBorders removeBorders;

View File

@ -0,0 +1,26 @@
#include <Config/Settings/FpsLimiter.h>
namespace Config
{
namespace Settings
{
FpsLimiter::FpsLimiter()
: MappedSetting("FpsLimiter", "off", {
{"off", OFF},
{"flipstart", FLIPSTART},
{"flipend", FLIPEND},
{"msgloop", MSGLOOP}
})
{
}
Setting::ParamInfo FpsLimiter::getParamInfo() const
{
if (OFF != m_value)
{
return { "MaxFPS", 10, 200, 60, m_param };
}
return {};
}
}
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <Config/MappedSetting.h>
namespace Config
{
namespace Settings
{
class FpsLimiter : public MappedSetting<UINT>
{
public:
static const UINT OFF = 0;
static const UINT FLIPSTART = 1;
static const UINT FLIPEND = 2;
static const UINT MSGLOOP = 3;
FpsLimiter();
virtual ParamInfo getParamInfo() const override;
};
}
}

View File

@ -5,6 +5,7 @@
#include <Common/CompatPtr.h> #include <Common/CompatPtr.h>
#include <Common/Hook.h> #include <Common/Hook.h>
#include <Common/ScopedCriticalSection.h> #include <Common/ScopedCriticalSection.h>
#include <Common/ScopedThreadPriority.h>
#include <Common/Time.h> #include <Common/Time.h>
#include <Config/Config.h> #include <Config/Config.h>
#include <D3dDdi/Device.h> #include <D3dDdi/Device.h>
@ -748,4 +749,33 @@ namespace DDraw
} }
return true; return true;
} }
void RealPrimarySurface::waitForFlipFpsLimit()
{
static long long g_qpcPrevWaitEnd = Time::queryPerformanceCounter() - Time::g_qpcFrequency;
auto qpcNow = Time::queryPerformanceCounter();
auto qpcWaitEnd = g_qpcPrevWaitEnd + Time::g_qpcFrequency / Config::fpsLimiter.getParam();
if (qpcNow - qpcWaitEnd >= 0)
{
g_qpcPrevWaitEnd = qpcNow;
g_qpcDelayedFlipEnd = qpcNow;
return;
}
g_qpcPrevWaitEnd = qpcWaitEnd;
g_qpcDelayedFlipEnd = qpcWaitEnd;
Compat::ScopedThreadPriority prio(THREAD_PRIORITY_TIME_CRITICAL);
while (Time::qpcToMs(qpcWaitEnd - qpcNow) > 0)
{
Time::waitForNextTick();
flush();
qpcNow = Time::queryPerformanceCounter();
}
while (qpcWaitEnd - qpcNow > 0)
{
qpcNow = Time::queryPerformanceCounter();
}
g_qpcDelayedFlipEnd = Time::queryPerformanceCounter();
}
} }

View File

@ -34,5 +34,6 @@ namespace DDraw
static void setUpdateReady(); static void setUpdateReady();
static void updateDevicePresentationWindowPos(); static void updateDevicePresentationWindowPos();
static bool waitForFlip(CompatWeakPtr<IDirectDrawSurface7> surface); static bool waitForFlip(CompatWeakPtr<IDirectDrawSurface7> surface);
static void waitForFlipFpsLimit();
}; };
} }

View File

@ -1,4 +1,5 @@
#include <Common/CompatPtr.h> #include <Common/CompatPtr.h>
#include <Config/Config.h>
#include <D3dDdi/KernelModeThunks.h> #include <D3dDdi/KernelModeThunks.h>
#include <D3dDdi/ScopedCriticalSection.h> #include <D3dDdi/ScopedCriticalSection.h>
#include <DDraw/DirectDrawClipper.h> #include <DDraw/DirectDrawClipper.h>
@ -127,6 +128,12 @@ namespace DDraw
RealPrimarySurface::setUpdateReady(); RealPrimarySurface::setUpdateReady();
RealPrimarySurface::flush(); RealPrimarySurface::flush();
RealPrimarySurface::waitForFlip(m_data->getDDS()); RealPrimarySurface::waitForFlip(m_data->getDDS());
if (Config::Settings::FpsLimiter::FLIPSTART == Config::fpsLimiter.get())
{
RealPrimarySurface::waitForFlipFpsLimit();
}
auto surfaceTargetOverride(CompatPtr<TSurface>::from(lpDDSurfaceTargetOverride)); auto surfaceTargetOverride(CompatPtr<TSurface>::from(lpDDSurfaceTargetOverride));
const bool isFlipEmulated = 0 != (PrimarySurface::getOrigCaps() & DDSCAPS_SYSTEMMEMORY); const bool isFlipEmulated = 0 != (PrimarySurface::getOrigCaps() & DDSCAPS_SYSTEMMEMORY);
if (isFlipEmulated) if (isFlipEmulated)
@ -137,7 +144,12 @@ namespace DDraw
caps.dwCaps = DDSCAPS_BACKBUFFER; caps.dwCaps = DDSCAPS_BACKBUFFER;
getOrigVtable(This).GetAttachedSurface(This, &caps, &surfaceTargetOverride.getRef()); getOrigVtable(This).GetAttachedSurface(This, &caps, &surfaceTargetOverride.getRef());
} }
return Blt(This, nullptr, surfaceTargetOverride.get(), nullptr, DDBLT_WAIT, nullptr); 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); HRESULT result = SurfaceImpl::Flip(This, surfaceTargetOverride, DDFLIP_WAIT);
@ -147,7 +159,13 @@ namespace DDraw
} }
PrimarySurface::updateFrontResource(); PrimarySurface::updateFrontResource();
return RealPrimarySurface::flip(surfaceTargetOverride, dwFlags); result = RealPrimarySurface::flip(surfaceTargetOverride, dwFlags);
if (SUCCEEDED(result) && Config::Settings::FpsLimiter::FLIPEND == Config::fpsLimiter.get())
{
DDraw::RealPrimarySurface::waitForFlip(m_data->getDDS());
RealPrimarySurface::waitForFlipFpsLimit();
}
return result;
} }
template <typename TSurface> template <typename TSurface>

View File

@ -14,6 +14,7 @@
#include <DDraw/Surfaces/Surface.h> #include <DDraw/Surfaces/Surface.h>
#include <DDraw/Surfaces/SurfaceImpl.h> #include <DDraw/Surfaces/SurfaceImpl.h>
#include <Dll/Dll.h> #include <Dll/Dll.h>
#include <Gdi/WinProc.h>
namespace namespace
{ {
@ -110,6 +111,7 @@ namespace DDraw
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
DWORD dwFlags, LPDDBLTFX lpDDBltFx) DWORD dwFlags, LPDDBLTFX lpDDBltFx)
{ {
Gdi::WinProc::startFrame();
RealPrimarySurface::waitForFlip(m_data->getDDS()); RealPrimarySurface::waitForFlip(m_data->getDDS());
DirectDrawClipper::update(); DirectDrawClipper::update();
return blt(This, lpDDSrcSurface, lpSrcRect, [=](TSurface* This, TSurface* lpDDSrcSurface, LPRECT lpSrcRect) return blt(This, lpDDSrcSurface, lpSrcRect, [=](TSurface* This, TSurface* lpDDSrcSurface, LPRECT lpSrcRect)
@ -120,6 +122,7 @@ namespace DDraw
HRESULT SurfaceImpl<TSurface>::BltFast( HRESULT SurfaceImpl<TSurface>::BltFast(
TSurface* This, DWORD dwX, DWORD dwY, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) TSurface* This, DWORD dwX, DWORD dwY, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans)
{ {
Gdi::WinProc::startFrame();
RealPrimarySurface::waitForFlip(m_data->getDDS()); RealPrimarySurface::waitForFlip(m_data->getDDS());
return blt(This, lpDDSrcSurface, lpSrcRect, [=](TSurface* This, TSurface* lpDDSrcSurface, LPRECT lpSrcRect) return blt(This, lpDDSrcSurface, lpSrcRect, [=](TSurface* This, TSurface* lpDDSrcSurface, LPRECT lpSrcRect)
{ return getOrigVtable(This).BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans); }); { return getOrigVtable(This).BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans); });
@ -145,6 +148,7 @@ namespace DDraw
template <typename TSurface> template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::GetDC(TSurface* This, HDC* lphDC) HRESULT SurfaceImpl<TSurface>::GetDC(TSurface* This, HDC* lphDC)
{ {
Gdi::WinProc::startFrame();
RealPrimarySurface::waitForFlip(m_data->getDDS()); RealPrimarySurface::waitForFlip(m_data->getDDS());
HRESULT result = getOrigVtable(This).GetDC(This, lphDC); HRESULT result = getOrigVtable(This).GetDC(This, lphDC);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
@ -182,6 +186,7 @@ namespace DDraw
TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc, TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
DWORD dwFlags, HANDLE hEvent) DWORD dwFlags, HANDLE hEvent)
{ {
Gdi::WinProc::startFrame();
RealPrimarySurface::waitForFlip(m_data->getDDS()); RealPrimarySurface::waitForFlip(m_data->getDDS());
HRESULT result = getOrigVtable(This).Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent); HRESULT result = getOrigVtable(This).Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
if (SUCCEEDED(result)) if (SUCCEEDED(result))

View File

@ -145,6 +145,7 @@
<ClInclude Include="Common\Path.h" /> <ClInclude Include="Common\Path.h" />
<ClInclude Include="Common\Rect.h" /> <ClInclude Include="Common\Rect.h" />
<ClInclude Include="Common\ScopedSrwLock.h" /> <ClInclude Include="Common\ScopedSrwLock.h" />
<ClInclude Include="Common\ScopedThreadPriority.h" />
<ClInclude Include="Common\VtableHookVisitor.h" /> <ClInclude Include="Common\VtableHookVisitor.h" />
<ClInclude Include="Common\VtableSizeVisitor.h" /> <ClInclude Include="Common\VtableSizeVisitor.h" />
<ClInclude Include="Common\VtableVisitor.h" /> <ClInclude Include="Common\VtableVisitor.h" />
@ -171,6 +172,7 @@
<ClInclude Include="Config\Settings\DisplayResolution.h" /> <ClInclude Include="Config\Settings\DisplayResolution.h" />
<ClInclude Include="Config\Settings\DpiAwareness.h" /> <ClInclude Include="Config\Settings\DpiAwareness.h" />
<ClInclude Include="Config\Settings\ForceD3D9On12.h" /> <ClInclude Include="Config\Settings\ForceD3D9On12.h" />
<ClInclude Include="Config\Settings\FpsLimiter.h" />
<ClInclude Include="Config\Settings\FullscreenMode.h" /> <ClInclude Include="Config\Settings\FullscreenMode.h" />
<ClInclude Include="Config\Settings\LogLevel.h" /> <ClInclude Include="Config\Settings\LogLevel.h" />
<ClInclude Include="Config\Settings\RemoveBorders.h" /> <ClInclude Include="Config\Settings\RemoveBorders.h" />
@ -307,6 +309,7 @@
<ClCompile Include="Config\Settings\DisplayFilter.cpp" /> <ClCompile Include="Config\Settings\DisplayFilter.cpp" />
<ClCompile Include="Config\Settings\DisplayRefreshRate.cpp" /> <ClCompile Include="Config\Settings\DisplayRefreshRate.cpp" />
<ClCompile Include="Config\Settings\DisplayResolution.cpp" /> <ClCompile Include="Config\Settings\DisplayResolution.cpp" />
<ClCompile Include="Config\Settings\FpsLimiter.cpp" />
<ClCompile Include="Config\Settings\ResolutionScale.cpp" /> <ClCompile Include="Config\Settings\ResolutionScale.cpp" />
<ClCompile Include="Config\Settings\SpriteDetection.cpp" /> <ClCompile Include="Config\Settings\SpriteDetection.cpp" />
<ClCompile Include="Config\Settings\SpriteFilter.cpp" /> <ClCompile Include="Config\Settings\SpriteFilter.cpp" />

View File

@ -576,6 +576,12 @@
<ClInclude Include="Config\Settings\DpiAwareness.h"> <ClInclude Include="Config\Settings\DpiAwareness.h">
<Filter>Header Files\Config\Settings</Filter> <Filter>Header Files\Config\Settings</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Config\Settings\FpsLimiter.h">
<Filter>Header Files\Config\Settings</Filter>
</ClInclude>
<ClInclude Include="Common\ScopedThreadPriority.h">
<Filter>Header Files\Common</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Gdi\Gdi.cpp"> <ClCompile Include="Gdi\Gdi.cpp">
@ -905,6 +911,9 @@
<ClCompile Include="Overlay\ButtonControl.cpp"> <ClCompile Include="Overlay\ButtonControl.cpp">
<Filter>Source Files\Overlay</Filter> <Filter>Source Files\Overlay</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Config\Settings\FpsLimiter.cpp">
<Filter>Source Files\Config\Settings</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="DDrawCompat.rc"> <ResourceCompile Include="DDrawCompat.rc">

View File

@ -6,6 +6,8 @@
#include <Common/Hook.h> #include <Common/Hook.h>
#include <Common/Log.h> #include <Common/Log.h>
#include <Common/ScopedSrwLock.h> #include <Common/ScopedSrwLock.h>
#include <Common/ScopedThreadPriority.h>
#include <Common/Time.h>
#include <Config/Config.h> #include <Config/Config.h>
#include <Dll/Dll.h> #include <Dll/Dll.h>
#include <DDraw/DirectDraw.h> #include <DDraw/DirectDraw.h>
@ -28,6 +30,16 @@
namespace namespace
{ {
class ScopedIncrement
{
public:
ScopedIncrement(unsigned& num) : m_num(num) { ++m_num; }
~ScopedIncrement() { --m_num; }
private:
unsigned& m_num;
};
struct WindowProc struct WindowProc
{ {
WNDPROC wndProcA; WNDPROC wndProcA;
@ -42,6 +54,10 @@ namespace
thread_local unsigned g_inCreateDialog = 0; thread_local unsigned g_inCreateDialog = 0;
thread_local unsigned g_inMessageBox = 0; thread_local unsigned g_inMessageBox = 0;
thread_local unsigned g_inWindowProc = 0;
thread_local long long g_qpcWaitEnd = 0;
thread_local bool g_isFrameStarted = false;
thread_local bool g_waiting = false;
WindowProc getWindowProc(HWND hwnd); WindowProc getWindowProc(HWND hwnd);
bool isUser32ScrollBar(HWND hwnd); bool isUser32ScrollBar(HWND hwnd);
@ -68,6 +84,7 @@ namespace
decltype(&CallWindowProcA) callWindowProc, WNDPROC wndProc) decltype(&CallWindowProcA) callWindowProc, WNDPROC wndProc)
{ {
LOG_FUNC("ddcWindowProc", Compat::WindowMessageStruct(hwnd, uMsg, wParam, lParam)); LOG_FUNC("ddcWindowProc", Compat::WindowMessageStruct(hwnd, uMsg, wParam, lParam));
ScopedIncrement inc(g_inWindowProc);
switch (uMsg) switch (uMsg)
{ {
@ -388,7 +405,53 @@ namespace
decltype(&PeekMessageA) origPeekMessage) decltype(&PeekMessageA) origPeekMessage)
{ {
DDraw::RealPrimarySurface::setUpdateReady(); DDraw::RealPrimarySurface::setUpdateReady();
return origPeekMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); BOOL result = origPeekMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
if (!g_isFrameStarted || Config::Settings::FpsLimiter::MSGLOOP != Config::fpsLimiter.get())
{
return result;
}
auto qpcNow = Time::queryPerformanceCounter();
if (qpcNow - g_qpcWaitEnd >= 0)
{
if (!g_waiting)
{
g_qpcWaitEnd = qpcNow;
}
g_isFrameStarted = false;
g_waiting = false;
return result;
}
g_waiting = true;
if (result)
{
return result;
}
Compat::ScopedThreadPriority prio(THREAD_PRIORITY_TIME_CRITICAL);
while (Time::qpcToMs(g_qpcWaitEnd - qpcNow) > 0)
{
Time::waitForNextTick();
if (origPeekMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg))
{
return TRUE;
}
qpcNow = Time::queryPerformanceCounter();
}
while (g_qpcWaitEnd - qpcNow > 0)
{
if (origPeekMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg))
{
return TRUE;
}
qpcNow = Time::queryPerformanceCounter();
}
g_isFrameStarted = false;
g_waiting = false;
return result;
} }
BOOL WINAPI peekMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg) BOOL WINAPI peekMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg)
@ -654,6 +717,54 @@ namespace Gdi
Gdi::Window::updateAll(); Gdi::Window::updateAll();
} }
void startFrame()
{
if (Config::Settings::FpsLimiter::MSGLOOP != Config::fpsLimiter.get() || g_inWindowProc)
{
return;
}
auto fps = Config::fpsLimiter.getParam();
if (0 == fps)
{
fps = 1000;
}
if (!g_isFrameStarted)
{
g_qpcWaitEnd += Time::g_qpcFrequency / fps;
g_isFrameStarted = true;
return;
}
if (!g_waiting)
{
return;
}
g_qpcWaitEnd += Time::g_qpcFrequency / fps;
g_waiting = false;
auto qpcNow = Time::queryPerformanceCounter();
if (qpcNow - g_qpcWaitEnd >= 0)
{
return;
}
Compat::ScopedThreadPriority prio(THREAD_PRIORITY_TIME_CRITICAL);
while (Time::qpcToMs(g_qpcWaitEnd - qpcNow) > 0)
{
Time::waitForNextTick();
DDraw::RealPrimarySurface::flush();
qpcNow = Time::queryPerformanceCounter();
}
while (g_qpcWaitEnd - qpcNow > 0)
{
qpcNow = Time::queryPerformanceCounter();
}
}
void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc) void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc)
{ {

View File

@ -9,6 +9,7 @@ namespace Gdi
void dllThreadDetach(); void dllThreadDetach();
void installHooks(); void installHooks();
void onCreateWindow(HWND hwnd); void onCreateWindow(HWND hwnd);
void startFrame();
void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc); void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc);
} }
} }

View File

@ -17,7 +17,7 @@ namespace
namespace Overlay namespace Overlay
{ {
ConfigWindow::ConfigWindow() ConfigWindow::ConfigWindow()
: Window(nullptr, { 0, 0, SettingControl::TOTAL_WIDTH, 350 }, Config::configHotKey.get()) : Window(nullptr, { 0, 0, SettingControl::TOTAL_WIDTH, 380 }, Config::configHotKey.get())
, m_buttonCount(0) , m_buttonCount(0)
, m_focus(nullptr) , m_focus(nullptr)
{ {
@ -31,6 +31,7 @@ namespace Overlay
addControl(Config::bltFilter); addControl(Config::bltFilter);
addControl(Config::antialiasing); addControl(Config::antialiasing);
addControl(Config::displayFilter); addControl(Config::displayFilter);
addControl(Config::fpsLimiter);
addControl(Config::renderColorDepth); addControl(Config::renderColorDepth);
addControl(Config::resolutionScale); addControl(Config::resolutionScale);
addControl(Config::spriteDetection); addControl(Config::spriteDetection);

View File

@ -19,7 +19,7 @@ namespace Overlay
{ {
public: public:
static const int PARAM_LABEL_WIDTH = 70; static const int PARAM_LABEL_WIDTH = 70;
static const int PARAM_CONTROL_WIDTH = 151; static const int PARAM_CONTROL_WIDTH = 241;
static const int SETTING_LABEL_WIDTH = 120; static const int SETTING_LABEL_WIDTH = 120;
static const int SETTING_CONTROL_WIDTH = 151; static const int SETTING_CONTROL_WIDTH = 151;
static const int TOTAL_WIDTH = static const int TOTAL_WIDTH =