mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 15:44:04 +09:00
Merge branch 'master' into fix-storyboard-sample-pausing
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Timing;
|
||||
|
||||
@ -20,6 +22,11 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
public readonly BindableBool IsPaused = new BindableBool();
|
||||
|
||||
/// <summary>
|
||||
/// All adjustments applied to this clock which don't come from gameplay or mods.
|
||||
/// </summary>
|
||||
public virtual IEnumerable<Bindable<double>> NonGameplayAdjustments => Enumerable.Empty<Bindable<double>>();
|
||||
|
||||
public GameplayClock(IFrameBasedClock underlyingClock)
|
||||
{
|
||||
this.underlyingClock = underlyingClock;
|
||||
@ -29,6 +36,23 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
public double Rate => underlyingClock.Rate;
|
||||
|
||||
/// <summary>
|
||||
/// The rate of gameplay when playback is at 100%.
|
||||
/// This excludes any seeking / user adjustments.
|
||||
/// </summary>
|
||||
public double TrueGameplayRate
|
||||
{
|
||||
get
|
||||
{
|
||||
double baseRate = Rate;
|
||||
|
||||
foreach (var adjustment in NonGameplayAdjustments)
|
||||
baseRate /= adjustment.Value;
|
||||
|
||||
return baseRate;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRunning => underlyingClock.IsRunning;
|
||||
|
||||
/// <summary>
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@ -50,9 +51,11 @@ namespace osu.Game.Screens.Play
|
||||
/// <summary>
|
||||
/// The final clock which is exposed to underlying components.
|
||||
/// </summary>
|
||||
[Cached]
|
||||
public GameplayClock GameplayClock => localGameplayClock;
|
||||
|
||||
[Cached(typeof(GameplayClock))]
|
||||
[Cached(typeof(ISamplePlaybackDisabler))]
|
||||
public readonly GameplayClock GameplayClock;
|
||||
private readonly LocalGameplayClock localGameplayClock;
|
||||
|
||||
private Bindable<double> userAudioOffset;
|
||||
|
||||
@ -80,7 +83,7 @@ namespace osu.Game.Screens.Play
|
||||
userOffsetClock = new HardwareCorrectionOffsetClock(platformOffsetClock);
|
||||
|
||||
// the clock to be exposed via DI to children.
|
||||
GameplayClock = new GameplayClock(userOffsetClock);
|
||||
localGameplayClock = new LocalGameplayClock(userOffsetClock);
|
||||
|
||||
GameplayClock.IsPaused.BindTo(IsPaused);
|
||||
}
|
||||
@ -201,7 +204,9 @@ namespace osu.Game.Screens.Play
|
||||
protected override void Update()
|
||||
{
|
||||
if (!IsPaused.Value)
|
||||
{
|
||||
userOffsetClock.ProcessFrame();
|
||||
}
|
||||
|
||||
base.Update();
|
||||
}
|
||||
@ -216,6 +221,9 @@ namespace osu.Game.Screens.Play
|
||||
track.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust);
|
||||
track.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate);
|
||||
|
||||
localGameplayClock.MutableNonGameplayAdjustments.Add(pauseFreqAdjust);
|
||||
localGameplayClock.MutableNonGameplayAdjustments.Add(UserPlaybackRate);
|
||||
|
||||
speedAdjustmentsApplied = true;
|
||||
}
|
||||
|
||||
@ -232,9 +240,24 @@ namespace osu.Game.Screens.Play
|
||||
track.RemoveAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust);
|
||||
track.RemoveAdjustment(AdjustableProperty.Tempo, UserPlaybackRate);
|
||||
|
||||
localGameplayClock.MutableNonGameplayAdjustments.Remove(pauseFreqAdjust);
|
||||
localGameplayClock.MutableNonGameplayAdjustments.Remove(UserPlaybackRate);
|
||||
|
||||
speedAdjustmentsApplied = false;
|
||||
}
|
||||
|
||||
private class LocalGameplayClock : GameplayClock
|
||||
{
|
||||
public readonly List<Bindable<double>> MutableNonGameplayAdjustments = new List<Bindable<double>>();
|
||||
|
||||
public override IEnumerable<Bindable<double>> NonGameplayAdjustments => MutableNonGameplayAdjustments;
|
||||
|
||||
public LocalGameplayClock(FramedOffsetClock underlyingClock)
|
||||
: base(underlyingClock)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private class HardwareCorrectionOffsetClock : FramedOffsetClock
|
||||
{
|
||||
// we always want to apply the same real-time offset, so it should be adjusted by the difference in playback rate (from realtime) to achieve this.
|
||||
|
@ -8,7 +8,7 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows a component to disable sample playback dynamically as required.
|
||||
/// Handled by <see cref="SkinnableSound"/>.
|
||||
/// Handled by <see cref="PausableSkinnableSound"/>.
|
||||
/// </summary>
|
||||
public interface ISamplePlaybackDisabler
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play
|
||||
AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke());
|
||||
AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke());
|
||||
|
||||
AddInternal(pauseLoop = new UnpausableSkinnableSound(new SampleInfo("pause-loop"))
|
||||
AddInternal(pauseLoop = new SkinnableSound(new SampleInfo("pause-loop"))
|
||||
{
|
||||
Looping = true,
|
||||
Volume = { Value = 0 }
|
||||
@ -54,15 +54,5 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
pauseLoop.VolumeTo(0, TRANSITION_DURATION, Easing.OutQuad).Finally(_ => pauseLoop.Stop());
|
||||
}
|
||||
|
||||
private class UnpausableSkinnableSound : SkinnableSound
|
||||
{
|
||||
protected override bool PlayWhenPaused => true;
|
||||
|
||||
public UnpausableSkinnableSound(SampleInfo sampleInfo)
|
||||
: base(sampleInfo)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user