From 1cf16038a708f1c586b6405b58bb3d70082cf2c5 Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Tue, 16 Jun 2020 14:54:05 +0100 Subject: [PATCH 01/30] Create IApplicableToSample --- osu.Game/Rulesets/Mods/IApplicableToSample.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 osu.Game/Rulesets/Mods/IApplicableToSample.cs diff --git a/osu.Game/Rulesets/Mods/IApplicableToSample.cs b/osu.Game/Rulesets/Mods/IApplicableToSample.cs new file mode 100644 index 0000000000..559d127cfc --- /dev/null +++ b/osu.Game/Rulesets/Mods/IApplicableToSample.cs @@ -0,0 +1,15 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Audio.Sample; + +namespace osu.Game.Rulesets.Mods +{ + /// + /// An interface for mods that make adjustments to a sample. + /// + public interface IApplicableToSample : IApplicableMod + { + void ApplyToSample(SampleChannel sample); + } +} From 9f4f3ce2cc055867cbfe58f723c334f7b08b1448 Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Tue, 16 Jun 2020 14:54:50 +0100 Subject: [PATCH 02/30] Handle IApplicableToSample mods --- .../Storyboards/Drawables/DrawableStoryboardSample.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index 8292b02068..2b9c66d2e6 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -1,11 +1,14 @@ // Copyright (c) ppy Pty Ltd . 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.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; namespace osu.Game.Storyboards.Drawables { @@ -28,12 +31,17 @@ namespace osu.Game.Storyboards.Drawables } [BackgroundDependencyLoader] - private void load(IBindable beatmap) + private void load(IBindable beatmap, IBindable> mods) { channel = beatmap.Value.Skin.GetSample(sampleInfo); if (channel != null) + { channel.Volume.Value = sampleInfo.Volume / 100.0; + + foreach (var mod in mods.Value.OfType()) + mod.ApplyToSample(channel); + } } protected override void Update() From 4138f6119f24ce50991a64c89cd91e4c5fa28a23 Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Tue, 16 Jun 2020 14:58:23 +0100 Subject: [PATCH 03/30] Update rate adjust mods to also use IApplicableToSample --- osu.Game/Rulesets/Mods/ModRateAdjust.cs | 8 +++++++- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index cb2ff149f1..ecd625c3b4 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -2,12 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Audio; +using osu.Framework.Audio.Sample; using osu.Framework.Audio.Track; using osu.Framework.Bindables; namespace osu.Game.Rulesets.Mods { - public abstract class ModRateAdjust : Mod, IApplicableToTrack + public abstract class ModRateAdjust : Mod, IApplicableToTrack, IApplicableToSample { public abstract BindableNumber SpeedChange { get; } @@ -16,6 +17,11 @@ namespace osu.Game.Rulesets.Mods track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange); } + public virtual void ApplyToSample(SampleChannel sample) + { + sample.AddAdjustment(AdjustableProperty.Frequency, SpeedChange); + } + public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:N2}x"; } } diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index df059eef7d..352e3ae915 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -10,10 +10,11 @@ using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.Objects; +using osu.Framework.Audio.Sample; namespace osu.Game.Rulesets.Mods { - public abstract class ModTimeRamp : Mod, IUpdatableByPlayfield, IApplicableToBeatmap, IApplicableToTrack + public abstract class ModTimeRamp : Mod, IUpdatableByPlayfield, IApplicableToBeatmap, IApplicableToTrack, IApplicableToSample { /// /// The point in the beatmap at which the final ramping rate should be reached. @@ -58,6 +59,11 @@ namespace osu.Game.Rulesets.Mods AdjustPitch.TriggerChange(); } + public void ApplyToSample(SampleChannel sample) + { + sample.AddAdjustment(AdjustableProperty.Frequency, SpeedChange); + } + public virtual void ApplyToBeatmap(IBeatmap beatmap) { HitObject lastObject = beatmap.HitObjects.LastOrDefault(); From c3e268616fdd1b44cc146f0a07b7e05cd788866f Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Wed, 17 Jun 2020 11:43:32 +0100 Subject: [PATCH 04/30] Implement grouping interface IApplicableToAudio --- osu.Game/Rulesets/Mods/IApplicableToAudio.cs | 10 ++++++++++ osu.Game/Rulesets/Mods/ModRateAdjust.cs | 2 +- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Rulesets/Mods/IApplicableToAudio.cs diff --git a/osu.Game/Rulesets/Mods/IApplicableToAudio.cs b/osu.Game/Rulesets/Mods/IApplicableToAudio.cs new file mode 100644 index 0000000000..40e13764c6 --- /dev/null +++ b/osu.Game/Rulesets/Mods/IApplicableToAudio.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace osu.Game.Rulesets.Mods +{ + public interface IApplicableToAudio : IApplicableToTrack, IApplicableToSample + { + } +} diff --git a/osu.Game/Rulesets/Mods/ModRateAdjust.cs b/osu.Game/Rulesets/Mods/ModRateAdjust.cs index ecd625c3b4..874384686f 100644 --- a/osu.Game/Rulesets/Mods/ModRateAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModRateAdjust.cs @@ -8,7 +8,7 @@ using osu.Framework.Bindables; namespace osu.Game.Rulesets.Mods { - public abstract class ModRateAdjust : Mod, IApplicableToTrack, IApplicableToSample + public abstract class ModRateAdjust : Mod, IApplicableToAudio { public abstract BindableNumber SpeedChange { get; } diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 352e3ae915..cbd07efa97 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -14,7 +14,7 @@ using osu.Framework.Audio.Sample; namespace osu.Game.Rulesets.Mods { - public abstract class ModTimeRamp : Mod, IUpdatableByPlayfield, IApplicableToBeatmap, IApplicableToTrack, IApplicableToSample + public abstract class ModTimeRamp : Mod, IUpdatableByPlayfield, IApplicableToBeatmap, IApplicableToAudio { /// /// The point in the beatmap at which the final ramping rate should be reached. From bed5e857df7d2af44ae5f4bbfa304f04be741da1 Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Wed, 17 Jun 2020 14:49:55 +0100 Subject: [PATCH 05/30] Add missing license header and remove unused usings --- osu.Game/Rulesets/Mods/IApplicableToAudio.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Mods/IApplicableToAudio.cs b/osu.Game/Rulesets/Mods/IApplicableToAudio.cs index 40e13764c6..901da7af55 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToAudio.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToAudio.cs @@ -1,6 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Text; +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. namespace osu.Game.Rulesets.Mods { From f04f2d21755103041272a66484730a5ae8687cfc Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Thu, 18 Jun 2020 21:46:32 +0100 Subject: [PATCH 06/30] Add test scene --- .../Gameplay/TestSceneStoryboardSamples.cs | 57 +++++++++++++++++++ .../Drawables/DrawableStoryboardSample.cs | 17 +++--- 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 552d163b2f..60911d6792 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -10,9 +10,12 @@ using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.IO.Stores; using osu.Framework.Testing; +using osu.Framework.Timing; using osu.Game.Audio; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens.Play; using osu.Game.Skinning; using osu.Game.Storyboards; @@ -70,6 +73,37 @@ namespace osu.Game.Tests.Gameplay AddUntilStep("sample playback succeeded", () => sample.LifetimeEnd < double.MaxValue); } + [Test] + public void TestSamplePlaybackWithRateMods() + { + GameplayClockContainer gameplayContainer = null; + TestDrawableStoryboardSample sample = null; + + OsuModDoubleTime doubleTimeMod = null; + + AddStep("create container", () => + { + var beatmap = Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); + + Add(gameplayContainer = new GameplayClockContainer(beatmap, new[] { doubleTimeMod = new OsuModDoubleTime() }, 0)); + + SelectedMods.Value = new[] { doubleTimeMod }; + Beatmap.Value = new TestCustomSkinWorkingBeatmap(beatmap.Beatmap, gameplayContainer.GameplayClock, Audio); + }); + + AddStep("create storyboard sample", () => + { + gameplayContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1)) + { + Clock = gameplayContainer.GameplayClock + }); + }); + + AddStep("start", () => gameplayContainer.Start()); + + AddAssert("sample playback rate matches mod rates", () => sample.TestChannel.AggregateFrequency.Value == doubleTimeMod.SpeedChange.Value); + } + private class TestSkin : LegacySkin { public TestSkin(string resourceName, AudioManager audioManager) @@ -99,5 +133,28 @@ namespace osu.Game.Tests.Gameplay { } } + + private class TestCustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap + { + private readonly AudioManager audio; + + public TestCustomSkinWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock referenceClock, AudioManager audio) + : base(beatmap, null, referenceClock, audio) + { + this.audio = audio; + } + + protected override ISkin GetSkin() => new TestSkin("test-sample", audio); + } + + private class TestDrawableStoryboardSample : DrawableStoryboardSample + { + public TestDrawableStoryboardSample(StoryboardSampleInfo sampleInfo) + : base(sampleInfo) + { + } + + public SampleChannel TestChannel => Channel; + } } } diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index 2b9c66d2e6..04df46410e 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -20,7 +20,8 @@ namespace osu.Game.Storyboards.Drawables private const double allowable_late_start = 100; private readonly StoryboardSampleInfo sampleInfo; - private SampleChannel channel; + + protected SampleChannel Channel; public override bool RemoveWhenNotAlive => false; @@ -33,14 +34,14 @@ namespace osu.Game.Storyboards.Drawables [BackgroundDependencyLoader] private void load(IBindable beatmap, IBindable> mods) { - channel = beatmap.Value.Skin.GetSample(sampleInfo); + Channel = beatmap.Value.Skin.GetSample(sampleInfo); - if (channel != null) + if (Channel != null) { - channel.Volume.Value = sampleInfo.Volume / 100.0; + Channel.Volume.Value = sampleInfo.Volume / 100.0; foreach (var mod in mods.Value.OfType()) - mod.ApplyToSample(channel); + mod.ApplyToSample(Channel); } } @@ -52,7 +53,7 @@ namespace osu.Game.Storyboards.Drawables if (Time.Current < sampleInfo.StartTime) { // We've rewound before the start time of the sample - channel?.Stop(); + Channel?.Stop(); // In the case that the user fast-forwards to a point far beyond the start time of the sample, // we want to be able to fall into the if-conditional below (therefore we must not have a life time end) @@ -64,7 +65,7 @@ namespace osu.Game.Storyboards.Drawables // We've passed the start time of the sample. We only play the sample if we're within an allowable range // from the sample's start, to reduce layering if we've been fast-forwarded far into the future if (Time.Current - sampleInfo.StartTime < allowable_late_start) - channel?.Play(); + Channel?.Play(); // In the case that the user rewinds to a point far behind the start time of the sample, // we want to be able to fall into the if-conditional above (therefore we must not have a life time start) @@ -75,7 +76,7 @@ namespace osu.Game.Storyboards.Drawables protected override void Dispose(bool isDisposing) { - channel?.Stop(); + Channel?.Stop(); base.Dispose(isDisposing); } } From 0046cc08e913572866146cebdb512aed9f2ec725 Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Fri, 19 Jun 2020 18:40:36 +0100 Subject: [PATCH 07/30] Add test cases for different mods and rates. Cleanup test scene. --- .../Gameplay/TestSceneStoryboardSamples.cs | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 60911d6792..0803da6678 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -10,9 +10,8 @@ using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.IO.Stores; using osu.Framework.Testing; -using osu.Framework.Timing; using osu.Game.Audio; -using osu.Game.Beatmaps; +using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; @@ -73,26 +72,39 @@ namespace osu.Game.Tests.Gameplay AddUntilStep("sample playback succeeded", () => sample.LifetimeEnd < double.MaxValue); } - [Test] - public void TestSamplePlaybackWithRateMods() + [TestCase(typeof(OsuModDoubleTime), 1.5)] + [TestCase(typeof(OsuModHalfTime), 0.75)] + [TestCase(typeof(ModWindUp), 1.5)] + [TestCase(typeof(ModWindDown), 0.75)] + [TestCase(typeof(OsuModDoubleTime), 2)] + [TestCase(typeof(OsuModHalfTime), 0.5)] + [TestCase(typeof(ModWindUp), 2)] + [TestCase(typeof(ModWindDown), 0.5)] + public void TestSamplePlaybackWithRateMods(Type expectedMod, double expectedRate) { GameplayClockContainer gameplayContainer = null; TestDrawableStoryboardSample sample = null; - OsuModDoubleTime doubleTimeMod = null; + Mod testedMod = Activator.CreateInstance(expectedMod) as Mod; - AddStep("create container", () => + switch (testedMod) { - var beatmap = Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); + case ModRateAdjust m: + m.SpeedChange.Value = expectedRate; + break; - Add(gameplayContainer = new GameplayClockContainer(beatmap, new[] { doubleTimeMod = new OsuModDoubleTime() }, 0)); + case ModTimeRamp m: + m.SpeedChange.Value = expectedRate; + break; + } - SelectedMods.Value = new[] { doubleTimeMod }; - Beatmap.Value = new TestCustomSkinWorkingBeatmap(beatmap.Beatmap, gameplayContainer.GameplayClock, Audio); - }); - - AddStep("create storyboard sample", () => + AddStep("setup storyboard sample", () => { + Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, Audio); + SelectedMods.Value = new[] { testedMod }; + + Add(gameplayContainer = new GameplayClockContainer(Beatmap.Value, SelectedMods.Value, 0)); + gameplayContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1)) { Clock = gameplayContainer.GameplayClock @@ -101,7 +113,7 @@ namespace osu.Game.Tests.Gameplay AddStep("start", () => gameplayContainer.Start()); - AddAssert("sample playback rate matches mod rates", () => sample.TestChannel.AggregateFrequency.Value == doubleTimeMod.SpeedChange.Value); + AddAssert("sample playback rate matches mod rates", () => sample.TestChannel.AggregateFrequency.Value == expectedRate); } private class TestSkin : LegacySkin @@ -138,8 +150,8 @@ namespace osu.Game.Tests.Gameplay { private readonly AudioManager audio; - public TestCustomSkinWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock referenceClock, AudioManager audio) - : base(beatmap, null, referenceClock, audio) + public TestCustomSkinWorkingBeatmap(RulesetInfo ruleset, AudioManager audio) + : base(ruleset, null, audio) { this.audio = audio; } From 1d5084c35554939390b33db0c8d8191e0382724a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 19 Jun 2020 20:11:12 +0200 Subject: [PATCH 08/30] Use {Initial,Final}Rate instead of SpeedChange --- osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 0803da6678..295fcc5b58 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -94,7 +94,7 @@ namespace osu.Game.Tests.Gameplay break; case ModTimeRamp m: - m.SpeedChange.Value = expectedRate; + m.InitialRate.Value = m.FinalRate.Value = expectedRate; break; } From 34476f6c2fa0d1e3ad922e46980fa9133302ee29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 19 Jun 2020 20:12:17 +0200 Subject: [PATCH 09/30] Delegate to base in a more consistent manner --- osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 295fcc5b58..b30870d057 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -113,7 +113,7 @@ namespace osu.Game.Tests.Gameplay AddStep("start", () => gameplayContainer.Start()); - AddAssert("sample playback rate matches mod rates", () => sample.TestChannel.AggregateFrequency.Value == expectedRate); + AddAssert("sample playback rate matches mod rates", () => sample.Channel.AggregateFrequency.Value == expectedRate); } private class TestSkin : LegacySkin @@ -166,7 +166,7 @@ namespace osu.Game.Tests.Gameplay { } - public SampleChannel TestChannel => Channel; + public new SampleChannel Channel => base.Channel; } } } From 53861cdde81dec2aba2edfad6c92d89208a477ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 19 Jun 2020 20:13:43 +0200 Subject: [PATCH 10/30] Privatise setter --- osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index 04df46410e..60cb9b94a6 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -21,7 +21,7 @@ namespace osu.Game.Storyboards.Drawables private readonly StoryboardSampleInfo sampleInfo; - protected SampleChannel Channel; + protected SampleChannel Channel { get; private set; } public override bool RemoveWhenNotAlive => false; From 470d5bfce3497c2c2a7048ee5db8a4a65249b153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 19 Jun 2020 20:15:14 +0200 Subject: [PATCH 11/30] Invert if to reduce nesting --- .../Storyboards/Drawables/DrawableStoryboardSample.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index 60cb9b94a6..8eaf9ac652 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -35,14 +35,13 @@ namespace osu.Game.Storyboards.Drawables private void load(IBindable beatmap, IBindable> mods) { Channel = beatmap.Value.Skin.GetSample(sampleInfo); + if (Channel == null) + return; - if (Channel != null) - { - Channel.Volume.Value = sampleInfo.Volume / 100.0; + Channel.Volume.Value = sampleInfo.Volume / 100.0; - foreach (var mod in mods.Value.OfType()) - mod.ApplyToSample(Channel); - } + foreach (var mod in mods.Value.OfType()) + mod.ApplyToSample(Channel); } protected override void Update() From e827b14abf5212aa0809256b4830456acda994e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 21 Jun 2020 16:40:05 +0200 Subject: [PATCH 12/30] Add LayeredHitSamples skin config lookup --- osu.Game/Skinning/GlobalSkinConfiguration.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Skinning/GlobalSkinConfiguration.cs b/osu.Game/Skinning/GlobalSkinConfiguration.cs index 8774fe5a97..d405702ea5 100644 --- a/osu.Game/Skinning/GlobalSkinConfiguration.cs +++ b/osu.Game/Skinning/GlobalSkinConfiguration.cs @@ -5,6 +5,7 @@ namespace osu.Game.Skinning { public enum GlobalSkinConfiguration { - AnimationFramerate + AnimationFramerate, + LayeredHitSounds, } } From c5049b51c5835ab6950d1f9244d0d355157439a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 21 Jun 2020 16:43:21 +0200 Subject: [PATCH 13/30] Mark normal-hitnormal sample as layered --- .../Objects/Legacy/ConvertHitObjectParser.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 9e936c7717..77075b2abe 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -12,6 +12,7 @@ using System.Linq; using JetBrains.Annotations; using osu.Framework.Utils; using osu.Game.Beatmaps.Legacy; +using osu.Game.Skinning; namespace osu.Game.Rulesets.Objects.Legacy { @@ -356,7 +357,10 @@ namespace osu.Game.Rulesets.Objects.Legacy Bank = bankInfo.Normal, Name = HitSampleInfo.HIT_NORMAL, Volume = bankInfo.Volume, - CustomSampleBank = bankInfo.CustomSampleBank + CustomSampleBank = bankInfo.CustomSampleBank, + // if the sound type doesn't have the Normal flag set, attach it anyway as a layered sample. + // None also counts as a normal non-layered sample: https://osu.ppy.sh/help/wiki/osu!_File_Formats/Osu_(file_format)#hitsounds + IsLayered = type != LegacyHitSoundType.None && !type.HasFlag(LegacyHitSoundType.Normal) } }; @@ -409,7 +413,7 @@ namespace osu.Game.Rulesets.Objects.Legacy public SampleBankInfo Clone() => (SampleBankInfo)MemberwiseClone(); } - internal class LegacyHitSampleInfo : HitSampleInfo + public class LegacyHitSampleInfo : HitSampleInfo { private int customSampleBank; @@ -424,6 +428,15 @@ namespace osu.Game.Rulesets.Objects.Legacy Suffix = value.ToString(); } } + + /// + /// Whether this hit sample is layered. + /// + /// + /// Layered hit samples are automatically added in all modes (except osu!mania), but can be disabled + /// using the skin config option. + /// + public bool IsLayered { get; set; } } private class FileHitSampleInfo : LegacyHitSampleInfo From c7d2ce12eb1cbf0cd6a8f5d1c72ac482d6ed62a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 21 Jun 2020 18:52:15 +0200 Subject: [PATCH 14/30] Add failing test cases --- ...a-hitobject-beatmap-custom-sample-bank.osu | 10 ++++ ...a-hitobject-beatmap-normal-sample-bank.osu | 10 ++++ .../TestSceneManiaHitObjectSamples.cs | 49 +++++++++++++++ .../Gameplay/TestSceneHitObjectSamples.cs | 60 +++++++++++++++++++ .../hitobject-beatmap-custom-sample-bank.osu | 7 +++ .../Tests/Beatmaps/HitObjectSampleTest.cs | 12 +++- 6 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Mania.Tests/Resources/SampleLookups/mania-hitobject-beatmap-custom-sample-bank.osu create mode 100644 osu.Game.Rulesets.Mania.Tests/Resources/SampleLookups/mania-hitobject-beatmap-normal-sample-bank.osu create mode 100644 osu.Game.Rulesets.Mania.Tests/TestSceneManiaHitObjectSamples.cs create mode 100644 osu.Game.Tests/Resources/SampleLookups/hitobject-beatmap-custom-sample-bank.osu diff --git a/osu.Game.Rulesets.Mania.Tests/Resources/SampleLookups/mania-hitobject-beatmap-custom-sample-bank.osu b/osu.Game.Rulesets.Mania.Tests/Resources/SampleLookups/mania-hitobject-beatmap-custom-sample-bank.osu new file mode 100644 index 0000000000..4f8e1b68dd --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/Resources/SampleLookups/mania-hitobject-beatmap-custom-sample-bank.osu @@ -0,0 +1,10 @@ +osu file format v14 + +[General] +Mode: 3 + +[TimingPoints] +0,300,4,0,2,100,1,0 + +[HitObjects] +444,320,1000,5,2,0:0:0:0: diff --git a/osu.Game.Rulesets.Mania.Tests/Resources/SampleLookups/mania-hitobject-beatmap-normal-sample-bank.osu b/osu.Game.Rulesets.Mania.Tests/Resources/SampleLookups/mania-hitobject-beatmap-normal-sample-bank.osu new file mode 100644 index 0000000000..f22901e304 --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/Resources/SampleLookups/mania-hitobject-beatmap-normal-sample-bank.osu @@ -0,0 +1,10 @@ +osu file format v14 + +[General] +Mode: 3 + +[TimingPoints] +0,300,4,0,2,100,1,0 + +[HitObjects] +444,320,1000,5,1,0:0:0:0: diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaHitObjectSamples.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaHitObjectSamples.cs new file mode 100644 index 0000000000..0d726e1a50 --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaHitObjectSamples.cs @@ -0,0 +1,49 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Reflection; +using NUnit.Framework; +using osu.Framework.IO.Stores; +using osu.Game.Tests.Beatmaps; + +namespace osu.Game.Rulesets.Mania.Tests +{ + public class TestSceneManiaHitObjectSamples : HitObjectSampleTest + { + protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); + protected override IResourceStore Resources => new DllResourceStore(Assembly.GetAssembly(typeof(TestSceneManiaHitObjectSamples))); + + /// + /// Tests that when a normal sample bank is used, the normal hitsound will be looked up. + /// + [Test] + public void TestManiaHitObjectNormalSampleBank() + { + const string expected_sample = "normal-hitnormal2"; + + SetupSkins(expected_sample, expected_sample); + + CreateTestWithBeatmap("mania-hitobject-beatmap-normal-sample-bank.osu"); + + AssertBeatmapLookup(expected_sample); + } + + /// + /// Tests that when a custom sample bank is used, layered hitsounds are not played + /// (only the sample from the custom bank is looked up). + /// + [Test] + public void TestManiaHitObjectCustomSampleBank() + { + const string expected_sample = "normal-hitwhistle2"; + const string unwanted_sample = "normal-hitnormal2"; + + SetupSkins(expected_sample, unwanted_sample); + + CreateTestWithBeatmap("mania-hitobject-beatmap-custom-sample-bank.osu"); + + AssertBeatmapLookup(expected_sample); + AssertNoLookup(unwanted_sample); + } + } +} diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs index ef6efb7fec..737946e1e0 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs @@ -6,6 +6,7 @@ using osu.Framework.IO.Stores; using osu.Framework.Testing; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; +using osu.Game.Skinning; using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Resources; @@ -167,5 +168,64 @@ namespace osu.Game.Tests.Gameplay AssertBeatmapLookup(expected_sample); } + + /// + /// Tests that when a custom sample bank is used, both the normal and additional sounds will be looked up. + /// + [Test] + public void TestHitObjectCustomSampleBank() + { + string[] expectedSamples = + { + "normal-hitnormal2", + "normal-hitwhistle2" + }; + + SetupSkins(expectedSamples[0], expectedSamples[1]); + + CreateTestWithBeatmap("hitobject-beatmap-custom-sample-bank.osu"); + + AssertBeatmapLookup(expectedSamples[0]); + AssertUserLookup(expectedSamples[1]); + } + + /// + /// Tests that when a custom sample bank is used, but is disabled, + /// only the additional sound will be looked up. + /// + [Test] + public void TestHitObjectCustomSampleBankWithoutLayered() + { + const string expected_sample = "normal-hitwhistle2"; + const string unwanted_sample = "normal-hitnormal2"; + + SetupSkins(expected_sample, unwanted_sample); + disableLayeredHitSounds(); + + CreateTestWithBeatmap("hitobject-beatmap-custom-sample-bank.osu"); + + AssertBeatmapLookup(expected_sample); + AssertNoLookup(unwanted_sample); + } + + /// + /// Tests that when a normal sample bank is used and is disabled, + /// the normal sound will be looked up anyway. + /// + [Test] + public void TestHitObjectNormalSampleBankWithoutLayered() + { + const string expected_sample = "normal-hitnormal"; + + SetupSkins(expected_sample, expected_sample); + disableLayeredHitSounds(); + + CreateTestWithBeatmap("hitobject-beatmap-sample.osu"); + + AssertBeatmapLookup(expected_sample); + } + + private void disableLayeredHitSounds() + => AddStep("set LayeredHitSounds to false", () => Skin.Configuration.ConfigDictionary[GlobalSkinConfiguration.LayeredHitSounds.ToString()] = "0"); } } diff --git a/osu.Game.Tests/Resources/SampleLookups/hitobject-beatmap-custom-sample-bank.osu b/osu.Game.Tests/Resources/SampleLookups/hitobject-beatmap-custom-sample-bank.osu new file mode 100644 index 0000000000..c50c921839 --- /dev/null +++ b/osu.Game.Tests/Resources/SampleLookups/hitobject-beatmap-custom-sample-bank.osu @@ -0,0 +1,7 @@ +osu file format v14 + +[TimingPoints] +0,300,4,0,2,100,1,0 + +[HitObjects] +444,320,1000,5,2,0:0:0:0: diff --git a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs index b4ce322165..ab4fb38657 100644 --- a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs +++ b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs @@ -24,6 +24,10 @@ namespace osu.Game.Tests.Beatmaps public abstract class HitObjectSampleTest : PlayerTestScene { protected abstract IResourceStore Resources { get; } + protected LegacySkin Skin { get; private set; } + + [Resolved] + private RulesetStore rulesetStore { get; set; } private readonly SkinInfo userSkinInfo = new SkinInfo(); @@ -64,6 +68,9 @@ namespace osu.Game.Tests.Beatmaps { using (var reader = new LineBufferedReader(Resources.GetStream($"Resources/SampleLookups/{filename}"))) currentTestBeatmap = Decoder.GetDecoder(reader).Decode(reader); + + // populate ruleset for beatmap converters that require it to be present. + currentTestBeatmap.BeatmapInfo.Ruleset = rulesetStore.GetRuleset(currentTestBeatmap.BeatmapInfo.RulesetID); }); }); } @@ -91,7 +98,7 @@ namespace osu.Game.Tests.Beatmaps }; // Need to refresh the cached skin source to refresh the skin resource store. - dependencies.SkinSource = new SkinProvidingContainer(new LegacySkin(userSkinInfo, userSkinResourceStore, Audio)); + dependencies.SkinSource = new SkinProvidingContainer(Skin = new LegacySkin(userSkinInfo, userSkinResourceStore, Audio)); }); } @@ -101,6 +108,9 @@ namespace osu.Game.Tests.Beatmaps protected void AssertUserLookup(string name) => AddAssert($"\"{name}\" looked up from user skin", () => !beatmapSkinResourceStore.PerformedLookups.Contains(name) && userSkinResourceStore.PerformedLookups.Contains(name)); + protected void AssertNoLookup(string name) => AddAssert($"\"{name}\" not looked up", + () => !beatmapSkinResourceStore.PerformedLookups.Contains(name) && !userSkinResourceStore.PerformedLookups.Contains(name)); + private class SkinSourceDependencyContainer : IReadOnlyDependencyContainer { public ISkinSource SkinSource; From 8233f5fbc4e532cedc6a02b54d453ab106f5bf64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 21 Jun 2020 22:44:35 +0200 Subject: [PATCH 15/30] Check skin option in skin transformers --- .../Skinning/ManiaLegacySkinTransformer.cs | 12 ++++++++++++ osu.Game/Skinning/LegacySkinTransformer.cs | 13 ++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs index 84e88a10be..e167135556 100644 --- a/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/ManiaLegacySkinTransformer.cs @@ -9,6 +9,9 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Skinning; using System.Collections.Generic; +using osu.Framework.Audio.Sample; +using osu.Game.Audio; +using osu.Game.Rulesets.Objects.Legacy; namespace osu.Game.Rulesets.Mania.Skinning { @@ -129,6 +132,15 @@ namespace osu.Game.Rulesets.Mania.Skinning return this.GetAnimation(filename, true, true); } + public override SampleChannel GetSample(ISampleInfo sampleInfo) + { + // layered hit sounds never play in mania + if (sampleInfo is ConvertHitObjectParser.LegacyHitSampleInfo legacySample && legacySample.IsLayered) + return new SampleChannelVirtual(); + + return Source.GetSample(sampleInfo); + } + public override IBindable GetConfig(TLookup lookup) { if (lookup is ManiaSkinConfigurationLookup maniaLookup) diff --git a/osu.Game/Skinning/LegacySkinTransformer.cs b/osu.Game/Skinning/LegacySkinTransformer.cs index 1131c93288..94a7a32f05 100644 --- a/osu.Game/Skinning/LegacySkinTransformer.cs +++ b/osu.Game/Skinning/LegacySkinTransformer.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; using osu.Game.Audio; +using osu.Game.Rulesets.Objects.Legacy; namespace osu.Game.Skinning { @@ -28,7 +29,17 @@ namespace osu.Game.Skinning public Texture GetTexture(string componentName) => Source.GetTexture(componentName); - public virtual SampleChannel GetSample(ISampleInfo sampleInfo) => Source.GetSample(sampleInfo); + public virtual SampleChannel GetSample(ISampleInfo sampleInfo) + { + if (!(sampleInfo is ConvertHitObjectParser.LegacyHitSampleInfo legacySample)) + return Source.GetSample(sampleInfo); + + var playLayeredHitSounds = GetConfig(GlobalSkinConfiguration.LayeredHitSounds); + if (legacySample.IsLayered && playLayeredHitSounds?.Value == false) + return new SampleChannelVirtual(); + + return Source.GetSample(sampleInfo); + } public abstract IBindable GetConfig(TLookup lookup); } From 1387a9e2c63a0d46200a4ea7ef71e28cdb68c893 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Jun 2020 16:57:17 +0900 Subject: [PATCH 16/30] Move all tournament tests to using placeholder data rather than reading from bracket --- .../Components/TestSceneMatchScoreDisplay.cs | 2 +- osu.Game.Tournament.Tests/LadderTestScene.cs | 146 ------------------ .../Screens/TestSceneLadderEditorScreen.cs | 2 +- .../Screens/TestSceneLadderScreen.cs | 2 +- .../Screens/TestSceneMapPoolScreen.cs | 2 +- .../Screens/TestSceneRoundEditorScreen.cs | 2 +- .../Screens/TestSceneSeedingEditorScreen.cs | 2 +- .../Screens/TestSceneSeedingScreen.cs | 2 +- .../Screens/TestSceneTeamEditorScreen.cs | 2 +- .../Screens/TestSceneTeamIntroScreen.cs | 2 +- .../Screens/TestSceneTeamWinScreen.cs | 2 +- .../TournamentTestScene.cs | 141 +++++++++++++++++ 12 files changed, 151 insertions(+), 156 deletions(-) delete mode 100644 osu.Game.Tournament.Tests/LadderTestScene.cs diff --git a/osu.Game.Tournament.Tests/Components/TestSceneMatchScoreDisplay.cs b/osu.Game.Tournament.Tests/Components/TestSceneMatchScoreDisplay.cs index 77119f7a60..acd5d53310 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneMatchScoreDisplay.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneMatchScoreDisplay.cs @@ -9,7 +9,7 @@ using osu.Game.Tournament.Screens.Gameplay.Components; namespace osu.Game.Tournament.Tests.Components { - public class TestSceneMatchScoreDisplay : LadderTestScene + public class TestSceneMatchScoreDisplay : TournamentTestScene { [Cached(Type = typeof(MatchIPCInfo))] private MatchIPCInfo matchInfo = new MatchIPCInfo(); diff --git a/osu.Game.Tournament.Tests/LadderTestScene.cs b/osu.Game.Tournament.Tests/LadderTestScene.cs deleted file mode 100644 index 2f4373679c..0000000000 --- a/osu.Game.Tournament.Tests/LadderTestScene.cs +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Linq; -using NUnit.Framework; -using osu.Framework.Allocation; -using osu.Framework.Utils; -using osu.Game.Beatmaps; -using osu.Game.Rulesets; -using osu.Game.Tournament.Models; -using osu.Game.Users; - -namespace osu.Game.Tournament.Tests -{ - [TestFixture] - public abstract class LadderTestScene : TournamentTestScene - { - [Cached] - protected LadderInfo Ladder { get; private set; } = new LadderInfo(); - - [Resolved] - private RulesetStore rulesetStore { get; set; } - - [BackgroundDependencyLoader] - private void load() - { - Ladder.Ruleset.Value ??= rulesetStore.AvailableRulesets.First(); - - Ruleset.BindTo(Ladder.Ruleset); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - TournamentMatch match = CreateSampleMatch(); - - Ladder.Rounds.Add(match.Round.Value); - Ladder.Matches.Add(match); - Ladder.Teams.Add(match.Team1.Value); - Ladder.Teams.Add(match.Team2.Value); - - Ladder.CurrentMatch.Value = match; - } - - public static TournamentMatch CreateSampleMatch() => new TournamentMatch - { - Team1 = - { - Value = new TournamentTeam - { - FlagName = { Value = "JP" }, - FullName = { Value = "Japan" }, - LastYearPlacing = { Value = 10 }, - Seed = { Value = "Low" }, - SeedingResults = - { - new SeedingResult - { - Mod = { Value = "NM" }, - Seed = { Value = 10 }, - Beatmaps = - { - new SeedingBeatmap - { - BeatmapInfo = CreateSampleBeatmapInfo(), - Score = 12345672, - Seed = { Value = 24 }, - }, - new SeedingBeatmap - { - BeatmapInfo = CreateSampleBeatmapInfo(), - Score = 1234567, - Seed = { Value = 12 }, - }, - new SeedingBeatmap - { - BeatmapInfo = CreateSampleBeatmapInfo(), - Score = 1234567, - Seed = { Value = 16 }, - } - } - }, - new SeedingResult - { - Mod = { Value = "DT" }, - Seed = { Value = 5 }, - Beatmaps = - { - new SeedingBeatmap - { - BeatmapInfo = CreateSampleBeatmapInfo(), - Score = 234567, - Seed = { Value = 3 }, - }, - new SeedingBeatmap - { - BeatmapInfo = CreateSampleBeatmapInfo(), - Score = 234567, - Seed = { Value = 6 }, - }, - new SeedingBeatmap - { - BeatmapInfo = CreateSampleBeatmapInfo(), - Score = 234567, - Seed = { Value = 12 }, - } - } - } - }, - Players = - { - new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 12 } } }, - new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 16 } } }, - new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 20 } } }, - new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 24 } } }, - new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 30 } } }, - } - } - }, - Team2 = - { - Value = new TournamentTeam - { - FlagName = { Value = "US" }, - FullName = { Value = "United States" }, - Players = - { - new User { Username = "Hello" }, - new User { Username = "Hello" }, - new User { Username = "Hello" }, - new User { Username = "Hello" }, - new User { Username = "Hello" }, - } - } - }, - Round = - { - Value = new TournamentRound { Name = { Value = "Quarterfinals" } } - } - }; - - public static BeatmapInfo CreateSampleBeatmapInfo() => - new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist", ID = RNG.Next(0, 1000000) } }; - } -} diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs index a45c5de2bd..bceb3e6b74 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs @@ -8,7 +8,7 @@ using osu.Game.Tournament.Screens.Editors; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneLadderEditorScreen : LadderTestScene + public class TestSceneLadderEditorScreen : TournamentTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneLadderScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneLadderScreen.cs index 2be0564c82..c4c100d506 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneLadderScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneLadderScreen.cs @@ -8,7 +8,7 @@ using osu.Game.Tournament.Screens.Ladder; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneLadderScreen : LadderTestScene + public class TestSceneLadderScreen : TournamentTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneMapPoolScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneMapPoolScreen.cs index a4538be384..f4032fdd54 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneMapPoolScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneMapPoolScreen.cs @@ -12,7 +12,7 @@ using osu.Game.Tournament.Screens.MapPool; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneMapPoolScreen : LadderTestScene + public class TestSceneMapPoolScreen : TournamentTestScene { private MapPoolScreen screen; diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneRoundEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneRoundEditorScreen.cs index e15ac416b0..5c2b59df3a 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneRoundEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneRoundEditorScreen.cs @@ -5,7 +5,7 @@ using osu.Game.Tournament.Screens.Editors; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneRoundEditorScreen : LadderTestScene + public class TestSceneRoundEditorScreen : TournamentTestScene { public TestSceneRoundEditorScreen() { diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs index 8d12d5393d..2722021216 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs @@ -7,7 +7,7 @@ using osu.Game.Tournament.Screens.Editors; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneSeedingEditorScreen : LadderTestScene + public class TestSceneSeedingEditorScreen : TournamentTestScene { [Cached] private readonly LadderInfo ladder = new LadderInfo(); diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneSeedingScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneSeedingScreen.cs index 4269f8f56a..d414d8e36e 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneSeedingScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneSeedingScreen.cs @@ -8,7 +8,7 @@ using osu.Game.Tournament.Screens.TeamIntro; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneSeedingScreen : LadderTestScene + public class TestSceneSeedingScreen : TournamentTestScene { [Cached] private readonly LadderInfo ladder = new LadderInfo(); diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneTeamEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneTeamEditorScreen.cs index 097bad4a02..fc6574ec8a 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneTeamEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneTeamEditorScreen.cs @@ -5,7 +5,7 @@ using osu.Game.Tournament.Screens.Editors; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneTeamEditorScreen : LadderTestScene + public class TestSceneTeamEditorScreen : TournamentTestScene { public TestSceneTeamEditorScreen() { diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs index e36b594ff2..b3f78c92d9 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs @@ -9,7 +9,7 @@ using osu.Game.Tournament.Screens.TeamIntro; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneTeamIntroScreen : LadderTestScene + public class TestSceneTeamIntroScreen : TournamentTestScene { [Cached] private readonly LadderInfo ladder = new LadderInfo(); diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs index 1a2faa76c1..6873fb0f4b 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs @@ -9,7 +9,7 @@ using osu.Game.Tournament.Screens.TeamWin; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneTeamWinScreen : LadderTestScene + public class TestSceneTeamWinScreen : TournamentTestScene { [Cached] private readonly LadderInfo ladder = new LadderInfo(); diff --git a/osu.Game.Tournament.Tests/TournamentTestScene.cs b/osu.Game.Tournament.Tests/TournamentTestScene.cs index 18ac3230da..a7b141cf43 100644 --- a/osu.Game.Tournament.Tests/TournamentTestScene.cs +++ b/osu.Game.Tournament.Tests/TournamentTestScene.cs @@ -1,13 +1,154 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Platform; using osu.Framework.Testing; +using osu.Framework.Utils; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; using osu.Game.Tests.Visual; +using osu.Game.Tournament.IPC; +using osu.Game.Tournament.Models; +using osu.Game.Users; namespace osu.Game.Tournament.Tests { public abstract class TournamentTestScene : OsuTestScene { + [Cached] + protected LadderInfo Ladder { get; private set; } = new LadderInfo(); + + [Resolved] + private RulesetStore rulesetStore { get; set; } + + [Cached] + protected MatchIPCInfo IPCInfo { get; private set; } = new MatchIPCInfo(); + + [BackgroundDependencyLoader] + private void load(Storage storage) + { + Ladder.Ruleset.Value ??= rulesetStore.AvailableRulesets.First(); + + Ruleset.BindTo(Ladder.Ruleset); + Dependencies.CacheAs(new StableInfo(storage)); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + TournamentMatch match = CreateSampleMatch(); + + Ladder.Rounds.Add(match.Round.Value); + Ladder.Matches.Add(match); + Ladder.Teams.Add(match.Team1.Value); + Ladder.Teams.Add(match.Team2.Value); + + Ladder.CurrentMatch.Value = match; + } + + public static TournamentMatch CreateSampleMatch() => new TournamentMatch + { + Team1 = + { + Value = new TournamentTeam + { + FlagName = { Value = "JP" }, + FullName = { Value = "Japan" }, + LastYearPlacing = { Value = 10 }, + Seed = { Value = "Low" }, + SeedingResults = + { + new SeedingResult + { + Mod = { Value = "NM" }, + Seed = { Value = 10 }, + Beatmaps = + { + new SeedingBeatmap + { + BeatmapInfo = CreateSampleBeatmapInfo(), + Score = 12345672, + Seed = { Value = 24 }, + }, + new SeedingBeatmap + { + BeatmapInfo = CreateSampleBeatmapInfo(), + Score = 1234567, + Seed = { Value = 12 }, + }, + new SeedingBeatmap + { + BeatmapInfo = CreateSampleBeatmapInfo(), + Score = 1234567, + Seed = { Value = 16 }, + } + } + }, + new SeedingResult + { + Mod = { Value = "DT" }, + Seed = { Value = 5 }, + Beatmaps = + { + new SeedingBeatmap + { + BeatmapInfo = CreateSampleBeatmapInfo(), + Score = 234567, + Seed = { Value = 3 }, + }, + new SeedingBeatmap + { + BeatmapInfo = CreateSampleBeatmapInfo(), + Score = 234567, + Seed = { Value = 6 }, + }, + new SeedingBeatmap + { + BeatmapInfo = CreateSampleBeatmapInfo(), + Score = 234567, + Seed = { Value = 12 }, + } + } + } + }, + Players = + { + new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 12 } } }, + new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 16 } } }, + new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 20 } } }, + new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 24 } } }, + new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 30 } } }, + } + } + }, + Team2 = + { + Value = new TournamentTeam + { + FlagName = { Value = "US" }, + FullName = { Value = "United States" }, + Players = + { + new User { Username = "Hello" }, + new User { Username = "Hello" }, + new User { Username = "Hello" }, + new User { Username = "Hello" }, + new User { Username = "Hello" }, + } + } + }, + Round = + { + Value = new TournamentRound { Name = { Value = "Quarterfinals" } } + } + }; + + public static BeatmapInfo CreateSampleBeatmapInfo() => + new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist", ID = RNG.Next(0, 1000000) } }; + protected override ITestSceneTestRunner CreateRunner() => new TournamentTestSceneTestRunner(); public class TournamentTestSceneTestRunner : TournamentGameBase, ITestSceneTestRunner From 92e272ebb6f301a5b896ea2a3166d2cbf761be99 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Jun 2020 16:57:40 +0900 Subject: [PATCH 17/30] Remove unnecessary prefixes --- osu.Game.Tournament/TournamentSceneManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tournament/TournamentSceneManager.cs b/osu.Game.Tournament/TournamentSceneManager.cs index 23fcb01db7..2c539cdd43 100644 --- a/osu.Game.Tournament/TournamentSceneManager.cs +++ b/osu.Game.Tournament/TournamentSceneManager.cs @@ -37,7 +37,7 @@ namespace osu.Game.Tournament public const float STREAM_AREA_WIDTH = 1366; - public const double REQUIRED_WIDTH = TournamentSceneManager.CONTROL_AREA_WIDTH * 2 + TournamentSceneManager.STREAM_AREA_WIDTH; + public const double REQUIRED_WIDTH = CONTROL_AREA_WIDTH * 2 + STREAM_AREA_WIDTH; [Cached] private TournamentMatchChatDisplay chat = new TournamentMatchChatDisplay(); From eb3e1b2b2698ab5bc843bd5a90c945ca01cd7d5f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Jun 2020 17:03:22 +0900 Subject: [PATCH 18/30] Fix incorrect inheritance on remaining test scene --- .../Components/TestSceneTournamentBeatmapPanel.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tournament.Tests/Components/TestSceneTournamentBeatmapPanel.cs b/osu.Game.Tournament.Tests/Components/TestSceneTournamentBeatmapPanel.cs index 77fa411058..bc32a12ab7 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneTournamentBeatmapPanel.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneTournamentBeatmapPanel.cs @@ -8,12 +8,11 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; -using osu.Game.Tests.Visual; using osu.Game.Tournament.Components; namespace osu.Game.Tournament.Tests.Components { - public class TestSceneTournamentBeatmapPanel : OsuTestScene + public class TestSceneTournamentBeatmapPanel : TournamentTestScene { [Resolved] private IAPIProvider api { get; set; } From 5fd6246d1b5e3b0d650cf4117d10df84b6d9f5de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Jun 2020 17:57:07 +0900 Subject: [PATCH 19/30] Fix remaining test scenes --- .../Screens/TestSceneTeamWinScreen.cs | 10 ++-------- osu.Game.Tournament.Tests/TournamentTestScene.cs | 13 +++++-------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs index 6873fb0f4b..3ca58dcaf4 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs @@ -4,25 +4,19 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Game.Tournament.Models; using osu.Game.Tournament.Screens.TeamWin; namespace osu.Game.Tournament.Tests.Screens { public class TestSceneTeamWinScreen : TournamentTestScene { - [Cached] - private readonly LadderInfo ladder = new LadderInfo(); - [BackgroundDependencyLoader] private void load() { - var match = new TournamentMatch(); - match.Team1.Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "USA"); - match.Team2.Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "JPN"); + var match = Ladder.CurrentMatch.Value; + match.Round.Value = Ladder.Rounds.FirstOrDefault(g => g.Name.Value == "Finals"); match.Completed.Value = true; - ladder.CurrentMatch.Value = match; Add(new TeamWinScreen { diff --git a/osu.Game.Tournament.Tests/TournamentTestScene.cs b/osu.Game.Tournament.Tests/TournamentTestScene.cs index a7b141cf43..d22da25f9d 100644 --- a/osu.Game.Tournament.Tests/TournamentTestScene.cs +++ b/osu.Game.Tournament.Tests/TournamentTestScene.cs @@ -31,14 +31,6 @@ namespace osu.Game.Tournament.Tests { Ladder.Ruleset.Value ??= rulesetStore.AvailableRulesets.First(); - Ruleset.BindTo(Ladder.Ruleset); - Dependencies.CacheAs(new StableInfo(storage)); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - TournamentMatch match = CreateSampleMatch(); Ladder.Rounds.Add(match.Round.Value); @@ -47,6 +39,9 @@ namespace osu.Game.Tournament.Tests Ladder.Teams.Add(match.Team2.Value); Ladder.CurrentMatch.Value = match; + + Ruleset.BindTo(Ladder.Ruleset); + Dependencies.CacheAs(new StableInfo(storage)); } public static TournamentMatch CreateSampleMatch() => new TournamentMatch @@ -55,6 +50,7 @@ namespace osu.Game.Tournament.Tests { Value = new TournamentTeam { + Acronym = { Value = "JPN" }, FlagName = { Value = "JP" }, FullName = { Value = "Japan" }, LastYearPlacing = { Value = 10 }, @@ -128,6 +124,7 @@ namespace osu.Game.Tournament.Tests { Value = new TournamentTeam { + Acronym = { Value = "USA" }, FlagName = { Value = "US" }, FullName = { Value = "United States" }, Players = From 9e1bf71233b66a88b2419339db6cf181a7705534 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Wed, 24 Jun 2020 11:29:38 +0200 Subject: [PATCH 20/30] Added text explaining a second copy will be made --- osu.Game/Screens/Select/ImportFromStablePopup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/ImportFromStablePopup.cs b/osu.Game/Screens/Select/ImportFromStablePopup.cs index 20494829ae..272f9566d5 100644 --- a/osu.Game/Screens/Select/ImportFromStablePopup.cs +++ b/osu.Game/Screens/Select/ImportFromStablePopup.cs @@ -12,7 +12,7 @@ namespace osu.Game.Screens.Select public ImportFromStablePopup(Action importFromStable) { HeaderText = @"You have no beatmaps!"; - BodyText = "An existing copy of osu! was found, though.\nWould you like to import your beatmaps, skins and scores?"; + BodyText = "An existing copy of osu! was found, though.\nWould you like to import your beatmaps, skins and scores?\nThis will create a second copy of all files on disk."; Icon = FontAwesome.Solid.Plane; From 6bc507d49ed2bc76cbbaffc5dc9ddac087a5bd8f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 24 Jun 2020 18:53:52 +0900 Subject: [PATCH 21/30] Increase coordinate parsing limits --- osu.Game/Beatmaps/Formats/Parsing.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/Parsing.cs b/osu.Game/Beatmaps/Formats/Parsing.cs index c3efb8c760..c4795a6931 100644 --- a/osu.Game/Beatmaps/Formats/Parsing.cs +++ b/osu.Game/Beatmaps/Formats/Parsing.cs @@ -11,7 +11,7 @@ namespace osu.Game.Beatmaps.Formats /// public static class Parsing { - public const int MAX_COORDINATE_VALUE = 65536; + public const int MAX_COORDINATE_VALUE = 131072; public const double MAX_PARSE_VALUE = int.MaxValue; From 4c283476866d7cf9d276a8e3219fa3a069f7604f Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Wed, 24 Jun 2020 15:34:20 +0100 Subject: [PATCH 22/30] Adjust sample rate by UserPlaybackRate --- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 83991ad027..71a97da5c2 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Play public bool LoadedBeatmapSuccessfully => DrawableRuleset?.Objects.Any() == true; - protected GameplayClockContainer GameplayClockContainer { get; private set; } + public GameplayClockContainer GameplayClockContainer { get; private set; } public DimmableStoryboard DimmableStoryboard { get; private set; } diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index 8eaf9ac652..3dc7eab968 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -4,11 +4,13 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; +using osu.Game.Screens.Play; namespace osu.Game.Storyboards.Drawables { @@ -32,7 +34,7 @@ namespace osu.Game.Storyboards.Drawables } [BackgroundDependencyLoader] - private void load(IBindable beatmap, IBindable> mods) + private void load(IBindable beatmap, IBindable> mods, Player player) { Channel = beatmap.Value.Skin.GetSample(sampleInfo); if (Channel == null) @@ -42,6 +44,8 @@ namespace osu.Game.Storyboards.Drawables foreach (var mod in mods.Value.OfType()) mod.ApplyToSample(Channel); + + Channel.AddAdjustment(AdjustableProperty.Frequency, player.GameplayClockContainer.UserPlaybackRate); } protected override void Update() From 992ada46700d6f6420a6f22b0904376bb7ec7c58 Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Wed, 24 Jun 2020 16:17:18 +0100 Subject: [PATCH 23/30] Revert UserPlaybackRate changes --- osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index 3dc7eab968..5aeadb2e1f 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -34,7 +34,7 @@ namespace osu.Game.Storyboards.Drawables } [BackgroundDependencyLoader] - private void load(IBindable beatmap, IBindable> mods, Player player) + private void load(IBindable beatmap, IBindable> mods) { Channel = beatmap.Value.Skin.GetSample(sampleInfo); if (Channel == null) @@ -44,8 +44,6 @@ namespace osu.Game.Storyboards.Drawables foreach (var mod in mods.Value.OfType()) mod.ApplyToSample(Channel); - - Channel.AddAdjustment(AdjustableProperty.Frequency, player.GameplayClockContainer.UserPlaybackRate); } protected override void Update() From f2a48a339ea7e643ab5156764f99450d53f30bf2 Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Wed, 24 Jun 2020 16:33:19 +0100 Subject: [PATCH 24/30] Remove unused usings --- osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index 5aeadb2e1f..8eaf9ac652 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -4,13 +4,11 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; -using osu.Game.Screens.Play; namespace osu.Game.Storyboards.Drawables { From ac5cd8f25a3a1f08c3adc3fe562e0fbdc5b0585c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Jun 2020 13:40:26 +0900 Subject: [PATCH 25/30] Fix colours with 0 alpha being invisible in legacy skins --- osu.Game/Skinning/LegacySkin.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 0b2b723440..bbc64a24e7 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -271,7 +271,15 @@ namespace osu.Game.Skinning } private IBindable getCustomColour(IHasCustomColours source, string lookup) - => source.CustomColours.TryGetValue(lookup, out var col) ? new Bindable(col) : null; + { + if (!source.CustomColours.TryGetValue(lookup, out var col)) + return null; + + if (col.A == 0) + col.A = 1; + + return new Bindable(col); + } private IBindable getManiaImage(LegacyManiaSkinConfiguration source, string lookup) => source.ImageLookups.TryGetValue(lookup, out var image) ? new Bindable(image) : null; From 4c601af207c3374eb37fd588e989e2ee9f129acb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Jun 2020 13:43:14 +0900 Subject: [PATCH 26/30] Match condition --- osu.Game/Skinning/LegacySkin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index bbc64a24e7..be6d694efe 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -275,7 +275,7 @@ namespace osu.Game.Skinning if (!source.CustomColours.TryGetValue(lookup, out var col)) return null; - if (col.A == 0) + if (col.A <= 0 || col.A >= 255) col.A = 1; return new Bindable(col); From 8b84aa454d61cd61390fcce8f8f79be4e8ab1ebb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Jun 2020 13:43:56 +0900 Subject: [PATCH 27/30] Fix incorrect upper bound --- osu.Game/Skinning/LegacySkin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index be6d694efe..ea630b9b8d 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -275,7 +275,7 @@ namespace osu.Game.Skinning if (!source.CustomColours.TryGetValue(lookup, out var col)) return null; - if (col.A <= 0 || col.A >= 255) + if (col.A <= 0 || col.A >= 1) col.A = 1; return new Bindable(col); From 4ff9a910121d85957cdb94011a8ed5dba653c3ad Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Jun 2020 14:15:26 +0900 Subject: [PATCH 28/30] Adjust at parse time instead --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 7 ++++++- osu.Game/Skinning/LegacySkin.cs | 10 +--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 6406bd88a5..a0e83554a3 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -103,7 +103,12 @@ namespace osu.Game.Beatmaps.Formats try { - colour = new Color4(byte.Parse(split[0]), byte.Parse(split[1]), byte.Parse(split[2]), split.Length == 4 ? byte.Parse(split[3]) : (byte)255); + byte alpha = split.Length == 4 ? byte.Parse(split[3]) : (byte)255; + + if (alpha == 0) + alpha = 255; + + colour = new Color4(byte.Parse(split[0]), byte.Parse(split[1]), byte.Parse(split[2]), alpha); } catch { diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index ea630b9b8d..0b2b723440 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -271,15 +271,7 @@ namespace osu.Game.Skinning } private IBindable getCustomColour(IHasCustomColours source, string lookup) - { - if (!source.CustomColours.TryGetValue(lookup, out var col)) - return null; - - if (col.A <= 0 || col.A >= 1) - col.A = 1; - - return new Bindable(col); - } + => source.CustomColours.TryGetValue(lookup, out var col) ? new Bindable(col) : null; private IBindable getManiaImage(LegacyManiaSkinConfiguration source, string lookup) => source.ImageLookups.TryGetValue(lookup, out var image) ? new Bindable(image) : null; From 531a69650f390ef3825f449daf46f0a32149895a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 25 Jun 2020 14:22:40 +0900 Subject: [PATCH 29/30] Add test --- osu.Game.Tests/Resources/skin-zero-alpha-colour.ini | 5 +++++ osu.Game.Tests/Skins/LegacySkinDecoderTest.cs | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 osu.Game.Tests/Resources/skin-zero-alpha-colour.ini diff --git a/osu.Game.Tests/Resources/skin-zero-alpha-colour.ini b/osu.Game.Tests/Resources/skin-zero-alpha-colour.ini new file mode 100644 index 0000000000..3c0dae6b13 --- /dev/null +++ b/osu.Game.Tests/Resources/skin-zero-alpha-colour.ini @@ -0,0 +1,5 @@ +[General] +Version: latest + +[Colours] +Combo1: 255,255,255,0 \ No newline at end of file diff --git a/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs b/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs index aedf26ee75..c408d2f182 100644 --- a/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs +++ b/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs @@ -108,5 +108,15 @@ namespace osu.Game.Tests.Skins using (var stream = new LineBufferedReader(resStream)) Assert.That(decoder.Decode(stream).LegacyVersion, Is.EqualTo(1.0m)); } + + [Test] + public void TestDecodeColourWithZeroAlpha() + { + var decoder = new LegacySkinDecoder(); + + using (var resStream = TestResources.OpenResource("skin-zero-alpha-colour.ini")) + using (var stream = new LineBufferedReader(resStream)) + Assert.That(decoder.Decode(stream).ComboColours[0].A, Is.EqualTo(1.0f)); + } } } From 65a2fc3bfc052a150d67d0b14a19fece40cf47cb Mon Sep 17 00:00:00 2001 From: Ronnie Moir <7267697+H2n9@users.noreply.github.com> Date: Thu, 25 Jun 2020 17:53:14 +0100 Subject: [PATCH 30/30] Revert access modifier --- osu.Game/Screens/Play/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 71a97da5c2..83991ad027 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Play public bool LoadedBeatmapSuccessfully => DrawableRuleset?.Objects.Any() == true; - public GameplayClockContainer GameplayClockContainer { get; private set; } + protected GameplayClockContainer GameplayClockContainer { get; private set; } public DimmableStoryboard DimmableStoryboard { get; private set; }