diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs
index 77d1e60b87..76790e2b46 100644
--- a/osu.Game/Rulesets/UI/DrawableRuleset.cs
+++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs
@@ -59,6 +59,8 @@ namespace osu.Game.Rulesets.UI
///
public Container Overlays { get; private set; }
+ public override GameplayClock FrameStableClock => frameStabilityContainer.GameplayClock;
+
///
/// Invoked when a has been applied by a .
///
@@ -334,6 +336,11 @@ namespace osu.Game.Rulesets.UI
///
public readonly BindableBool IsPaused = new BindableBool();
+ ///
+ /// The frame-stable clock which is being used for playfield display.
+ ///
+ public abstract GameplayClock FrameStableClock { get; }
+
/// ~
/// The associated ruleset.
///
diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs
index ad15bcf057..733a495248 100644
--- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs
+++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs
@@ -20,7 +20,8 @@ namespace osu.Game.Rulesets.UI
public FrameStabilityContainer()
{
RelativeSizeAxes = Axes.Both;
- gameplayClock = new GameplayClock(framedClock = new FramedClock(manualClock = new ManualClock()));
+
+ GameplayClock = new GameplayClock(framedClock = new FramedClock(manualClock = new ManualClock()));
}
private readonly ManualClock manualClock;
@@ -28,7 +29,7 @@ namespace osu.Game.Rulesets.UI
private readonly FramedClock framedClock;
[Cached]
- private GameplayClock gameplayClock;
+ public GameplayClock GameplayClock { get; }
private IFrameBasedClock parentGameplayClock;
@@ -38,7 +39,7 @@ namespace osu.Game.Rulesets.UI
if (clock != null)
{
parentGameplayClock = clock;
- gameplayClock.IsPaused.BindTo(clock.IsPaused);
+ GameplayClock.IsPaused.BindTo(clock.IsPaused);
}
}
@@ -73,7 +74,7 @@ namespace osu.Game.Rulesets.UI
public override bool UpdateSubTree()
{
requireMoreUpdateLoops = true;
- validState = !gameplayClock.IsPaused.Value;
+ validState = !GameplayClock.IsPaused.Value;
int loops = 0;
@@ -160,7 +161,7 @@ namespace osu.Game.Rulesets.UI
if (parentGameplayClock == null)
parentGameplayClock = Clock;
- Clock = gameplayClock;
+ Clock = GameplayClock;
ProcessCustomClock = false;
}
diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs
index f8e092c8b1..ee229ab93e 100644
--- a/osu.Game/Screens/Play/HUDOverlay.cs
+++ b/osu.Game/Screens/Play/HUDOverlay.cs
@@ -35,6 +35,10 @@ namespace osu.Game.Screens.Play
public readonly HoldForMenuButton HoldToQuit;
public readonly PlayerSettingsOverlay PlayerSettingsOverlay;
+ private readonly ScoreProcessor scoreProcessor;
+ private readonly DrawableRuleset drawableRuleset;
+ private readonly IReadOnlyList mods;
+
private Bindable showHud;
private readonly Container visibilityContainer;
private readonly BindableBool replayLoaded = new BindableBool();
@@ -45,6 +49,10 @@ namespace osu.Game.Screens.Play
public HUDOverlay(ScoreProcessor scoreProcessor, DrawableRuleset drawableRuleset, IReadOnlyList mods)
{
+ this.scoreProcessor = scoreProcessor;
+ this.drawableRuleset = drawableRuleset;
+ this.mods = mods;
+
RelativeSizeAxes = Axes.Both;
Children = new Drawable[]
@@ -89,20 +97,21 @@ namespace osu.Game.Screens.Play
}
}
};
+ }
+ [BackgroundDependencyLoader(true)]
+ private void load(OsuConfigManager config, NotificationOverlay notificationOverlay)
+ {
BindProcessor(scoreProcessor);
BindDrawableRuleset(drawableRuleset);
Progress.Objects = drawableRuleset.Objects;
Progress.AllowSeeking = drawableRuleset.HasReplayLoaded.Value;
Progress.RequestSeek = time => RequestSeek(time);
+ Progress.ReferenceClock = drawableRuleset.FrameStableClock;
ModDisplay.Current.Value = mods;
- }
- [BackgroundDependencyLoader(true)]
- private void load(OsuConfigManager config, NotificationOverlay notificationOverlay)
- {
showHud = config.GetBindable(OsuSetting.ShowInterface);
showHud.ValueChanged += visible => visibilityContainer.FadeTo(visible.NewValue ? 1 : 0, duration);
showHud.TriggerChange();
diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs
index 94b25e04a3..d478454f00 100644
--- a/osu.Game/Screens/Play/SongProgress.cs
+++ b/osu.Game/Screens/Play/SongProgress.cs
@@ -10,6 +10,7 @@ using osu.Game.Graphics;
using osu.Framework.Allocation;
using System.Linq;
using osu.Framework.Bindables;
+using osu.Framework.Timing;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.UI;
@@ -55,7 +56,9 @@ namespace osu.Game.Screens.Play
private readonly BindableBool replayLoaded = new BindableBool();
- private GameplayClock gameplayClock;
+ public IClock ReferenceClock;
+
+ private IClock gameplayClock;
[BackgroundDependencyLoader(true)]
private void load(OsuColour colours, GameplayClock clock)
@@ -154,10 +157,12 @@ namespace osu.Game.Screens.Play
if (objects == null)
return;
- double position = gameplayClock?.CurrentTime ?? Time.Current;
- double progress = Math.Min(1, (position - firstHitTime) / (lastHitTime - firstHitTime));
+ double gameplayTime = gameplayClock?.CurrentTime ?? Time.Current;
+ double frameStableTime = ReferenceClock?.CurrentTime ?? gameplayTime;
- bar.CurrentTime = position;
+ double progress = Math.Min(1, (frameStableTime - firstHitTime) / (lastHitTime - firstHitTime));
+
+ bar.CurrentTime = gameplayTime;
graph.Progress = (int)(graph.ColumnCount * progress);
}
}