mirror of
https://github.com/ppy/osu.git
synced 2025-01-06 04:13:11 +08:00
Merge pull request #4583 from peppy/fix-offset-seek-handling
Fix gameplay offset handling on seeks
This commit is contained in:
commit
67a03bbc90
@ -36,6 +36,8 @@ namespace osu.Game.Screens.Play
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly DecoupleableInterpolatingFramedClock adjustableClock;
|
private readonly DecoupleableInterpolatingFramedClock adjustableClock;
|
||||||
|
|
||||||
|
private readonly double gameplayStartTime;
|
||||||
|
|
||||||
public readonly Bindable<double> UserPlaybackRate = new BindableDouble(1)
|
public readonly Bindable<double> UserPlaybackRate = new BindableDouble(1)
|
||||||
{
|
{
|
||||||
Default = 1,
|
Default = 1,
|
||||||
@ -52,11 +54,14 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
private Bindable<double> userAudioOffset;
|
private Bindable<double> userAudioOffset;
|
||||||
|
|
||||||
private readonly FramedOffsetClock offsetClock;
|
private readonly FramedOffsetClock userOffsetClock;
|
||||||
|
|
||||||
|
private readonly FramedOffsetClock platformOffsetClock;
|
||||||
|
|
||||||
public GameplayClockContainer(WorkingBeatmap beatmap, double gameplayStartTime)
|
public GameplayClockContainer(WorkingBeatmap beatmap, double gameplayStartTime)
|
||||||
{
|
{
|
||||||
this.beatmap = beatmap;
|
this.beatmap = beatmap;
|
||||||
|
this.gameplayStartTime = gameplayStartTime;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
@ -64,30 +69,31 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
|
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.
|
// 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.
|
// 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.
|
// 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.
|
// the clock to be exposed via DI to children.
|
||||||
GameplayClock = new GameplayClock(offsetClock);
|
GameplayClock = new GameplayClock(userOffsetClock);
|
||||||
|
|
||||||
GameplayClock.IsPaused.BindTo(IsPaused);
|
GameplayClock.IsPaused.BindTo(IsPaused);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private double totalOffset => userOffsetClock.Offset + platformOffsetClock.Offset;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
{
|
{
|
||||||
userAudioOffset = config.GetBindable<double>(OsuSetting.AudioOffset);
|
userAudioOffset = config.GetBindable<double>(OsuSetting.AudioOffset);
|
||||||
userAudioOffset.BindValueChanged(offset => offsetClock.Offset = offset.NewValue, true);
|
userAudioOffset.BindValueChanged(offset => userOffsetClock.Offset = offset.NewValue, true);
|
||||||
|
|
||||||
UserPlaybackRate.ValueChanged += _ => updateRate();
|
UserPlaybackRate.ValueChanged += _ => updateRate();
|
||||||
|
|
||||||
|
Seek(Math.Min(0, gameplayStartTime - beatmap.BeatmapInfo.AudioLeadIn));
|
||||||
|
adjustableClock.ProcessFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Restart()
|
public void Restart()
|
||||||
@ -104,9 +110,7 @@ namespace osu.Game.Screens.Play
|
|||||||
this.Delay(750).Schedule(() =>
|
this.Delay(750).Schedule(() =>
|
||||||
{
|
{
|
||||||
if (!IsPaused.Value)
|
if (!IsPaused.Value)
|
||||||
{
|
Start();
|
||||||
adjustableClock.Start();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -121,7 +125,19 @@ namespace osu.Game.Screens.Play
|
|||||||
IsPaused.Value = false;
|
IsPaused.Value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Seek(double time) => adjustableClock.Seek(time);
|
/// <summary>
|
||||||
|
/// Seek to a specific time in gameplay.
|
||||||
|
/// <remarks>
|
||||||
|
/// Adjusts for any offsets which have been applied (so the seek may not be the expected point in time on the underlying audio track).
|
||||||
|
/// </remarks>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The destination time to seek to.</param>
|
||||||
|
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()
|
public void Stop()
|
||||||
{
|
{
|
||||||
@ -138,7 +154,7 @@ namespace osu.Game.Screens.Play
|
|||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
if (!IsPaused.Value)
|
if (!IsPaused.Value)
|
||||||
offsetClock.ProcessFrame();
|
userOffsetClock.ProcessFrame();
|
||||||
|
|
||||||
base.Update();
|
base.Update();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user