From 7843664f688cfa517ad0088761ef2e1341245dd4 Mon Sep 17 00:00:00 2001 From: "J.D. Purcell" Date: Fri, 16 Dec 2016 16:01:21 -0500 Subject: [PATCH] Improve FPS smoothing to initialize with a real value instead of ramping up from zero. Re-initialize the FPS data after pausing or changing fast forward/rewind state to eliminate ramp-up and ramp-down in those cases. Only the initial behavior has changed; the FPS calculation/smoothing is otherwise mathematically identical. --- BizHawk.Client.EmuHawk/MainForm.cs | 111 +++++++++++++++++------------ 1 file changed, 65 insertions(+), 46 deletions(-) diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 58befef60b..75b80b34a6 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -487,6 +487,8 @@ namespace BizHawk.Client.EmuHawk Activate(); BringToFront(); + InitializeFpsData(); + for (;;) { Input.Instance.Update(); @@ -584,6 +586,11 @@ namespace BizHawk.Client.EmuHawk private set { + if (_emulatorPaused && !value) // Unpausing + { + InitializeFpsData(); + } + _emulatorPaused = value; if (OnPauseChanged != null) { @@ -1358,15 +1365,16 @@ namespace BizHawk.Client.EmuHawk private bool _runloopFrameProgress; private long _frameAdvanceTimestamp; private long _frameRewindTimestamp; - private double _runloopLastFps; - private double _runloopDisplayFps; private bool _runloopFrameadvance; - private double _runloopUpdatesPerSecond = 12.0; - private double _runloopFpsSmoothing = 8.0; - private long _runloopSecond; - private bool _runloopLastFf; + private bool _lastFastForwardingOrRewinding; private bool _inResizeLoop; + private readonly double _fpsUpdatesPerSecond = 12.0; + private readonly double _fpsSmoothing = 8.0; + private double _lastFps; + private int _framesSinceLastFpsUpdate; + private long _timestampLastFpsUpdate; + private readonly Throttle _throttle; private bool _unthrottled; @@ -1416,7 +1424,7 @@ namespace BizHawk.Client.EmuHawk //we need to display FPS somewhere, in this case if (Global.Config.DispSpeedupFeatures == 0) { - str = str + string.Format("({0:0} fps) -", _runloopDisplayFps); + str = str + string.Format("({0:0} fps) -", _lastFps); } if (!string.IsNullOrEmpty(VersionInfo.CustomBuildString)) @@ -2757,8 +2765,13 @@ namespace BizHawk.Client.EmuHawk if (runFrame || force) { var isFastForwarding = Global.ClientControls["Fast Forward"] || IsTurboing; - var updateFpsString = _runloopLastFf != isFastForwarding; - _runloopLastFf = isFastForwarding; + var isFastFowardingOrRewinding = isFastForwarding || isRewinding; + + if (isFastFowardingOrRewinding != _lastFastForwardingOrRewinding) + { + InitializeFpsData(); + } + _lastFastForwardingOrRewinding = isFastFowardingOrRewinding; // client input-related duties GlobalWin.OSD.ClearGUIText(); @@ -2783,9 +2796,9 @@ namespace BizHawk.Client.EmuHawk GlobalWin.Tools.UpdateToolsBefore(); } - _runloopLastFps+= _runloopFpsSmoothing; + _framesSinceLastFpsUpdate++; - UpdateFpsDisplay(currentTimestamp, updateFpsString, isRewinding, isFastForwarding); + UpdateFpsDisplay(currentTimestamp, isRewinding, isFastForwarding); CaptureRewind(suppressCaptureRewind); @@ -2794,7 +2807,7 @@ namespace BizHawk.Client.EmuHawk { atten = Global.Config.SoundVolume / 100.0f; - if (isFastForwarding || IsTurboing || isRewinding) + if (isFastFowardingOrRewinding) { if (Global.Config.SoundEnabledRWFF) atten *= Global.Config.SoundVolumeRWFF / 100.0f; @@ -2884,46 +2897,52 @@ namespace BizHawk.Client.EmuHawk GlobalWin.Sound.UpdateSound(atten); } - private void UpdateFpsDisplay(long currentTimestamp, bool updateFpsString, bool isRewinding, bool isFastForwarding) + private void UpdateFpsDisplay(long currentTimestamp, bool isRewinding, bool isFastForwarding) { - var timeDiff = (currentTimestamp - _runloopSecond); - if ( timeDiff * _runloopUpdatesPerSecond >= Stopwatch.Frequency) + double elapsedSeconds = (currentTimestamp - _timestampLastFpsUpdate) / (double)Stopwatch.Frequency; + + if (elapsedSeconds < 1.0 / _fpsUpdatesPerSecond) { - _runloopLastFps = Stopwatch.Frequency * (_runloopLastFps / (Stopwatch.Frequency + timeDiff * _runloopFpsSmoothing)); - _runloopSecond = currentTimestamp; - _runloopDisplayFps = _runloopLastFps; - updateFpsString = true; + return; } - if (updateFpsString) + if (_lastFps == 0) // Initial calculation { - var fps_string = string.Format("{0:0} fps", _runloopDisplayFps); - if (isRewinding) - { - if (IsTurboing || isFastForwarding) - { - fps_string += " <<<<"; - } - else - { - fps_string += " <<"; - } - } - else if (IsTurboing) - { - fps_string += " >>>>"; - } - else if (isFastForwarding) - { - fps_string += " >>"; - } - - GlobalWin.OSD.FPS = fps_string; - - //need to refresh window caption in this case - if (Global.Config.DispSpeedupFeatures == 0) - SetWindowText(); + _lastFps = (_framesSinceLastFpsUpdate - 1) / elapsedSeconds; } + else + { + _lastFps = (_lastFps + (_framesSinceLastFpsUpdate * _fpsSmoothing)) / (1.0 + (elapsedSeconds * _fpsSmoothing)); + } + _framesSinceLastFpsUpdate = 0; + _timestampLastFpsUpdate = currentTimestamp; + + var fps_string = string.Format("{0:0} fps", _lastFps); + if (isRewinding) + { + fps_string += IsTurboing || isFastForwarding ? + " <<<<" : + " <<"; + } + else if (isFastForwarding) + { + fps_string += IsTurboing ? + " >>>>" : + " >>"; + } + + GlobalWin.OSD.FPS = fps_string; + + //need to refresh window caption in this case + if (Global.Config.DispSpeedupFeatures == 0) + SetWindowText(); + } + + private void InitializeFpsData() + { + _lastFps = 0; + _timestampLastFpsUpdate = Stopwatch.GetTimestamp(); + _framesSinceLastFpsUpdate = 0; } #endregion