From 2dbc275bb8e27cab2370eff682422a1be1d1fc8c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Nov 2024 17:54:05 +0900 Subject: [PATCH 1/4] Make quick restart even faster --- osu.Game/Screens/Play/PlayerLoader.cs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 9b4bf7d63365..51268e5dcedb 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -51,6 +51,8 @@ public partial class PlayerLoader : ScreenWithBeatmapBackground public override bool? AllowGlobalTrackControl => false; + public override float BackgroundParallaxAmount => quickRestart ? 0 : 1; + // Here because IsHovered will not update unless we do so. public override bool HandlePositionalInput => true; @@ -387,7 +389,7 @@ protected override void Update() // We need to perform this check here rather than in OnHover as any number of children of VisualSettings // may also be handling the hover events. - if (inputManager.HoveredDrawables.Contains(VisualSettings)) + if (inputManager.HoveredDrawables.Contains(VisualSettings) || quickRestart) { // Preview user-defined background dim and blur when hovered on the visual settings panel. ApplyToBackground(b => @@ -458,8 +460,9 @@ private void contentIn(double delayBeforeSideDisplays = 0) if (quickRestart) { - prepareNewPlayer(); - content.ScaleTo(1, 650, Easing.OutQuint); + // A slight delay is added here to avoid an awkward stutter during the initial animation. + Scheduler.AddDelayed(prepareNewPlayer, 100); + content.ScaleTo(1); } else { @@ -467,15 +470,15 @@ private void contentIn(double delayBeforeSideDisplays = 0) .ScaleTo(1, 650, Easing.OutQuint) .Then() .Schedule(prepareNewPlayer); - } - using (BeginDelayedSequence(delayBeforeSideDisplays)) - { - settingsScroll.FadeInFromZero(500, Easing.Out) - .MoveToX(0, 500, Easing.OutQuint); + using (BeginDelayedSequence(delayBeforeSideDisplays)) + { + settingsScroll.FadeInFromZero(500, Easing.Out) + .MoveToX(0, 500, Easing.OutQuint); - disclaimers.FadeInFromZero(500, Easing.Out) - .MoveToX(0, 500, Easing.OutQuint); + disclaimers.FadeInFromZero(500, Easing.Out) + .MoveToX(0, 500, Easing.OutQuint); + } } AddRangeInternal(new[] @@ -565,7 +568,7 @@ private void pushWhenLoaded() else this.Exit(); }); - }, 500); + }, quickRestart ? 0 : 500); } private void cancelLoad() From f597568476bdce8930bbdb30fa6fc937c1f2964f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Nov 2024 01:23:21 +0900 Subject: [PATCH 2/4] Fix test failure due to restart happening too fast --- osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 1949808dfe51..cf813cfd5154 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -523,7 +523,7 @@ public void TestQuickRetry() AddUntilStep("restart completed", () => getCurrentPlayer() != null && getCurrentPlayer() != previousPlayer); AddStep("release quick retry key", () => InputManager.ReleaseKey(Key.Tilde)); - AddUntilStep("wait for player", () => getCurrentPlayer()?.LoadState == LoadState.Ready); + AddUntilStep("wait for player", () => getCurrentPlayer()?.LoadState >= LoadState.Ready); AddUntilStep("time reached zero", () => getCurrentPlayer()?.GameplayClockContainer.CurrentTime > 0); AddUntilStep("skip button not visible", () => !checkSkipButtonVisible()); From 9849a88eefc7d9e8534eba47ac230b947b1cb0c1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Nov 2024 18:27:26 +0900 Subject: [PATCH 3/4] Adjust transition further to avoid brief "jumpscare" display of metadata --- osu.Game/Screens/Play/PlayerLoader.cs | 86 +++++++++++++++++++-------- 1 file changed, 60 insertions(+), 26 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 51268e5dcedb..5843c28f3a80 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -10,6 +10,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Transforms; using osu.Framework.Input; @@ -88,9 +89,13 @@ public partial class PlayerLoader : ScreenWithBeatmapBackground private SkinnableSound sampleRestart = null!; + private Box? quickRestartBlackLayer; + [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); + private const double quick_restart_initial_delay = 500; + protected bool BackgroundBrightnessReduction { set @@ -307,6 +312,9 @@ public override void OnSuspending(ScreenTransitionEvent e) { base.OnSuspending(e); + quickRestartBlackLayer?.FadeOut(500, Easing.OutQuint); + quickRestartBlackLayer = null; + BackgroundBrightnessReduction = false; // we're moving to player, so a period of silence is upcoming. @@ -350,7 +358,14 @@ protected override void LogoArriving(OsuLogo logo, bool resuming) if (!resuming) logo.MoveTo(new Vector2(0.5f), duration, Easing.OutQuint); logo.ScaleTo(new Vector2(0.15f), duration, Easing.OutQuint); - logo.FadeIn(350); + + if (quickRestart) + { + logo.Delay(quick_restart_initial_delay) + .FadeIn(350); + } + else + logo.FadeIn(350); Scheduler.AddDelayed(() => { @@ -456,17 +471,33 @@ private void contentIn(double delayBeforeSideDisplays = 0) { MetadataInfo.Loading = true; - content.FadeInFromZero(500, Easing.OutQuint); - if (quickRestart) { - // A slight delay is added here to avoid an awkward stutter during the initial animation. - Scheduler.AddDelayed(prepareNewPlayer, 100); - content.ScaleTo(1); + // A quick restart starts by triggering a fade to black + AddInternal(quickRestartBlackLayer = new Box + { + Colour = Color4.Black, + RelativeSizeAxes = Axes.Both, + Depth = float.MaxValue + }); + + quickRestartBlackLayer + .Delay(50) + .FadeOut(5000, Easing.OutQuint); + + prepareNewPlayer(); + + content + .Delay(quick_restart_initial_delay) + .ScaleTo(1) + .FadeInFromZero(500, Easing.OutQuint); } else { + content.FadeInFromZero(500, Easing.OutQuint); + content + .ScaleTo(0.7f) .ScaleTo(1, 650, Easing.OutQuint) .Then() .Schedule(prepareNewPlayer); @@ -542,33 +573,36 @@ private void pushWhenLoaded() highPerformanceSession ??= highPerformanceSessionManager?.BeginSession(); scheduledPushPlayer = Scheduler.AddDelayed(() => - { - // ensure that once we have reached this "point of no return", readyForPush will be false for all future checks (until a new player instance is prepared). - var consumedPlayer = consumePlayer(); + { + // ensure that once we have reached this "point of no return", readyForPush will be false for all future checks (until a new player instance is prepared). + var consumedPlayer = consumePlayer(); - ContentOut(); + ContentOut(); - TransformSequence pushSequence = this.Delay(0); + TransformSequence pushSequence = this.Delay(0); - // This goes hand-in-hand with the restoration of low pass filter in contentOut(). - this.TransformBindableTo(volumeAdjustment, 0, CONTENT_OUT_DURATION, Easing.OutCubic); + // This goes hand-in-hand with the restoration of low pass filter in contentOut(). + this.TransformBindableTo(volumeAdjustment, 0, CONTENT_OUT_DURATION, Easing.OutCubic); - pushSequence.Schedule(() => - { - if (!this.IsCurrentScreen()) return; + pushSequence.Schedule(() => + { + if (!this.IsCurrentScreen()) return; - LoadTask = null; + LoadTask = null; - // By default, we want to load the player and never be returned to. - // Note that this may change if the player we load requested a re-run. - ValidForResume = false; + // By default, we want to load the player and never be returned to. + // Note that this may change if the player we load requested a re-run. + ValidForResume = false; - if (consumedPlayer.LoadedBeatmapSuccessfully) - this.Push(consumedPlayer); - else - this.Exit(); - }); - }, quickRestart ? 0 : 500); + if (consumedPlayer.LoadedBeatmapSuccessfully) + this.Push(consumedPlayer); + else + this.Exit(); + }); + }, + // When a quick restart is activated, the metadata content will display some time later if it's taking too long. + // To avoid it appearing too briefly, if it begins to fade in let's induce a standard delay. + quickRestart && content.Alpha == 0 ? 0 : 500); } private void cancelLoad() From 36d48a01c841e9997fbc8a46adaa1962ed7f9c06 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Nov 2024 19:33:34 +0900 Subject: [PATCH 4/4] Add missing expire call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Screens/Play/PlayerLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 5843c28f3a80..cf867e31f8d5 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -312,7 +312,7 @@ public override void OnSuspending(ScreenTransitionEvent e) { base.OnSuspending(e); - quickRestartBlackLayer?.FadeOut(500, Easing.OutQuint); + quickRestartBlackLayer?.FadeOut(500, Easing.OutQuint).Expire(); quickRestartBlackLayer = null; BackgroundBrightnessReduction = false;