@@ -56,7 +56,7 @@ static HMODULE WINAPI SkipDirectPlay_LoadLibraryA(LPCSTR fileName)
56
56
if (!StrCmpIA (" enbseries\\ enbhelper.dll" , fileName))
57
57
{
58
58
std::error_code ec;
59
-
59
+
60
60
// Try to load enbhelper.dll from our custom launch directory first.
61
61
const fs::path inLaunchDir = fs::path{FromUTF8 (GetLaunchPath ())} / " enbseries" / " enbhelper.dll" ;
62
62
@@ -146,18 +146,16 @@ CCore::CCore()
146
146
// Setup our hooks.
147
147
ApplyHooks ();
148
148
149
- // No initial fps limit
150
- m_bDoneFrameRateLimit = false ;
151
- m_uiFrameRateLimit = 0 ;
152
- m_uiServerFrameRateLimit = 0 ;
153
149
m_iUnminimizeFrameCounter = 0 ;
154
150
m_bDidRecreateRenderTargets = false ;
155
151
m_fMinStreamingMemory = 0 ;
156
152
m_fMaxStreamingMemory = 0 ;
157
153
m_bGettingIdleCallsFromMultiplayer = false ;
158
154
m_bWindowsTimerEnabled = false ;
159
155
m_timeDiscordAppLastUpdate = 0 ;
160
- m_CurrentRefreshRate = 60 ;
156
+
157
+ // Initialize FPS limiter
158
+ m_pFPSLimiter = std::make_unique<FPSLimiter::FPSLimiter>();
161
159
162
160
// Create tray icon
163
161
m_pTrayIcon = new CTrayIcon ();
@@ -180,6 +178,8 @@ CCore::~CCore()
180
178
// Destroy tray icon
181
179
delete m_pTrayIcon;
182
180
181
+ m_pFPSLimiter.reset ();
182
+
183
183
// This will set the GTA volume to the GTA volume value in the settings,
184
184
// and is not affected by the master volume setting.
185
185
m_pLocalGUI->GetMainMenu ()->GetSettingsWindow ()->ResetGTAVolume ();
@@ -1347,7 +1347,7 @@ void CCore::OnModUnload()
1347
1347
m_pKeyBinds->RemoveAllControlFunctions ();
1348
1348
1349
1349
// Reset client script frame rate limit
1350
- m_uiClientScriptFrameRateLimit = 0 ;
1350
+ GetFPSLimiter ()-> SetClientEnforcedFPS (FPSLimits::FPS_UNLIMITED) ;
1351
1351
1352
1352
// Clear web whitelist
1353
1353
if (m_pWebCore)
@@ -1772,8 +1772,8 @@ void CCore::OnPostColorFilterRender()
1772
1772
{
1773
1773
if (!CGraphics::GetSingleton ().HasLine3DPostFXQueueItems () && !CGraphics::GetSingleton ().HasPrimitive3DPostFXQueueItems ())
1774
1774
return ;
1775
-
1776
- CGraphics::GetSingleton ().EnteringMTARenderZone ();
1775
+
1776
+ CGraphics::GetSingleton ().EnteringMTARenderZone ();
1777
1777
1778
1778
CGraphics::GetSingleton ().DrawPrimitive3DPostFXQueue ();
1779
1779
CGraphics::GetSingleton ().DrawLine3DPostFXQueue ();
@@ -1831,141 +1831,14 @@ void CCore::ApplyCoreInitSettings()
1831
1831
//
1832
1832
void CCore::OnGameTimerUpdate ()
1833
1833
{
1834
- ApplyQueuedFrameRateLimit ();
1834
+ // NOTE: (pxd) We are handling the frame limiting updates
1835
+ // earlier in the callpath (CModManager::DoPulsePreFrame, CModManager::DoPulsePostFrame)
1835
1836
}
1836
1837
1837
- //
1838
- // Recalculate FPS limit to use
1839
- //
1840
- // Uses client rate from config
1841
- // Uses client rate from script
1842
- // Uses server rate from argument, or last time if not supplied
1843
- //
1844
- void CCore::RecalculateFrameRateLimit (uint uiServerFrameRateLimit, bool bLogToConsole)
1838
+ void CCore::OnFPSLimitChange (std::uint16_t fps)
1845
1839
{
1846
- // Save rate from server if valid
1847
- if (uiServerFrameRateLimit != -1 )
1848
- m_uiServerFrameRateLimit = uiServerFrameRateLimit;
1849
-
1850
- // Start with value set by the server
1851
- m_uiFrameRateLimit = m_uiServerFrameRateLimit;
1852
-
1853
- // Apply client config setting
1854
- uint uiClientConfigRate;
1855
- g_pCore->GetCVars ()->Get (" fps_limit" , uiClientConfigRate);
1856
- if (uiClientConfigRate > 0 )
1857
- uiClientConfigRate = std::max (45U , uiClientConfigRate);
1858
- // Lowest wins (Although zero is highest)
1859
- if ((m_uiFrameRateLimit == 0 || uiClientConfigRate < m_uiFrameRateLimit) && uiClientConfigRate > 0 )
1860
- m_uiFrameRateLimit = uiClientConfigRate;
1861
-
1862
- // Apply client script setting
1863
- uint uiClientScriptRate = m_uiClientScriptFrameRateLimit;
1864
- // Lowest wins (Although zero is highest)
1865
- if ((m_uiFrameRateLimit == 0 || uiClientScriptRate < m_uiFrameRateLimit) && uiClientScriptRate > 0 )
1866
- m_uiFrameRateLimit = uiClientScriptRate;
1867
-
1868
- if (!IsConnected ())
1869
- m_uiFrameRateLimit = m_CurrentRefreshRate;
1870
-
1871
- // Removes Limiter from Frame Graph if limit is zero and skips frame limit
1872
- if (m_uiFrameRateLimit == 0 )
1873
- {
1874
- m_bQueuedFrameRateValid = false ;
1875
- GetGraphStats ()->RemoveTimingPoint (" Limiter" );
1876
- }
1877
-
1878
- // Print new limits to the console
1879
- if (bLogToConsole)
1880
- {
1881
- SString strStatus (" Server FPS limit: %d" , m_uiServerFrameRateLimit);
1882
- if (m_uiFrameRateLimit != m_uiServerFrameRateLimit)
1883
- strStatus += SString (" (Using %d)" , m_uiFrameRateLimit);
1884
- CCore::GetSingleton ().GetConsole ()->Print (strStatus);
1885
- }
1886
- }
1887
-
1888
- //
1889
- // Change client rate as set by script
1890
- //
1891
- void CCore::SetClientScriptFrameRateLimit (uint uiClientScriptFrameRateLimit)
1892
- {
1893
- m_uiClientScriptFrameRateLimit = uiClientScriptFrameRateLimit;
1894
- RecalculateFrameRateLimit (-1 , false );
1895
- }
1896
-
1897
- void CCore::SetCurrentRefreshRate (uint value)
1898
- {
1899
- m_CurrentRefreshRate = value;
1900
- RecalculateFrameRateLimit (-1 , false );
1901
- }
1902
-
1903
- //
1904
- // Make sure the frame rate limit has been applied since the last call
1905
- //
1906
- void CCore::EnsureFrameRateLimitApplied ()
1907
- {
1908
- if (!m_bDoneFrameRateLimit)
1909
- {
1910
- ApplyFrameRateLimit ();
1911
- }
1912
- m_bDoneFrameRateLimit = false ;
1913
- }
1914
-
1915
- //
1916
- // Do FPS limiting
1917
- //
1918
- // This is called once a frame even if minimized
1919
- //
1920
- void CCore::ApplyFrameRateLimit (uint uiOverrideRate)
1921
- {
1922
- TIMING_CHECKPOINT (" -CallIdle1" );
1923
- ms_TimingCheckpoints.EndTimingCheckpoints ();
1924
-
1925
- // Frame rate limit stuff starts here
1926
- m_bDoneFrameRateLimit = true ;
1927
-
1928
- uint uiUseRate = uiOverrideRate != -1 ? uiOverrideRate : m_uiFrameRateLimit;
1929
-
1930
- if (uiUseRate > 0 )
1931
- {
1932
- // Apply previous frame rate if is hasn't been done yet
1933
- ApplyQueuedFrameRateLimit ();
1934
-
1935
- // Limit is usually applied in OnGameTimerUpdate
1936
- m_uiQueuedFrameRate = uiUseRate;
1937
- m_bQueuedFrameRateValid = true ;
1938
- }
1939
-
1940
- DoReliablePulse ();
1941
-
1942
- TIMING_GRAPH (" FrameEnd" );
1943
- TIMING_GRAPH (" " );
1944
- }
1945
-
1946
- //
1947
- // Frame rate limit (wait) is done here.
1948
- //
1949
- void CCore::ApplyQueuedFrameRateLimit ()
1950
- {
1951
- if (m_bQueuedFrameRateValid)
1952
- {
1953
- m_bQueuedFrameRateValid = false ;
1954
- // Calc required time in ms between frames
1955
- const double dTargetTimeToUse = 1000.0 / m_uiQueuedFrameRate;
1956
-
1957
- while (true )
1958
- {
1959
- // See if we need to wait
1960
- double dSpare = dTargetTimeToUse - m_FrameRateTimer.Get ();
1961
- if (dSpare <= 0.0 )
1962
- break ;
1963
- if (dSpare >= 10.0 )
1964
- Sleep (1 );
1965
- }
1966
- m_FrameRateTimer.Reset ();
1967
- TIMING_GRAPH (" Limiter" );
1968
- }
1840
+ if (m_pNet != nullptr ) // We have to wait for the network module to be loaded
1841
+ GetWebCore ()->OnFPSLimitChange (fps);
1969
1842
}
1970
1843
1971
1844
//
@@ -2020,7 +1893,7 @@ void CCore::OnDeviceRestore()
2020
1893
void CCore::OnPreFxRender ()
2021
1894
{
2022
1895
if (!CGraphics::GetSingleton ().HasLine3DPreGUIQueueItems () && !CGraphics::GetSingleton ().HasPrimitive3DPreGUIQueueItems ())
2023
- return ;
1896
+ return ;
2024
1897
2025
1898
CGraphics::GetSingleton ().EnteringMTARenderZone ();
2026
1899
@@ -2035,7 +1908,7 @@ void CCore::OnPreFxRender()
2035
1908
//
2036
1909
void CCore::OnPreHUDRender ()
2037
1910
{
2038
- CGraphics::GetSingleton ().EnteringMTARenderZone ();
1911
+ CGraphics::GetSingleton ().EnteringMTARenderZone ();
2039
1912
2040
1913
// Maybe capture screen and other stuff
2041
1914
CGraphics::GetSingleton ().GetRenderItemManager ()->DoPulse ();
@@ -2396,7 +2269,8 @@ SString CCore::GetBlueCopyrightString()
2396
2269
2397
2270
// Set streaming memory size override [See `engineStreamingSetMemorySize`]
2398
2271
// Use `0` to turn it off, and thus restore the value to the `cvar` setting
2399
- void CCore::SetCustomStreamingMemory (size_t sizeBytes) {
2272
+ void CCore::SetCustomStreamingMemory (size_t sizeBytes)
2273
+ {
2400
2274
// NOTE: The override is applied to the game in `CClientGame::DoPulsePostFrame`
2401
2275
// There's no specific reason we couldn't do it here, but we wont
2402
2276
m_CustomStreamingMemoryLimitBytes = sizeBytes;
0 commit comments