From 50f8ab3dfb07c9cc12b0fb5598ecadfdecf3b43d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Apr 2019 16:58:20 +0900 Subject: [PATCH 1/2] Fix gameplay offset handling on seeks --- .../Screens/Play/GameplayClockContainer.cs | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index c13222c6de..fc7a9ddd20 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -36,6 +36,8 @@ namespace osu.Game.Screens.Play /// private readonly DecoupleableInterpolatingFramedClock adjustableClock; + private readonly double gameplayStartTime; + public readonly Bindable UserPlaybackRate = new BindableDouble(1) { Default = 1, @@ -52,11 +54,14 @@ namespace osu.Game.Screens.Play private Bindable userAudioOffset; - private readonly FramedOffsetClock offsetClock; + private readonly FramedOffsetClock userOffsetClock; + + private readonly FramedOffsetClock platformOffsetClock; public GameplayClockContainer(WorkingBeatmap beatmap, double gameplayStartTime) { this.beatmap = beatmap; + this.gameplayStartTime = gameplayStartTime; RelativeSizeAxes = Axes.Both; @@ -64,30 +69,31 @@ namespace osu.Game.Screens.Play adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; - adjustableClock.Seek(Math.Min(0, gameplayStartTime - beatmap.BeatmapInfo.AudioLeadIn)); - - adjustableClock.ProcessFrame(); - // Lazer's audio timings in general doesn't match stable. This is the result of user testing, albeit limited. // This only seems to be required on windows. We need to eventually figure out why, with a bit of luck. - var platformOffsetClock = new FramedOffsetClock(adjustableClock) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 22 : 0 }; + platformOffsetClock = new FramedOffsetClock(adjustableClock) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 22 : 0 }; // the final usable gameplay clock with user-set offsets applied. - offsetClock = new FramedOffsetClock(platformOffsetClock); + userOffsetClock = new FramedOffsetClock(platformOffsetClock); // the clock to be exposed via DI to children. - GameplayClock = new GameplayClock(offsetClock); + GameplayClock = new GameplayClock(userOffsetClock); GameplayClock.IsPaused.BindTo(IsPaused); } + private double totalOffset => userOffsetClock.Offset + platformOffsetClock.Offset; + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); - userAudioOffset.BindValueChanged(offset => offsetClock.Offset = offset.NewValue, true); + userAudioOffset.BindValueChanged(offset => userOffsetClock.Offset = offset.NewValue, true); UserPlaybackRate.ValueChanged += _ => updateRate(); + + Seek(Math.Min(0, gameplayStartTime - beatmap.BeatmapInfo.AudioLeadIn)); + adjustableClock.ProcessFrame(); } public void Restart() @@ -104,9 +110,7 @@ namespace osu.Game.Screens.Play this.Delay(750).Schedule(() => { if (!IsPaused.Value) - { - adjustableClock.Start(); - } + Start(); }); }); }); @@ -121,7 +125,12 @@ namespace osu.Game.Screens.Play IsPaused.Value = false; } - public void Seek(double time) => adjustableClock.Seek(time); + public void Seek(double time) + { + // remove the offset component here because most of the time we want the seek to be aligned to gameplay, not the audio track. + // we may want to consider reversing the application of offsets in the future as it may feel more correct. + adjustableClock.Seek(time - totalOffset); + } public void Stop() { @@ -138,7 +147,7 @@ namespace osu.Game.Screens.Play protected override void Update() { if (!IsPaused.Value) - offsetClock.ProcessFrame(); + userOffsetClock.ProcessFrame(); base.Update(); } From efd7bea7712463013746f1a9295402303d819120 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Apr 2019 17:01:11 +0900 Subject: [PATCH 2/2] Add further xmldoc --- osu.Game/Screens/Play/GameplayClockContainer.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index fc7a9ddd20..5ded375259 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -125,6 +125,13 @@ namespace osu.Game.Screens.Play IsPaused.Value = false; } + /// + /// Seek to a specific time in gameplay. + /// + /// Adjusts for any offsets which have been applied (so the seek may not be the expected point in time on the underlying audio track). + /// + /// + /// The destination time to seek to. public void Seek(double time) { // remove the offset component here because most of the time we want the seek to be aligned to gameplay, not the audio track.