@@ -49,7 +49,10 @@ namespace FPSLimiter
4949 m_data.serverEnforcedFPS = 0 ;
5050 m_data.clientEnforcedFPS = 0 ;
5151 m_data.userDefinedFPS = 0 ;
52- // m_data.displayRefreshRate = 0; // We do not reset display refresh rate
52+
53+ bool bVSync;
54+ CVARS_GET (" vsync" , bVSync);
55+ m_data.displayRefreshRate = bVSync ? GetDisplayRefreshRate () : 0 ;
5356 CalculateCurrentFPSLimit ();
5457 }
5558
@@ -86,7 +89,7 @@ namespace FPSLimiter
8689 if (m_data.displayRefreshRate > FPS_LIMIT_MIN && m_data.displayRefreshRate < minFPS)
8790 {
8891 minFPS = m_data.displayRefreshRate ;
89- enforcer = EnforcerType::RefreshRate ;
92+ enforcer = EnforcerType::VSync ;
9093 }
9194
9295 // If the lowest matches the active target, return its enforcer
@@ -115,16 +118,28 @@ namespace FPSLimiter
115118 CalculateCurrentFPSLimit ();
116119 }
117120
118- void FPSLimiter::SetDisplayRefreshRate (std:: uint32_t refreshRate )
121+ void FPSLimiter::SetDisplayVSync ( bool enabled )
119122 {
120- m_data.displayRefreshRate = ValidateFPS (refreshRate) ;
123+ m_data.displayRefreshRate = enabled ? GetDisplayRefreshRate () : 0 ;
121124 CalculateCurrentFPSLimit ();
122125 }
123126
124127#pragma endregion Interface
125128
126129#pragma region Internal
127130
131+ std::uint32_t FPSLimiter::GetDisplayRefreshRate ()
132+ {
133+ D3DDISPLAYMODE DisplayMode;
134+ IDirect3D9* pD3D9 = CProxyDirect3D9::StaticGetDirect3D ();
135+ if (pD3D9 && pD3D9->GetAdapterDisplayMode (D3DADAPTER_DEFAULT, &DisplayMode) == D3D_OK)
136+ {
137+ return ValidateFPS (DisplayMode.RefreshRate );
138+ }
139+ // Fallback to 60 Hz if unable to get refresh rate
140+ return 60 ;
141+ }
142+
128143 // Priority: Server > Client > User > None
129144 void FPSLimiter::CalculateCurrentFPSLimit ()
130145 {
@@ -154,10 +169,6 @@ namespace FPSLimiter
154169
155170 m_data.activeFPSTarget = minFPS;
156171
157- std::stringstream ss;
158- ss << " FPSLimiter: Calculated active FPS limit: " << m_data.activeFPSTarget ;
159- OutputDebugLine (ss.str ().c_str ());
160-
161172 // If limit changed, reset frame timing
162173 if (oldLimit != m_data.activeFPSTarget )
163174 {
@@ -168,13 +179,9 @@ namespace FPSLimiter
168179 OnFPSLimitChange ();
169180 }
170181
171- ss.clear ();
172- ss << " FPSLimiter: Calculated current FPS limit : " << m_data.activeFPSTarget
173- << " (Server: " << m_data.serverEnforcedFPS
174- << " , Client: " << m_data.clientEnforcedFPS
175- << " , User: " << m_data.userDefinedFPS
176- << " , Display: " << m_data.displayRefreshRate
177- << " ) Enforcer: " << EnumToString (GetEnforcer ());
182+ std::stringstream ss;
183+ ss << " FPSLimiter: FPS limit changed to " << (m_data.activeFPSTarget == 0 ? " unlimited" : std::to_string (m_data.activeFPSTarget ));
184+ ss << " (Enforced by: " << EnumToString (GetEnforcer ()) << " )" ;
178185
179186 auto * pConsole = CCore::GetSingleton ().GetConsole ();
180187 if (pConsole)
@@ -262,7 +269,11 @@ namespace FPSLimiter
262269 HMODULE ntdll = GetModuleHandleA (" ntdll.dll" );
263270 if (ntdll)
264271 {
265- NtSetTimerResolution setRes = reinterpret_cast <NtSetTimerResolution>(GetProcAddress (ntdll, " NtSetTimerResolution" ));
272+ auto proc = GetProcAddress (ntdll, " NtSetTimerResolution" );
273+ #pragma warning(push)
274+ #pragma warning(suppress : 4191)
275+ auto setRes = reinterpret_cast <NtSetTimerResolution>(proc);
276+ #pragma warning(pop)
266277 if (setRes)
267278 {
268279 ULONG actualRes;
@@ -356,6 +367,14 @@ namespace FPSLimiter
356367
357368#pragma endregion Events
358369
370+ IMPLEMENT_ENUM_BEGIN (EnforcerType)
371+ ADD_ENUM (EnforcerType::None, " none" )
372+ ADD_ENUM (EnforcerType::VSync, " vsync" )
373+ ADD_ENUM (EnforcerType::UserDefined, " user-defined" )
374+ ADD_ENUM (EnforcerType::Client, " client" )
375+ ADD_ENUM (EnforcerType::Server, " server" )
376+ IMPLEMENT_ENUM_END (" EnforcerType" );
377+
359378}; // namespace FPSLimiter
360379
361380std::uint32_t FPSLimiter::ValidateFPS (std::uint32_t uiFPS)
0 commit comments