From 40a27c810a7dabba9082475ed36aa0aa71872029 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 29 Sep 2017 19:24:14 +0800 Subject: [PATCH 01/83] Calculate SPM in spinner disc. --- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 6577c7fd50..518fe188fb 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -76,7 +76,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private float lastAngle; private float currentRotation; + private double lastTime; public float RotationAbsolute; + public double SpinsPerMinute; private int completeTick; @@ -107,9 +109,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces currentRotation += thisAngle - lastAngle; RotationAbsolute += Math.Abs(thisAngle - lastAngle); + SpinsPerMinute = (thisAngle - lastAngle) / (Time.Current - lastTime) * 1000 * 60 / 360; } lastAngle = thisAngle; + lastTime = Time.Current; if (Complete && updateCompleteTick()) { From e2e26c91af5856851ab414186258683ce07d9b85 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 29 Sep 2017 22:30:41 +0800 Subject: [PATCH 02/83] Show SPM value basically. --- .../Objects/Drawables/DrawableSpinner.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 98dd40b0e6..c7e0353985 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -13,6 +13,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Allocation; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Screens.Ranking; +using osu.Game.Graphics.Sprites; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -29,6 +30,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly Container circleContainer; private readonly CirclePiece circle; private readonly GlowPiece glow; + private readonly OsuSpriteText spmText; private readonly SpriteIcon symbol; @@ -96,6 +98,24 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Origin = Anchor.Centre, }, circleContainer.CreateProxy(), + spmText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + Text = @"0", + Font = @"Venera", + TextSize = 24, + Y = 120 + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.TopCentre, + Text = @"SPINS PER MINUTE", + Font = @"Venera", + TextSize = 12, + Y = 125 + }, ticks = new SpinnerTicks { Anchor = Anchor.Centre, @@ -167,6 +187,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables circle.Rotation = disc.Rotation; ticks.Rotation = disc.Rotation; + spmText.Text = disc.SpinsPerMinute.ToString(@"#0"); float relativeCircleScale = spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight; disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint); From 3de42ee4050f8b08d7c0db3796e4d6913097dc9a Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 30 Sep 2017 15:23:10 +0800 Subject: [PATCH 03/83] Smooth spm values into a time range. --- .../Objects/Drawables/DrawableSpinner.cs | 3 ++- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 20 ++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index c7e0353985..6b9e91d4f4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -187,7 +188,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables circle.Rotation = disc.Rotation; ticks.Rotation = disc.Rotation; - spmText.Text = disc.SpinsPerMinute.ToString(@"#0"); + spmText.Text = Math.Truncate(disc.SpinsPerMinute).ToString(@"#0"); float relativeCircleScale = spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight; disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 518fe188fb..04bbd8b871 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; @@ -76,9 +77,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private float lastAngle; private float currentRotation; - private double lastTime; public float RotationAbsolute; public double SpinsPerMinute; + private readonly Queue rotations = new Queue(); + private readonly Queue times = new Queue(); + private const double spm_count_duration = 595; // not using hundreds to avoid frame rounding issues private int completeTick; @@ -109,11 +112,22 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces currentRotation += thisAngle - lastAngle; RotationAbsolute += Math.Abs(thisAngle - lastAngle); - SpinsPerMinute = (thisAngle - lastAngle) / (Time.Current - lastTime) * 1000 * 60 / 360; + if (rotations.Count > 0) + { + float rotationFrom = rotations.Peek(); + double timeFrom = times.Peek(); + while (Time.Current - times.Peek() > spm_count_duration) + { + rotationFrom = rotations.Dequeue(); + timeFrom = times.Dequeue(); + } + SpinsPerMinute = (currentRotation - rotationFrom) / (Time.Current - timeFrom) * 1000 * 60 / 360; + } } lastAngle = thisAngle; - lastTime = Time.Current; + rotations.Enqueue(currentRotation); + times.Enqueue(Time.Current); if (Complete && updateCompleteTick()) { From 1a7e3fa09e4d51db6a30dfe7975538fc1277b824 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Oct 2017 19:21:08 +0900 Subject: [PATCH 04/83] Initial implementation of a test case which showcases waveforms --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 149 ++++++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 2 files changed, 150 insertions(+) create mode 100644 osu.Game/Tests/Visual/TestCaseWaveform.cs diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs new file mode 100644 index 0000000000..5f4e86fb92 --- /dev/null +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -0,0 +1,149 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Audio.Track; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Graphics.Sprites; +using osu.Game.Overlays; + +namespace osu.Game.Tests.Visual +{ + internal class TestCaseWaveform : OsuTestCase + { + private readonly Bindable beatmapBacking = new Bindable(); + + private readonly List displays = new List(); + + public TestCaseWaveform() + { + MusicController mc; + FillFlowContainer flow; + Child = flow = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + mc = new MusicController + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Y = 100, + State = Visibility.Visible + }, + } + }; + + for (int i = 1; i <= 16; i *= 2) + { + var newDisplay = new WaveformDisplay(i) { RelativeSizeAxes = Axes.Both }; + + displays.Add(newDisplay); + + flow.Add(new Container + { + RelativeSizeAxes = Axes.X, + Height = 100, + Children = new Drawable[] + { + newDisplay, + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.75f + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = $"Resolution: {(1f / i).ToString("0.00")}" + } + } + } + } + }); + } + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame) + { + beatmapBacking.BindTo(osuGame.Beatmap); + beatmapBacking.ValueChanged += b => b.Track.QueryWaveform(processWaveform); + } + + private void processWaveform(Waveform waveform) => Schedule(() => displays.ForEach(d => d.Display(waveform))); + + private class WaveformDisplay : CompositeDrawable + { + private readonly int resolution; + + public WaveformDisplay(int resolution) + { + this.resolution = resolution; + } + + public void Display(Waveform waveform) + { + ClearInternal(); + + var generated = waveform.Generate((int)MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) / resolution); + + for (int i = 0; i < generated.Count; i++) + { + var point = generated[i]; + + // Left channel + AddInternal(new NonInputBox + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.BottomLeft, + RelativePositionAxes = Axes.X, + RelativeSizeAxes = Axes.Both, + X = 1f / generated.Count * i, + Size = new Vector2(1f / generated.Count, point.Amplitude[0] / 2), + Colour = Color4.Red + }); + + if (waveform.Channels >= 2) + { + // Right channel + AddInternal(new NonInputBox + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.TopLeft, + RelativePositionAxes = Axes.X, + RelativeSizeAxes = Axes.Both, + X = 1f / generated.Count * i, + Size = new Vector2(1f / generated.Count, point.Amplitude[1] / 2), + Colour = Color4.Green + }); + } + } + } + + private class NonInputBox : Box + { + public override bool HandleInput => false; + } + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9a8536bbc2..56490b6119 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -777,6 +777,7 @@ + From 319649f4465a45bc93c615d57ceb11ac36cd8460 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Oct 2017 21:19:38 +0900 Subject: [PATCH 05/83] Make TestCaseWaveform use a custom drawnode instead of boxes --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 128 +++++++++++++++++----- 1 file changed, 101 insertions(+), 27 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 5f4e86fb92..3f71e74a8d 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -5,12 +5,19 @@ using System; using System.Collections.Generic; using OpenTK; using OpenTK.Graphics; +using OpenTK.Graphics.ES30; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Framework.Graphics.Batches; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.OpenGL.Vertices; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; @@ -92,51 +99,118 @@ namespace osu.Game.Tests.Visual private void processWaveform(Waveform waveform) => Schedule(() => displays.ForEach(d => d.Display(waveform))); - private class WaveformDisplay : CompositeDrawable + private class WaveformDisplay : Drawable { + private List points; + private int channels; + + private Shader shader; + private readonly Texture texture; + private readonly int resolution; public WaveformDisplay(int resolution) { this.resolution = resolution; + + texture = Texture.WhitePixel; + } + + [BackgroundDependencyLoader] + private void load(ShaderManager shaders) + { + shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); } public void Display(Waveform waveform) { - ClearInternal(); + points = waveform.Generate((int)MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) / resolution); + channels = waveform.Channels; + Invalidate(Invalidation.DrawNode); + } - var generated = waveform.Generate((int)MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) / resolution); + protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); - for (int i = 0; i < generated.Count; i++) + private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); + protected override void ApplyDrawNode(DrawNode node) + { + var n = (WaveformDrawNode)node; + + n.Shader = shader; + n.Texture = texture; + n.Points = points; + n.Channels = channels; + n.Size = DrawSize; + n.Shared = sharedData; + + + base.ApplyDrawNode(node); + } + + private class WaveformDrawNodeSharedData + { + public readonly QuadBatch VertexBatch = new QuadBatch(1000, 10); + } + + private class WaveformDrawNode : DrawNode + { + public Shader Shader; + public Texture Texture; + + public WaveformDrawNodeSharedData Shared; + + public List Points; + public Vector2 Size; + public int Channels; + + public override void Draw(Action vertexAction) { - var point = generated[i]; + base.Draw(vertexAction); - // Left channel - AddInternal(new NonInputBox - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.BottomLeft, - RelativePositionAxes = Axes.X, - RelativeSizeAxes = Axes.Both, - X = 1f / generated.Count * i, - Size = new Vector2(1f / generated.Count, point.Amplitude[0] / 2), - Colour = Color4.Red - }); + if (Points == null || Points.Count == 0) + return; - if (waveform.Channels >= 2) + Shader.Bind(); + Texture.TextureGL.Bind(); + + float separation = Size.X / (Points.Count - 1); + Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; + + for (int i = 0; i < Points.Count - 1; i++) { - // Right channel - AddInternal(new NonInputBox + ColourInfo colour = DrawInfo.Colour; + Quad quadToDraw; + + switch (Channels) { - Anchor = Anchor.CentreLeft, - Origin = Anchor.TopLeft, - RelativePositionAxes = Axes.X, - RelativeSizeAxes = Axes.Both, - X = 1f / generated.Count * i, - Size = new Vector2(1f / generated.Count, point.Amplitude[1] / 2), - Colour = Color4.Green - }); + default: + case 2: + { + float height = Size.Y / 2; + quadToDraw = new Quad( + new Vector2(i * separation, height - Points[i].Amplitude[0] * height), + new Vector2((i + 1) * separation, height - Points[i + 1].Amplitude[0] * height), + new Vector2(i * separation, height + Points[i].Amplitude[1] * height), + new Vector2((i + 1) * separation, height + Points[i + 1].Amplitude[1] * height) + ); + } + break; + case 1: + { + quadToDraw = new Quad( + new Vector2(i * separation, Size.Y - Points[i].Amplitude[0] * Size.Y), + new Vector2((i + 1) * separation, Size.Y - Points[i + 1].Amplitude[0] * Size.Y), + new Vector2(i * separation, Size.Y), + new Vector2((i + 1) * separation, Size.Y) + ); + break; + } + } + + Texture.DrawQuad(quadToDraw * DrawInfo.Matrix, colour, null, Shared.VertexBatch.Add, Vector2.Divide(localInflationAmount, quadToDraw.Size)); } + + Shader.Unbind(); } } From 3eeb36cbd42f3cfa4b7b448e9c4170af4a346601 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Oct 2017 23:23:20 +0900 Subject: [PATCH 06/83] Remove now unused class --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 3f71e74a8d..2966728fb5 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -143,7 +143,6 @@ namespace osu.Game.Tests.Visual n.Size = DrawSize; n.Shared = sharedData; - base.ApplyDrawNode(node); } @@ -213,11 +212,6 @@ namespace osu.Game.Tests.Visual Shader.Unbind(); } } - - private class NonInputBox : Box - { - public override bool HandleInput => false; - } } } } From a37b10d51220b5f0df864cd8e503696eb669a0b6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 14:42:22 +0900 Subject: [PATCH 07/83] Make TestCaseWaveform use invalidations + remove some of the crud --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 69 +++++++++++++++-------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 2966728fb5..4df7ffe367 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -28,8 +28,6 @@ namespace osu.Game.Tests.Visual { private readonly Bindable beatmapBacking = new Bindable(); - private readonly List displays = new List(); - public TestCaseWaveform() { MusicController mc; @@ -53,9 +51,13 @@ namespace osu.Game.Tests.Visual for (int i = 1; i <= 16; i *= 2) { - var newDisplay = new WaveformDisplay(i) { RelativeSizeAxes = Axes.Both }; + var newDisplay = new WaveformDisplay + { + RelativeSizeAxes = Axes.Both, + Resolution = 1f / i + }; - displays.Add(newDisplay); + newDisplay.Beatmap.BindTo(beatmapBacking); flow.Add(new Container { @@ -91,29 +93,21 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) - { - beatmapBacking.BindTo(osuGame.Beatmap); - beatmapBacking.ValueChanged += b => b.Track.QueryWaveform(processWaveform); - } - - private void processWaveform(Waveform waveform) => Schedule(() => displays.ForEach(d => d.Display(waveform))); + private void load(OsuGameBase osuGame) => beatmapBacking.BindTo(osuGame.Beatmap); private class WaveformDisplay : Drawable { - private List points; - private int channels; + public readonly Bindable Beatmap = new Bindable(); + + private Waveform waveform; private Shader shader; private readonly Texture texture; - private readonly int resolution; - - public WaveformDisplay(int resolution) + public WaveformDisplay() { - this.resolution = resolution; - texture = Texture.WhitePixel; + Beatmap.ValueChanged += generateWaveform; } [BackgroundDependencyLoader] @@ -122,26 +116,51 @@ namespace osu.Game.Tests.Visual shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); } - public void Display(Waveform waveform) + private float resolution = 1; + public float Resolution { - points = waveform.Generate((int)MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) / resolution); - channels = waveform.Channels; - Invalidate(Invalidation.DrawNode); + get { return resolution; } + set + { + if (resolution == value) + return; + resolution = value; + + Invalidate(Invalidation.DrawNode); + } } - protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); + private Track lastQueriedTrack; + + private void generateWaveform(WorkingBeatmap beatmap) + { + // Cancel the old query so we don't saturate the audio thread + lastQueriedTrack?.CancelWaveformQuery(); + + beatmap.Track.QueryWaveform(w => + { + if (Beatmap.Value == beatmap) + { + waveform = w; + Invalidate(Invalidation.DrawNode); + } + }); + + lastQueriedTrack = beatmap.Track; + } private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); + protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); protected override void ApplyDrawNode(DrawNode node) { var n = (WaveformDrawNode)node; n.Shader = shader; n.Texture = texture; - n.Points = points; - n.Channels = channels; n.Size = DrawSize; n.Shared = sharedData; + n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) * resolution)); + n.Channels = waveform.Channels; base.ApplyDrawNode(node); } From 01c839eda7dfeb6f68edf6b6a442e956f6715c60 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 14:55:17 +0900 Subject: [PATCH 08/83] Move WaveformDisplay into separate class and add some commenting --- .../Edit/Screens/Compose/WaveformDisplay.cs | 168 ++++++++++++++++++ osu.Game/Tests/Visual/TestCaseWaveform.cs | 149 +--------------- osu.Game/osu.Game.csproj | 1 + 3 files changed, 170 insertions(+), 148 deletions(-) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs new file mode 100644 index 0000000000..0f0c32ea0d --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -0,0 +1,168 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Audio.Track; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Batches; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.OpenGL.Vertices; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Shaders; +using osu.Framework.Graphics.Textures; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Edit.Screens.Compose +{ + public class WaveformDisplay : Drawable + { + /// + /// The beatmap which the audio waveform should be displayed for. + /// + /// + public readonly Bindable Beatmap = new Bindable(); + + private Shader shader; + private readonly Texture texture; + + public WaveformDisplay() + { + texture = Texture.WhitePixel; + Beatmap.ValueChanged += generateWaveform; + } + + [BackgroundDependencyLoader] + private void load(ShaderManager shaders) + { + shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); + } + + private float resolution = 1; + /// + /// Controls the amount of interpolation of the waveform into the width of this . + /// Points in the waveform are interpolated between 1 / pixels of this . + /// + /// + public float Resolution + { + get { return resolution; } + set + { + if (value < 0 || value > 1) + throw new ArgumentOutOfRangeException(nameof(value)); + + if (resolution == value) + return; + resolution = value; + + Invalidate(Invalidation.DrawNode); + } + } + + private Waveform waveform; + private Track lastQueriedTrack; + private void generateWaveform(WorkingBeatmap beatmap) + { + // Cancel the old query so we don't saturate the audio thread + lastQueriedTrack?.CancelWaveformQuery(); + + beatmap.Track.QueryWaveform(w => + { + if (Beatmap.Value == beatmap) + { + waveform = w; + Invalidate(Invalidation.DrawNode); + } + }); + + lastQueriedTrack = beatmap.Track; + } + + private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); + protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); + protected override void ApplyDrawNode(DrawNode node) + { + var n = (WaveformDrawNode)node; + + n.Shader = shader; + n.Texture = texture; + n.Size = DrawSize; + n.Shared = sharedData; + n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) * resolution)); + n.Channels = waveform.Channels; + + base.ApplyDrawNode(node); + } + + private class WaveformDrawNodeSharedData + { + public readonly QuadBatch VertexBatch = new QuadBatch(1000, 10); + } + + private class WaveformDrawNode : DrawNode + { + public Shader Shader; + public Texture Texture; + + public WaveformDrawNodeSharedData Shared; + + public List Points; + public Vector2 Size; + public int Channels; + + public override void Draw(Action vertexAction) + { + base.Draw(vertexAction); + + if (Points == null || Points.Count == 0) + return; + + Shader.Bind(); + Texture.TextureGL.Bind(); + + float separation = Size.X / (Points.Count - 1); + Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; + + for (int i = 0; i < Points.Count - 1; i++) + { + ColourInfo colour = DrawInfo.Colour; + Quad quadToDraw; + + switch (Channels) + { + default: + case 2: + { + float height = Size.Y / 2; + quadToDraw = new Quad( + new Vector2(i * separation, height - Points[i].Amplitude[0] * height), + new Vector2((i + 1) * separation, height - Points[i + 1].Amplitude[0] * height), + new Vector2(i * separation, height + Points[i].Amplitude[1] * height), + new Vector2((i + 1) * separation, height + Points[i + 1].Amplitude[1] * height) + ); + } + break; + case 1: + { + quadToDraw = new Quad( + new Vector2(i * separation, Size.Y - Points[i].Amplitude[0] * Size.Y), + new Vector2((i + 1) * separation, Size.Y - Points[i + 1].Amplitude[0] * Size.Y), + new Vector2(i * separation, Size.Y), + new Vector2((i + 1) * separation, Size.Y) + ); + break; + } + } + + Texture.DrawQuad(quadToDraw * DrawInfo.Matrix, colour, null, Shared.VertexBatch.Add, Vector2.Divide(localInflationAmount, quadToDraw.Size)); + } + + Shader.Unbind(); + } + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 4df7ffe367..0430185bf7 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -1,26 +1,17 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using System.Collections.Generic; using OpenTK; using OpenTK.Graphics; -using OpenTK.Graphics.ES30; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Graphics.Batches; -using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.OpenGL.Vertices; -using osu.Framework.Graphics.Primitives; -using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; +using osu.Game.Screens.Edit.Screens.Compose; namespace osu.Game.Tests.Visual { @@ -94,143 +85,5 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuGameBase osuGame) => beatmapBacking.BindTo(osuGame.Beatmap); - - private class WaveformDisplay : Drawable - { - public readonly Bindable Beatmap = new Bindable(); - - private Waveform waveform; - - private Shader shader; - private readonly Texture texture; - - public WaveformDisplay() - { - texture = Texture.WhitePixel; - Beatmap.ValueChanged += generateWaveform; - } - - [BackgroundDependencyLoader] - private void load(ShaderManager shaders) - { - shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); - } - - private float resolution = 1; - public float Resolution - { - get { return resolution; } - set - { - if (resolution == value) - return; - resolution = value; - - Invalidate(Invalidation.DrawNode); - } - } - - private Track lastQueriedTrack; - - private void generateWaveform(WorkingBeatmap beatmap) - { - // Cancel the old query so we don't saturate the audio thread - lastQueriedTrack?.CancelWaveformQuery(); - - beatmap.Track.QueryWaveform(w => - { - if (Beatmap.Value == beatmap) - { - waveform = w; - Invalidate(Invalidation.DrawNode); - } - }); - - lastQueriedTrack = beatmap.Track; - } - - private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); - protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); - protected override void ApplyDrawNode(DrawNode node) - { - var n = (WaveformDrawNode)node; - - n.Shader = shader; - n.Texture = texture; - n.Size = DrawSize; - n.Shared = sharedData; - n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) * resolution)); - n.Channels = waveform.Channels; - - base.ApplyDrawNode(node); - } - - private class WaveformDrawNodeSharedData - { - public readonly QuadBatch VertexBatch = new QuadBatch(1000, 10); - } - - private class WaveformDrawNode : DrawNode - { - public Shader Shader; - public Texture Texture; - - public WaveformDrawNodeSharedData Shared; - - public List Points; - public Vector2 Size; - public int Channels; - - public override void Draw(Action vertexAction) - { - base.Draw(vertexAction); - - if (Points == null || Points.Count == 0) - return; - - Shader.Bind(); - Texture.TextureGL.Bind(); - - float separation = Size.X / (Points.Count - 1); - Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; - - for (int i = 0; i < Points.Count - 1; i++) - { - ColourInfo colour = DrawInfo.Colour; - Quad quadToDraw; - - switch (Channels) - { - default: - case 2: - { - float height = Size.Y / 2; - quadToDraw = new Quad( - new Vector2(i * separation, height - Points[i].Amplitude[0] * height), - new Vector2((i + 1) * separation, height - Points[i + 1].Amplitude[0] * height), - new Vector2(i * separation, height + Points[i].Amplitude[1] * height), - new Vector2((i + 1) * separation, height + Points[i + 1].Amplitude[1] * height) - ); - } - break; - case 1: - { - quadToDraw = new Quad( - new Vector2(i * separation, Size.Y - Points[i].Amplitude[0] * Size.Y), - new Vector2((i + 1) * separation, Size.Y - Points[i + 1].Amplitude[0] * Size.Y), - new Vector2(i * separation, Size.Y), - new Vector2((i + 1) * separation, Size.Y) - ); - break; - } - } - - Texture.DrawQuad(quadToDraw * DrawInfo.Matrix, colour, null, Shared.VertexBatch.Add, Vector2.Divide(localInflationAmount, quadToDraw.Size)); - } - - Shader.Unbind(); - } - } - } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 56490b6119..f89810dfc1 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -620,6 +620,7 @@ + From 80e984f72dea9361b6b2d53cb9bdbe42614412d2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 18:55:38 +0900 Subject: [PATCH 09/83] Update in-line with framework --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index 0f0c32ea0d..a781e63fd9 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -92,7 +92,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose n.Texture = texture; n.Size = DrawSize; n.Shared = sharedData; - n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.TotalPoints) * resolution)); + n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.MaximumPoints) * resolution)); n.Channels = waveform.Channels; base.ApplyDrawNode(node); From 81960c7b487d2a66b134ad9554d0a639153a2483 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 18:55:45 +0900 Subject: [PATCH 10/83] CI fixes --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 2 -- osu.Game/Tests/Visual/TestCaseWaveform.cs | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index a781e63fd9..236f6b6d47 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -23,7 +23,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose /// /// The beatmap which the audio waveform should be displayed for. /// - /// public readonly Bindable Beatmap = new Bindable(); private Shader shader; @@ -46,7 +45,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose /// Controls the amount of interpolation of the waveform into the width of this . /// Points in the waveform are interpolated between 1 / pixels of this . /// - /// public float Resolution { get { return resolution; } diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 0430185bf7..eff4f5cdad 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -21,7 +21,6 @@ namespace osu.Game.Tests.Visual public TestCaseWaveform() { - MusicController mc; FillFlowContainer flow; Child = flow = new FillFlowContainer { @@ -30,7 +29,7 @@ namespace osu.Game.Tests.Visual Spacing = new Vector2(0, 10), Children = new Drawable[] { - mc = new MusicController + new MusicController { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -74,7 +73,7 @@ namespace osu.Game.Tests.Visual { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = $"Resolution: {(1f / i).ToString("0.00")}" + Text = $"Resolution: {(1f / i):0.00}" } } } From 5ca4a2d2c81600178816afb37778e40ce480f47c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 19:09:39 +0900 Subject: [PATCH 11/83] Add some nullchecks to WaveformDisplay --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index 236f6b6d47..d1550117df 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -90,8 +90,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose n.Texture = texture; n.Size = DrawSize; n.Shared = sharedData; - n.Points = waveform.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.MaximumPoints) * resolution)); - n.Channels = waveform.Channels; + n.Points = waveform?.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.MaximumPoints) * resolution)); + n.Channels = waveform?.Channels ?? 0; base.ApplyDrawNode(node); } From 1377f73b460b90f7fd4037b51536cb36a7fff92f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 21:57:29 +0900 Subject: [PATCH 12/83] Multiply resolution before clamping --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index d1550117df..e11cd667e6 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -90,7 +90,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose n.Texture = texture; n.Size = DrawSize; n.Shared = sharedData; - n.Points = waveform?.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth), 0, waveform.MaximumPoints) * resolution)); + n.Points = waveform?.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth) * Resolution, 0, waveform.MaximumPoints))); n.Channels = waveform?.Channels ?? 0; base.ApplyDrawNode(node); From ea4545299386900ba257dadcb25f7a0960901884 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 21:57:46 +0900 Subject: [PATCH 13/83] Allow resolution > 1 --- osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs index e11cd667e6..3856558a32 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose get { return resolution; } set { - if (value < 0 || value > 1) + if (value < 0) throw new ArgumentOutOfRangeException(nameof(value)); if (resolution == value) From 8427bb44d18759b516865d49fd648327e3d14c99 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 21:10:01 +0900 Subject: [PATCH 14/83] Implement basic layout for the compose screen ScrollableTimeline --- .../Screens/Compose/ScrollableTimeline.cs | 143 ++++++++++++++++++ .../Visual/TestCaseEditorComposeTimeline.cs | 46 ++++++ osu.Game/osu.Game.csproj | 2 + 3 files changed, 191 insertions(+) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs create mode 100644 osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs new file mode 100644 index 0000000000..31d207a152 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs @@ -0,0 +1,143 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Screens.Compose +{ + public class ScrollableTimeline : CompositeDrawable + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly Container timelineContainer; + private readonly WaveformDisplay waveform; + + public ScrollableTimeline() + { + Masking = true; + CornerRadius = 5; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("111") + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + new Container + { + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222") + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Y, + Width = 160, + Padding = new MarginPadding { Horizontal = 25 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 4), + Children = new[] + { + new OsuCheckbox { LabelText = "Hit Objects" }, + new OsuCheckbox { LabelText = "Hit Sounds" }, + new OsuCheckbox { LabelText = "Waveform" } + } + } + } + }, + new Container + { + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("333") + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 15 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 30), + Children = new[] + { + new SpriteIcon + { + Size = new Vector2(18), + Icon = FontAwesome.fa_search_plus, + Colour = OsuColour.FromHex("555") + }, + new SpriteIcon + { + Size = new Vector2(18), + Icon = FontAwesome.fa_search_minus, + Colour = OsuColour.FromHex("555") + }, + } + } + } + }, + timelineContainer = new Container + { + RelativeSizeAxes = Axes.Y, + Children = new Drawable[] + { + waveform = new WaveformDisplay + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("081a84") + // Resolution = 0.33f, + } + } + } + } + } + }; + + waveform.Beatmap.BindTo(Beatmap); + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return false; + + waveform.ScaleTo(new Vector2(MathHelper.Clamp(waveform.Scale.X + state.Mouse.WheelDelta, 1, 30), 1), 150, Easing.OutQuint); + return true; + } + + protected override void Update() + { + base.Update(); + + timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1); + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs new file mode 100644 index 0000000000..714c7b5d50 --- /dev/null +++ b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -0,0 +1,46 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Overlays; +using osu.Game.Screens.Edit.Screens.Compose; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseEditorComposeTimeline : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(WaveformDisplay) }; + + private readonly ScrollableTimeline timeline; + + public TestCaseEditorComposeTimeline() + { + Children = new Drawable[] + { + new MusicController + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + State = Visibility.Visible + }, + timeline = new ScrollableTimeline + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(1000, 100) + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame) + { + timeline.Beatmap.BindTo(osuGame.Beatmap); + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fde38848f1..d9c98e9b92 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -622,6 +622,7 @@ + @@ -748,6 +749,7 @@ + From e9bc5dbd0f5e18cb0520596303cf021acc3f6c5e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 4 Oct 2017 23:35:20 +0900 Subject: [PATCH 15/83] Include framework commits --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 9d142a8e00..bcd92492a9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 9d142a8e009794dfee828392e36025d08577131d +Subproject commit bcd92492a9f01178b83c2360cb9b87536435adde From 0a9d23b4bad1da2081f720a3227319d10bbd11df Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Oct 2017 14:33:39 +0900 Subject: [PATCH 16/83] Update with framework changes (removal of WaveformDisplay) --- osu-framework | 2 +- .../Screens/Compose/BeatmapWaveformGraph.cs | 33 ++++ .../Edit/Screens/Compose/WaveformDisplay.cs | 166 ------------------ osu.Game/Tests/Visual/TestCaseWaveform.cs | 2 +- osu.Game/osu.Game.csproj | 2 +- 5 files changed, 36 insertions(+), 169 deletions(-) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs delete mode 100644 osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs diff --git a/osu-framework b/osu-framework index bcd92492a9..4019939ba9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit bcd92492a9f01178b83c2360cb9b87536435adde +Subproject commit 4019939ba9f0a407880e00422280ba573ffddb24 diff --git a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs b/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs new file mode 100644 index 0000000000..ceabda5b16 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Audio; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Edit.Screens.Compose +{ + public class BeatmapWaveformGraph : CompositeDrawable + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly WaveformGraph graph; + + public BeatmapWaveformGraph() + { + InternalChild = graph = new WaveformGraph { RelativeSizeAxes = Axes.Both }; + Beatmap.ValueChanged += b => graph.Track = b.Track; + } + + /// + /// Gets or sets the . + /// + public float Resolution + { + get { return graph.Resolution; } + set { graph.Resolution = value; } + } + } +} diff --git a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs b/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs deleted file mode 100644 index 3856558a32..0000000000 --- a/osu.Game/Screens/Edit/Screens/Compose/WaveformDisplay.cs +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Collections.Generic; -using OpenTK; -using osu.Framework.Allocation; -using osu.Framework.Audio.Track; -using osu.Framework.Configuration; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Batches; -using osu.Framework.Graphics.Colour; -using osu.Framework.Graphics.OpenGL.Vertices; -using osu.Framework.Graphics.Primitives; -using osu.Framework.Graphics.Shaders; -using osu.Framework.Graphics.Textures; -using osu.Game.Beatmaps; - -namespace osu.Game.Screens.Edit.Screens.Compose -{ - public class WaveformDisplay : Drawable - { - /// - /// The beatmap which the audio waveform should be displayed for. - /// - public readonly Bindable Beatmap = new Bindable(); - - private Shader shader; - private readonly Texture texture; - - public WaveformDisplay() - { - texture = Texture.WhitePixel; - Beatmap.ValueChanged += generateWaveform; - } - - [BackgroundDependencyLoader] - private void load(ShaderManager shaders) - { - shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); - } - - private float resolution = 1; - /// - /// Controls the amount of interpolation of the waveform into the width of this . - /// Points in the waveform are interpolated between 1 / pixels of this . - /// - public float Resolution - { - get { return resolution; } - set - { - if (value < 0) - throw new ArgumentOutOfRangeException(nameof(value)); - - if (resolution == value) - return; - resolution = value; - - Invalidate(Invalidation.DrawNode); - } - } - - private Waveform waveform; - private Track lastQueriedTrack; - private void generateWaveform(WorkingBeatmap beatmap) - { - // Cancel the old query so we don't saturate the audio thread - lastQueriedTrack?.CancelWaveformQuery(); - - beatmap.Track.QueryWaveform(w => - { - if (Beatmap.Value == beatmap) - { - waveform = w; - Invalidate(Invalidation.DrawNode); - } - }); - - lastQueriedTrack = beatmap.Track; - } - - private readonly WaveformDrawNodeSharedData sharedData = new WaveformDrawNodeSharedData(); - protected override DrawNode CreateDrawNode() => new WaveformDrawNode(); - protected override void ApplyDrawNode(DrawNode node) - { - var n = (WaveformDrawNode)node; - - n.Shader = shader; - n.Texture = texture; - n.Size = DrawSize; - n.Shared = sharedData; - n.Points = waveform?.Generate((int)(MathHelper.Clamp(Math.Ceiling(DrawWidth) * Resolution, 0, waveform.MaximumPoints))); - n.Channels = waveform?.Channels ?? 0; - - base.ApplyDrawNode(node); - } - - private class WaveformDrawNodeSharedData - { - public readonly QuadBatch VertexBatch = new QuadBatch(1000, 10); - } - - private class WaveformDrawNode : DrawNode - { - public Shader Shader; - public Texture Texture; - - public WaveformDrawNodeSharedData Shared; - - public List Points; - public Vector2 Size; - public int Channels; - - public override void Draw(Action vertexAction) - { - base.Draw(vertexAction); - - if (Points == null || Points.Count == 0) - return; - - Shader.Bind(); - Texture.TextureGL.Bind(); - - float separation = Size.X / (Points.Count - 1); - Vector2 localInflationAmount = new Vector2(0, 1) * DrawInfo.MatrixInverse.ExtractScale().Xy; - - for (int i = 0; i < Points.Count - 1; i++) - { - ColourInfo colour = DrawInfo.Colour; - Quad quadToDraw; - - switch (Channels) - { - default: - case 2: - { - float height = Size.Y / 2; - quadToDraw = new Quad( - new Vector2(i * separation, height - Points[i].Amplitude[0] * height), - new Vector2((i + 1) * separation, height - Points[i + 1].Amplitude[0] * height), - new Vector2(i * separation, height + Points[i].Amplitude[1] * height), - new Vector2((i + 1) * separation, height + Points[i + 1].Amplitude[1] * height) - ); - } - break; - case 1: - { - quadToDraw = new Quad( - new Vector2(i * separation, Size.Y - Points[i].Amplitude[0] * Size.Y), - new Vector2((i + 1) * separation, Size.Y - Points[i + 1].Amplitude[0] * Size.Y), - new Vector2(i * separation, Size.Y), - new Vector2((i + 1) * separation, Size.Y) - ); - break; - } - } - - Texture.DrawQuad(quadToDraw * DrawInfo.Matrix, colour, null, Shared.VertexBatch.Add, Vector2.Divide(localInflationAmount, quadToDraw.Size)); - } - - Shader.Unbind(); - } - } - } -} diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index eff4f5cdad..531005af10 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual for (int i = 1; i <= 16; i *= 2) { - var newDisplay = new WaveformDisplay + var newDisplay = new BeatmapWaveformGraph { RelativeSizeAxes = Axes.Both, Resolution = 1f / i diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f89810dfc1..106e4bfc3b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -266,6 +266,7 @@ + @@ -620,7 +621,6 @@ - From 7926757898ea4b12579f6fae8abce00e89a754ca Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Oct 2017 14:33:49 +0900 Subject: [PATCH 17/83] Remove unneeded parens --- osu.Game/Tests/Visual/TestCaseWaveform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 531005af10..4a6e93c7bf 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -73,7 +73,7 @@ namespace osu.Game.Tests.Visual { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = $"Resolution: {(1f / i):0.00}" + Text = $"Resolution: {1f / i:0.00}" } } } From 134e1299bb4a71e219edfd7746df79fa33cdc888 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 5 Oct 2017 19:23:58 +0800 Subject: [PATCH 18/83] Update spm value when spinner not active. --- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 04bbd8b871..b36fe4287e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -112,20 +112,20 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces currentRotation += thisAngle - lastAngle; RotationAbsolute += Math.Abs(thisAngle - lastAngle); - if (rotations.Count > 0) - { - float rotationFrom = rotations.Peek(); - double timeFrom = times.Peek(); - while (Time.Current - times.Peek() > spm_count_duration) - { - rotationFrom = rotations.Dequeue(); - timeFrom = times.Dequeue(); - } - SpinsPerMinute = (currentRotation - rotationFrom) / (Time.Current - timeFrom) * 1000 * 60 / 360; - } } lastAngle = thisAngle; + if (rotations.Count > 0) + { + float rotationFrom = rotations.Peek(); + double timeFrom = times.Peek(); + while (Time.Current - times.Peek() > spm_count_duration) + { + rotationFrom = rotations.Dequeue(); + timeFrom = times.Dequeue(); + } + SpinsPerMinute = (currentRotation - rotationFrom) / (Time.Current - timeFrom) * 1000 * 60 / 360; + } rotations.Enqueue(currentRotation); times.Enqueue(Time.Current); From 24187cc53a02442c7bf747f371ac7ff8e502ca5d Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 5 Oct 2017 19:55:20 +0800 Subject: [PATCH 19/83] Move spm text out of scaled parts. --- .../Objects/Drawables/DrawableSpinner.cs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 6b9e91d4f4..4bdb789471 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -99,24 +99,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Origin = Anchor.Centre, }, circleContainer.CreateProxy(), - spmText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - Text = @"0", - Font = @"Venera", - TextSize = 24, - Y = 120 - }, - new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.TopCentre, - Text = @"SPINS PER MINUTE", - Font = @"Venera", - TextSize = 12, - Y = 125 - }, ticks = new SpinnerTicks { Anchor = Anchor.Centre, @@ -124,6 +106,24 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables }, } }, + spmText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + Text = @"0", + Font = @"Venera", + TextSize = 24, + Y = 120 + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.TopCentre, + Text = @"SPINS PER MINUTE", + Font = @"Venera", + TextSize = 12, + Y = 125 + }, }; } From ee8746b848b82577f031365327db804dc63b39a7 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 5 Oct 2017 20:07:33 +0800 Subject: [PATCH 20/83] Fade in spm texts. --- .../Objects/Drawables/DrawableSpinner.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 4bdb789471..6a8976ea98 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -31,7 +31,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly Container circleContainer; private readonly CirclePiece circle; private readonly GlowPiece glow; - private readonly OsuSpriteText spmText; + private readonly OsuSpriteText spmText, spmLabel; + + private bool spmShown; private readonly SpriteIcon symbol; @@ -113,16 +115,18 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Text = @"0", Font = @"Venera", TextSize = 24, - Y = 120 + Y = 120, + Alpha = 0 }, - new OsuSpriteText + spmLabel = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.TopCentre, Text = @"SPINS PER MINUTE", Font = @"Venera", TextSize = 12, - Y = 125 + Y = 125, + Alpha = 0 }, }; } @@ -178,6 +182,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void Update() { disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton); + if (!spmShown && disc.Tracking) + { + spmShown = true; + spmText.FadeIn(TIME_FADEIN); + spmLabel.FadeIn(TIME_FADEIN); + } base.Update(); } From 29f9c8143df0c01786843caf5d158f98040b30ea Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 5 Oct 2017 20:08:45 +0800 Subject: [PATCH 21/83] Use RotationAbsolute to calculate spm. --- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index b36fe4287e..913305c6aa 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -124,9 +124,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces rotationFrom = rotations.Dequeue(); timeFrom = times.Dequeue(); } - SpinsPerMinute = (currentRotation - rotationFrom) / (Time.Current - timeFrom) * 1000 * 60 / 360; + SpinsPerMinute = (RotationAbsolute - rotationFrom) / (Time.Current - timeFrom) * 1000 * 60 / 360; } - rotations.Enqueue(currentRotation); + rotations.Enqueue(RotationAbsolute); times.Enqueue(Time.Current); if (Complete && updateCompleteTick()) From 404c4917dc7689903e649c5dae150b2b8b11b819 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 6 Oct 2017 18:35:51 +0800 Subject: [PATCH 22/83] Use single queue for spinning record. --- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 913305c6aa..8af7de88e4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -79,8 +79,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private float currentRotation; public float RotationAbsolute; public double SpinsPerMinute; - private readonly Queue rotations = new Queue(); - private readonly Queue times = new Queue(); + + private struct RotationRecord + { + public float Rotation; + public double Time; + } + + private readonly Queue records = new Queue(); private const double spm_count_duration = 595; // not using hundreds to avoid frame rounding issues private int completeTick; @@ -115,19 +121,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } lastAngle = thisAngle; - if (rotations.Count > 0) + if (records.Count > 0) { - float rotationFrom = rotations.Peek(); - double timeFrom = times.Peek(); - while (Time.Current - times.Peek() > spm_count_duration) - { - rotationFrom = rotations.Dequeue(); - timeFrom = times.Dequeue(); - } - SpinsPerMinute = (RotationAbsolute - rotationFrom) / (Time.Current - timeFrom) * 1000 * 60 / 360; + var record = records.Peek(); + while (Time.Current - records.Peek().Time > spm_count_duration) + record = records.Dequeue(); + SpinsPerMinute = (RotationAbsolute - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; } - rotations.Enqueue(RotationAbsolute); - times.Enqueue(Time.Current); + records.Enqueue(new RotationRecord { Rotation = RotationAbsolute, Time = Time.Current }); if (Complete && updateCompleteTick()) { From a876ab9b90f87780a71ccc7ff48d77ea9b5530c4 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 7 Oct 2017 15:31:42 +0800 Subject: [PATCH 23/83] Move spm counter to a seperated control. --- .../Objects/Drawables/DrawableSpinner.cs | 24 +++-------- .../Drawables/Pieces/SpinnerSpmCounter.cs | 42 +++++++++++++++++++ .../osu.Game.Rulesets.Osu.csproj | 1 + 3 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 6a8976ea98..97c2594f69 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -24,6 +24,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly SpinnerDisc disc; private readonly SpinnerTicks ticks; + private readonly SpinnerSpmCounter spmCounter; private readonly Container mainContainer; @@ -31,7 +32,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly Container circleContainer; private readonly CirclePiece circle; private readonly GlowPiece glow; - private readonly OsuSpriteText spmText, spmLabel; private bool spmShown; @@ -108,26 +108,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables }, } }, - spmText = new OsuSpriteText + spmCounter = new SpinnerSpmCounter { Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, - Text = @"0", - Font = @"Venera", - TextSize = 24, + Origin = Anchor.Centre, Y = 120, Alpha = 0 - }, - spmLabel = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.TopCentre, - Text = @"SPINS PER MINUTE", - Font = @"Venera", - TextSize = 12, - Y = 125, - Alpha = 0 - }, + } }; } @@ -185,8 +172,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (!spmShown && disc.Tracking) { spmShown = true; - spmText.FadeIn(TIME_FADEIN); - spmLabel.FadeIn(TIME_FADEIN); + spmCounter.FadeIn(TIME_FADEIN); } base.Update(); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs new file mode 100644 index 0000000000..17b2a813a5 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces +{ + public class SpinnerSpmCounter : Container + { + private readonly OsuSpriteText spmText; + public SpinnerSpmCounter() + { + Children = new Drawable[] + { + spmText = new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = @"0", + Font = @"Venera", + TextSize = 24 + }, + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = @"SPINS PER MINUTE", + Font = @"Venera", + TextSize = 12, + Y = 30 + } + }; + } + } +} diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index 300000754c..6bad45b8ca 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -68,6 +68,7 @@ + From 09093013a7a0a639198741788906afaaff1e8b15 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 7 Oct 2017 15:42:10 +0800 Subject: [PATCH 24/83] Move spm calculation into counter. --- .../Objects/Drawables/DrawableSpinner.cs | 4 +- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 20 ---------- .../Drawables/Pieces/SpinnerSpmCounter.cs | 37 +++++++++++++++++-- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 97c2594f69..0fded6ec1a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -14,7 +13,6 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Allocation; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Screens.Ranking; -using osu.Game.Graphics.Sprites; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -184,7 +182,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables circle.Rotation = disc.Rotation; ticks.Rotation = disc.Rotation; - spmText.Text = Math.Truncate(disc.SpinsPerMinute).ToString(@"#0"); + spmCounter.SetRotation(disc.RotationAbsolute); float relativeCircleScale = spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight; disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 8af7de88e4..ca75a61738 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; @@ -78,17 +77,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private float lastAngle; private float currentRotation; public float RotationAbsolute; - public double SpinsPerMinute; - - private struct RotationRecord - { - public float Rotation; - public double Time; - } - - private readonly Queue records = new Queue(); - private const double spm_count_duration = 595; // not using hundreds to avoid frame rounding issues - private int completeTick; private bool updateCompleteTick() => completeTick != (completeTick = (int)(RotationAbsolute / 360)); @@ -121,14 +109,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } lastAngle = thisAngle; - if (records.Count > 0) - { - var record = records.Peek(); - while (Time.Current - records.Peek().Time > spm_count_duration) - record = records.Dequeue(); - SpinsPerMinute = (RotationAbsolute - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; - } - records.Enqueue(new RotationRecord { Rotation = RotationAbsolute, Time = Time.Current }); if (Complete && updateCompleteTick()) { diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs index 17b2a813a5..57ec516484 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs @@ -3,9 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -38,5 +35,39 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } }; } + + private double spm; + public double SpinsPerMinute + { + get { return spm; } + private set + { + if (value == spm) return; + spm = value; + spmText.Text = Math.Truncate(value).ToString(@"#0"); + } + } + + private struct RotationRecord + { + public float Rotation; + public double Time; + } + + private readonly Queue records = new Queue(); + private const double spm_count_duration = 595; // not using hundreds to avoid frame rounding issues + + + public void SetRotation(float currentRotation) + { + if (records.Count > 0) + { + var record = records.Peek(); + while (Time.Current - records.Peek().Time > spm_count_duration) + record = records.Dequeue(); + SpinsPerMinute = (currentRotation - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; + } + records.Enqueue(new RotationRecord { Rotation = currentRotation, Time = Time.Current }); + } } } From 6c5c734ff1d07188812c75ad98bbb9e40fd396c1 Mon Sep 17 00:00:00 2001 From: Bang Sunghwan Date: Sun, 8 Oct 2017 09:42:09 +0900 Subject: [PATCH 25/83] Trim end of line Fix ArgumentOutOfRangeException when parsing http://osu.ppy.sh/osu/1004136 --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 21fee0f465..b4d5e8f13a 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -611,7 +611,7 @@ namespace osu.Game.Beatmaps.Formats CommandTimelineGroup timelineGroup = null; string line; - while ((line = stream.ReadLine()) != null) + while ((line = stream.ReadLine()?.TrimEnd()) != null) { if (string.IsNullOrEmpty(line)) continue; From bd9f2db477d64aff156b1150949af5e1b6ec0ca2 Mon Sep 17 00:00:00 2001 From: Bang Sunghwan Date: Sun, 8 Oct 2017 17:30:21 +0900 Subject: [PATCH 26/83] Trim line --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index b4d5e8f13a..353959582b 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -611,7 +611,7 @@ namespace osu.Game.Beatmaps.Formats CommandTimelineGroup timelineGroup = null; string line; - while ((line = stream.ReadLine()?.TrimEnd()) != null) + while ((line = stream.ReadLine()?.Trim()) != null) { if (string.IsNullOrEmpty(line)) continue; From 19b38983dffa148f09441a20185dd0f8b6f70521 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 9 Oct 2017 17:18:11 +0900 Subject: [PATCH 27/83] Update in-line with framework --- osu-framework | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 10 ++++++++++ osu.Game/Beatmaps/WorkingBeatmap.cs | 14 ++++++++++++++ .../Edit/Screens/Compose/BeatmapWaveformGraph.cs | 2 +- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/osu-framework b/osu-framework index 4019939ba9..38cf96c899 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 4019939ba9f0a407880e00422280ba573ffddb24 +Subproject commit 38cf96c8994ad41ae6aa86de6bfe09fd5fa9e1b6 diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index a1b678392b..5fcdab11f8 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -573,6 +573,16 @@ namespace osu.Game.Beatmaps } catch { return new TrackVirtual(); } } + + protected override Waveform GetWaveform() + { + try + { + var trackData = store.GetStream(getPathForFile(Metadata.AudioFile)); + return trackData == null ? new Waveform() : new Waveform(trackData); + } + catch { return new Waveform(); } + } } /// diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 277846ee80..959e71d48d 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -43,6 +43,7 @@ namespace osu.Game.Beatmaps protected abstract Beatmap GetBeatmap(); protected abstract Texture GetBackground(); protected abstract Track GetTrack(); + protected virtual Waveform GetWaveform() => new Waveform(); private Beatmap beatmap; private readonly object beatmapLock = new object(); @@ -96,6 +97,17 @@ namespace osu.Game.Beatmaps } } + private Waveform waveform; + private readonly object waveformLock = new object(); + public Waveform Waveform + { + get + { + lock (waveformLock) + return waveform ?? (waveform = GetWaveform()); + } + } + public bool TrackLoaded => track != null; public void TransferTo(WorkingBeatmap other) @@ -114,6 +126,8 @@ namespace osu.Game.Beatmaps { background?.Dispose(); background = null; + + waveform?.Dispose(); } public void DisposeTrack() diff --git a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs b/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs index ceabda5b16..f204c8c525 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose public BeatmapWaveformGraph() { InternalChild = graph = new WaveformGraph { RelativeSizeAxes = Axes.Both }; - Beatmap.ValueChanged += b => graph.Track = b.Track; + Beatmap.ValueChanged += b => graph.Waveform = b.Waveform; } /// From 222d0c86942416d2999f217a2a1b1ada26189c64 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Oct 2017 17:52:48 +0900 Subject: [PATCH 28/83] Fix visual regressions in MedalOverlay --- osu.Game/Overlays/MedalOverlay.cs | 2 +- osu.Game/Overlays/MedalSplash/DrawableMedal.cs | 9 ++++++--- osu.Game/Tests/Visual/TestCaseMedalOverlay.cs | 9 +++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/MedalOverlay.cs b/osu.Game/Overlays/MedalOverlay.cs index 880b607e78..776f2ffadb 100644 --- a/osu.Game/Overlays/MedalOverlay.cs +++ b/osu.Game/Overlays/MedalOverlay.cs @@ -159,7 +159,7 @@ namespace osu.Game.Overlays { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Both, }); } diff --git a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs index 3ac8af7b2b..ea51471199 100644 --- a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs +++ b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs @@ -90,6 +90,7 @@ namespace osu.Game.Overlays.MedalSplash }, description = new TextFlowContainer { + TextAnchor = Anchor.TopCentre, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, @@ -115,15 +116,16 @@ namespace osu.Game.Overlays.MedalSplash medalSprite.Texture = textures.Get(medal.ImageUrl); medalGlow.Texture = textures.Get(@"MedalSplash/medal-glow"); description.Colour = colours.BlueLight; - - unlocked.Position = new Vector2(0f, medalContainer.Size.Y / 2 + 10); - infoFlow.Position = new Vector2(0f, unlocked.Position.Y + 90); } protected override void LoadComplete() { base.LoadComplete(); + updateState(); + + unlocked.Position = new Vector2(0f, medalContainer.DrawSize.Y / 2 + 10); + infoFlow.Position = new Vector2(0f, unlocked.Position.Y + 90); } public DisplayState State @@ -172,6 +174,7 @@ namespace osu.Game.Overlays.MedalSplash this.ScaleTo(scale_when_full, duration, Easing.OutExpo); this.MoveToY(MedalOverlay.DISC_SIZE / 2 - 60, duration, Easing.OutExpo); + unlocked.Show(); name.FadeInFromZero(duration + 100); description.FadeInFromZero(duration * 2); break; diff --git a/osu.Game/Tests/Visual/TestCaseMedalOverlay.cs b/osu.Game/Tests/Visual/TestCaseMedalOverlay.cs index fecf37538b..9a26eefd63 100644 --- a/osu.Game/Tests/Visual/TestCaseMedalOverlay.cs +++ b/osu.Game/Tests/Visual/TestCaseMedalOverlay.cs @@ -1,7 +1,10 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using osu.Game.Overlays; +using osu.Game.Overlays.MedalSplash; using osu.Game.Users; namespace osu.Game.Tests.Visual @@ -10,6 +13,12 @@ namespace osu.Game.Tests.Visual { public override string Description => @"medal get!"; + public override IReadOnlyList RequiredTypes => new[] + { + typeof(MedalOverlay), + typeof(DrawableMedal), + }; + public TestCaseMedalOverlay() { AddStep(@"display", () => From 29c2a2979852f00ddafbf1d58560a681c2a2ea78 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 9 Oct 2017 18:47:12 +0900 Subject: [PATCH 29/83] Fix trimming too early in OsuLegacyDecoder crashing storyboards --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 353959582b..a70faf5be6 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -611,9 +611,9 @@ namespace osu.Game.Beatmaps.Formats CommandTimelineGroup timelineGroup = null; string line; - while ((line = stream.ReadLine()?.Trim()) != null) + while ((line = stream.ReadLine()) != null) { - if (string.IsNullOrEmpty(line)) + if (string.IsNullOrEmpty(line.Trim())) continue; if (line.StartsWith("//")) @@ -679,10 +679,12 @@ namespace osu.Game.Beatmaps.Formats private KeyValuePair splitKeyVal(string line, char separator) { + var split = line.Trim().Split(separator); + return new KeyValuePair ( - line.Remove(line.IndexOf(separator)).Trim(), - line.Substring(line.IndexOf(separator) + 1).Trim() + split[0].Trim(), + split.Length > 1 ? split[1].Trim() : string.Empty ); } From 26215b448898a49af66749a8e4bbafe36aa45818 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Oct 2017 19:42:55 +0900 Subject: [PATCH 30/83] Create an abstract base class for drawable catch objects --- .../Drawable/DrawableCatchHitObject.cs | 50 +++++++++++ .../Objects/Drawable/DrawableFruit.cs | 82 +++++-------------- .../osu.Game.Rulesets.Catch.csproj | 1 + 3 files changed, 72 insertions(+), 61 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs new file mode 100644 index 0000000000..fbb93e51a7 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Graphics; +using osu.Framework.MathUtils; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + public abstract class DrawableCatchHitObject : DrawableScrollingHitObject + { + protected DrawableCatchHitObject(CatchBaseHit hitObject) + : base(hitObject) + { + Origin = Anchor.Centre; + RelativePositionAxes = Axes.Both; + X = hitObject.X; + Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; + } + + public Func CheckPosition; + + protected override void CheckForJudgements(bool userTriggered, double timeOffset) + { + if (timeOffset > 0) + AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss }); + } + + private const float preempt = 1000; + + protected override void UpdateState(ArmedState state) + { + using (BeginAbsoluteSequence(HitObject.StartTime - preempt)) + { + // animation + this.FadeIn(200); + } + + switch (state) + { + case ArmedState.Miss: + using (BeginAbsoluteSequence(HitObject.StartTime, true)) + this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out); + break; + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index e0c9f0c028..8e2618c64c 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -1,72 +1,29 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.MathUtils; using osu.Game.Graphics; -using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Objects.Drawables; using OpenTK; using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { - public class DrawableFruit : DrawableScrollingHitObject + public class DrawableFruit : DrawableCatchHitObject { private const float pulp_size = 20; - private class Pulp : Circle, IHasAccentColour - { - public Pulp() - { - Size = new Vector2(pulp_size); - - Blending = BlendingMode.Additive; - Colour = Color4.White.Opacity(0.9f); - } - - private Color4 accentColour; - public Color4 AccentColour - { - get { return accentColour; } - set - { - accentColour = value; - - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Radius = 5, - Colour = accentColour.Lighten(100), - }; - } - } - } - - public DrawableFruit(CatchBaseHit h) : base(h) { - Origin = Anchor.Centre; Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f); - - RelativePositionAxes = Axes.Both; - X = h.X; - AccentColour = HitObject.ComboColour; - Masking = false; - - Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; } - public Func CheckPosition; - [BackgroundDependencyLoader] private void load() { @@ -115,28 +72,31 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable }; } - private const float preempt = 1000; - - protected override void CheckForJudgements(bool userTriggered, double timeOffset) + private class Pulp : Circle, IHasAccentColour { - if (timeOffset > 0) - AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss }); - } - - protected override void UpdateState(ArmedState state) - { - using (BeginAbsoluteSequence(HitObject.StartTime - preempt)) + public Pulp() { - // animation - this.FadeIn(200); + Size = new Vector2(pulp_size); + + Blending = BlendingMode.Additive; + Colour = Color4.White.Opacity(0.9f); } - switch (state) + private Color4 accentColour; + public Color4 AccentColour { - case ArmedState.Miss: - using (BeginAbsoluteSequence(HitObject.StartTime, true)) - this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out); - break; + get { return accentColour; } + set + { + accentColour = value; + + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Radius = 5, + Colour = accentColour.Lighten(100), + }; + } } } } diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 718ae32a17..f614ec647f 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -50,6 +50,7 @@ + From d5892cf54e7632ddfb7f410aeff1123f1a4bc4fd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Oct 2017 20:17:05 +0900 Subject: [PATCH 31/83] Add a bool to specify whether judgements should be visible for certain DrawableHitObjects --- .../Objects/Drawables/DrawableSliderTick.cs | 2 ++ osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 3 +++ .../Objects/Drawables/DrawableDrumRollTick.cs | 2 ++ osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 2 +- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 5 +++++ 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index 53b3427fc4..8a96640b1e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -22,6 +22,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public override bool RemoveWhenNotAlive => false; + public override bool DisplayJudgement => false; + public DrawableSliderTick(SliderTick sliderTick) : base(sliderTick) { this.sliderTick = sliderTick; diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 1bb4e8493b..89f6a4e255 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -91,6 +91,9 @@ namespace osu.Game.Rulesets.Osu.UI var osuJudgement = (OsuJudgement)judgement; var osuObject = (OsuHitObject)judgedObject.HitObject; + if (!judgedObject.DisplayJudgement) + return; + DrawableOsuJudgement explosion = new DrawableOsuJudgement(osuJudgement) { Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 8ac67ba0a6..e662f61bbe 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -21,6 +21,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables FillMode = FillMode.Fit; } + public override bool DisplayJudgement => false; + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index d9a216bbfc..136da8a532 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -221,7 +221,7 @@ namespace osu.Game.Rulesets.Taiko.UI public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { - if (judgementContainer.FirstOrDefault(j => j.JudgedObject == judgedObject) == null) + if (judgedObject.DisplayJudgement && judgementContainer.FirstOrDefault(j => j.JudgedObject == judgedObject) == null) { judgementContainer.Add(new DrawableTaikoJudgement(judgedObject, judgement) { diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 7a26a53c2a..bcd6734af6 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -25,6 +25,11 @@ namespace osu.Game.Rulesets.Objects.Drawables /// public virtual Color4 AccentColour { get; set; } = Color4.Gray; + /// + /// Whether a visible judgement should be displayed when this representation is hit. + /// + public virtual bool DisplayJudgement => true; + protected DrawableHitObject(HitObject hitObject) { HitObject = hitObject; From 074a1db4a1969f64f29035be9340df947a710eac Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 12:45:27 +0900 Subject: [PATCH 32/83] Implement scrolling and better zoom --- .../Screens/Compose/ScrollableTimeline.cs | 72 ++++++++++++------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs index 7b2b52a239..5fc47958e2 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs @@ -17,8 +17,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { public readonly Bindable Beatmap = new Bindable(); - private readonly Container timelineContainer; - private readonly BeatmapWaveformGraph waveform; + private readonly ScrollingTimelineContainer timelineContainer; public ScrollableTimeline() { @@ -104,33 +103,12 @@ namespace osu.Game.Screens.Edit.Screens.Compose } } }, - timelineContainer = new Container - { - RelativeSizeAxes = Axes.Y, - Children = new Drawable[] - { - waveform = new BeatmapWaveformGraph - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("081a84") - // Resolution = 0.33f, - } - } - } + timelineContainer = new ScrollingTimelineContainer { RelativeSizeAxes = Axes.Y } } } }; - waveform.Beatmap.BindTo(Beatmap); - } - - protected override bool OnWheel(InputState state) - { - if (!state.Keyboard.ControlPressed) - return false; - - waveform.ScaleTo(new Vector2(MathHelper.Clamp(waveform.Scale.X + state.Mouse.WheelDelta, 1, 30), 1), 150, Easing.OutQuint); - return true; + timelineContainer.Beatmap.BindTo(Beatmap); } protected override void Update() @@ -139,5 +117,49 @@ namespace osu.Game.Screens.Edit.Screens.Compose timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1); } + + private class ScrollingTimelineContainer : ScrollContainer + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly BeatmapWaveformGraph graph; + + public ScrollingTimelineContainer() + : base(Direction.Horizontal) + { + Masking = true; + + Add(graph = new BeatmapWaveformGraph + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222"), + Depth = float.MaxValue, + }); + + Content.AutoSizeAxes = Axes.None; + Content.RelativeSizeAxes = Axes.Both; + + graph.Beatmap.BindTo(Beatmap); + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return base.OnWheel(state); + + float newSize = MathHelper.Clamp(Content.Size.X + state.Mouse.WheelDelta, 1, 30); + + float relativeTarget = MathHelper.Clamp(Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X, 0, 1); + float newAbsoluteTarget = relativeTarget * newSize * Content.DrawSize.X / Content.Size.X; + + float mousePos = MathHelper.Clamp(ToLocalSpace(state.Mouse.NativeState.Position).X, 0, DrawSize.X); + float scrollPos = newAbsoluteTarget - mousePos; + + Content.ResizeWidthTo(newSize); + ScrollTo(scrollPos, false); + + return true; + } + } } } From 166194e6b6f587c04cd0132a08dafab703416542 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 15:09:26 +0900 Subject: [PATCH 33/83] Further logic simplification --- .../Screens/Compose/ScrollableTimeline.cs | 55 ++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs index 5fc47958e2..b5445883ab 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -142,20 +143,60 @@ namespace osu.Game.Screens.Edit.Screens.Compose graph.Beatmap.BindTo(Beatmap); } + private float minZoom = 1; + public float MinZoom + { + get { return minZoom; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (minZoom == value) + return; + minZoom = value; + } + } + + private float maxZoom = 30; + public float MaxZoom + { + get { return maxZoom; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (maxZoom == value) + return; + maxZoom = value; + } + } + + private float zoom = 1; + public float Zoom + { + get { return zoom; } + set + { + value = MathHelper.Clamp(value, MinZoom, MaxZoom); + if (zoom == value) + return; + zoom = value; + + Content.ResizeWidthTo(Zoom); + } + } + protected override bool OnWheel(InputState state) { if (!state.Keyboard.ControlPressed) return base.OnWheel(state); - float newSize = MathHelper.Clamp(Content.Size.X + state.Mouse.WheelDelta, 1, 30); + float relativeContentPosition = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; + float position = ToLocalSpace(state.Mouse.NativeState.Position).X; - float relativeTarget = MathHelper.Clamp(Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X, 0, 1); - float newAbsoluteTarget = relativeTarget * newSize * Content.DrawSize.X / Content.Size.X; + Zoom += state.Mouse.WheelDelta; - float mousePos = MathHelper.Clamp(ToLocalSpace(state.Mouse.NativeState.Position).X, 0, DrawSize.X); - float scrollPos = newAbsoluteTarget - mousePos; - - Content.ResizeWidthTo(newSize); + float scrollPos = Content.DrawSize.X * relativeContentPosition - position; ScrollTo(scrollPos, false); return true; From 1cf8c0284a3503c09c0f486c5d6b12f0f937f5ab Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 15:22:32 +0900 Subject: [PATCH 34/83] Re-namespace a few classes --- .../{ => Timeline}/BeatmapWaveformGraph.cs | 2 +- .../{ => Timeline}/ScrollableTimeline.cs | 86 +------------ .../Timeline/ScrollingTimelineContainer.cs | 113 ++++++++++++++++++ .../Visual/TestCaseEditorComposeTimeline.cs | 3 +- osu.Game/Tests/Visual/TestCaseWaveform.cs | 1 + osu.Game/osu.Game.csproj | 5 +- 6 files changed, 121 insertions(+), 89 deletions(-) rename osu.Game/Screens/Edit/Screens/Compose/{ => Timeline}/BeatmapWaveformGraph.cs (91%) rename osu.Game/Screens/Edit/Screens/Compose/{ => Timeline}/ScrollableTimeline.cs (63%) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.cs similarity index 91% rename from osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs rename to osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.cs index f204c8c525..5acee675e8 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/BeatmapWaveformGraph.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; -namespace osu.Game.Screens.Edit.Screens.Compose +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public class BeatmapWaveformGraph : CompositeDrawable { diff --git a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs similarity index 63% rename from osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs rename to osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index b5445883ab..5999241f61 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -12,7 +12,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; -namespace osu.Game.Screens.Edit.Screens.Compose +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public class ScrollableTimeline : CompositeDrawable { @@ -118,89 +118,5 @@ namespace osu.Game.Screens.Edit.Screens.Compose timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1); } - - private class ScrollingTimelineContainer : ScrollContainer - { - public readonly Bindable Beatmap = new Bindable(); - - private readonly BeatmapWaveformGraph graph; - - public ScrollingTimelineContainer() - : base(Direction.Horizontal) - { - Masking = true; - - Add(graph = new BeatmapWaveformGraph - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222"), - Depth = float.MaxValue, - }); - - Content.AutoSizeAxes = Axes.None; - Content.RelativeSizeAxes = Axes.Both; - - graph.Beatmap.BindTo(Beatmap); - } - - private float minZoom = 1; - public float MinZoom - { - get { return minZoom; } - set - { - if (value <= 0) - throw new ArgumentOutOfRangeException(nameof(value)); - if (minZoom == value) - return; - minZoom = value; - } - } - - private float maxZoom = 30; - public float MaxZoom - { - get { return maxZoom; } - set - { - if (value <= 0) - throw new ArgumentOutOfRangeException(nameof(value)); - if (maxZoom == value) - return; - maxZoom = value; - } - } - - private float zoom = 1; - public float Zoom - { - get { return zoom; } - set - { - value = MathHelper.Clamp(value, MinZoom, MaxZoom); - if (zoom == value) - return; - zoom = value; - - Content.ResizeWidthTo(Zoom); - } - } - - protected override bool OnWheel(InputState state) - { - if (!state.Keyboard.ControlPressed) - return base.OnWheel(state); - - float relativeContentPosition = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; - float position = ToLocalSpace(state.Mouse.NativeState.Position).X; - - Zoom += state.Mouse.WheelDelta; - - float scrollPos = Content.DrawSize.X * relativeContentPosition - position; - ScrollTo(scrollPos, false); - - return true; - } - } } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs new file mode 100644 index 0000000000..f4795452d5 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -0,0 +1,113 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using OpenTK; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Game.Beatmaps; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + internal class ScrollingTimelineContainer : ScrollContainer + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly BeatmapWaveformGraph graph; + + public ScrollingTimelineContainer() + : base(Direction.Horizontal) + { + Masking = true; + + Add(graph = new BeatmapWaveformGraph + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222"), + Depth = float.MaxValue, + }); + + Content.AutoSizeAxes = Axes.None; + Content.RelativeSizeAxes = Axes.Both; + + graph.Beatmap.BindTo(Beatmap); + } + + private float minZoom = 1; + /// + /// The minimum zoom level allowed. + /// + public float MinZoom + { + get { return minZoom; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (minZoom == value) + return; + minZoom = value; + + // Update the zoom level + Zoom = Zoom; + } + } + + private float maxZoom = 30; + /// + /// The maximum zoom level allowed. + /// + public float MaxZoom + { + get { return maxZoom; } + set + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value)); + if (maxZoom == value) + return; + maxZoom = value; + + // Update the zoom level + Zoom = Zoom; + } + } + + private float zoom = 1; + /// + /// The current zoom level. + /// + public float Zoom + { + get { return zoom; } + set + { + value = MathHelper.Clamp(value, MinZoom, MaxZoom); + if (zoom == value) + return; + zoom = value; + + Content.ResizeWidthTo(Zoom); + } + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return base.OnWheel(state); + + float relativeContentPosition = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; + float position = ToLocalSpace(state.Mouse.NativeState.Position).X; + + Zoom += state.Mouse.WheelDelta; + + float scrollPos = Content.DrawSize.X * relativeContentPosition - position; + ScrollTo(scrollPos, false); + + return true; + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs index 4ec3b8c661..40d617d2ea 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -9,12 +9,13 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; using osu.Game.Screens.Edit.Screens.Compose; +using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual { public class TestCaseEditorComposeTimeline : OsuTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(BeatmapWaveformGraph) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph) }; private readonly ScrollableTimeline timeline; diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index 4a6e93c7bf..c87be7e4b8 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -12,6 +12,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Screens.Edit.Screens.Compose; +using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b1d410ba50..321c2df4b5 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -266,7 +266,7 @@ - + @@ -630,7 +630,8 @@ - + + From 9cb9151811526690b5c6b31391cb4e7f728f8f0c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 16:00:11 +0900 Subject: [PATCH 35/83] Move origin + anchor outside of ctor --- osu.Game/Graphics/UserInterface/IconButton.cs | 3 --- osu.Game/Overlays/MusicController.cs | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 1808dc4b6c..956fac279f 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -38,9 +38,6 @@ namespace osu.Game.Graphics.UserInterface { AutoSizeAxes = Axes.Both; - Origin = Anchor.Centre; - Anchor = Anchor.Centre; - Children = new Drawable[] { content = new Container diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 64d0d628f0..a99ce89a36 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -161,11 +161,15 @@ namespace osu.Game.Overlays { prevButton = new IconButton { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Action = prev, Icon = FontAwesome.fa_step_backward, }, playButton = new IconButton { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Scale = new Vector2(1.4f), IconScale = new Vector2(1.4f), Action = play, @@ -173,6 +177,8 @@ namespace osu.Game.Overlays }, nextButton = new IconButton { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Action = next, Icon = FontAwesome.fa_step_forward, }, From b306eaca6e40f83a83bd25476c5a81f403d7cb83 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Oct 2017 16:39:23 +0900 Subject: [PATCH 36/83] Move mania tests to correct namespace --- .../{Testing => Tests}/TestCaseManiaHitObjects.cs | 2 +- .../{Testing => Tests}/TestCaseManiaPlayfield.cs | 2 +- osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game.Rulesets.Mania/{Testing => Tests}/TestCaseManiaHitObjects.cs (96%) rename osu.Game.Rulesets.Mania/{Testing => Tests}/TestCaseManiaPlayfield.cs (96%) diff --git a/osu.Game.Rulesets.Mania/Testing/TestCaseManiaHitObjects.cs b/osu.Game.Rulesets.Mania/Tests/TestCaseManiaHitObjects.cs similarity index 96% rename from osu.Game.Rulesets.Mania/Testing/TestCaseManiaHitObjects.cs rename to osu.Game.Rulesets.Mania/Tests/TestCaseManiaHitObjects.cs index a5568b7f6d..4230171288 100644 --- a/osu.Game.Rulesets.Mania/Testing/TestCaseManiaHitObjects.cs +++ b/osu.Game.Rulesets.Mania/Tests/TestCaseManiaHitObjects.cs @@ -10,7 +10,7 @@ using osu.Game.Tests.Visual; using OpenTK; using OpenTK.Graphics; -namespace osu.Game.Rulesets.Mania.Testing +namespace osu.Game.Rulesets.Mania.Tests { [TestFixture] internal class TestCaseManiaHitObjects : OsuTestCase diff --git a/osu.Game.Rulesets.Mania/Testing/TestCaseManiaPlayfield.cs b/osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs similarity index 96% rename from osu.Game.Rulesets.Mania/Testing/TestCaseManiaPlayfield.cs rename to osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs index 4b68334efb..c1de273a1b 100644 --- a/osu.Game.Rulesets.Mania/Testing/TestCaseManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs @@ -17,7 +17,7 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; using osu.Game.Tests.Visual; -namespace osu.Game.Rulesets.Mania.Testing +namespace osu.Game.Rulesets.Mania.Tests { [TestFixture] internal class TestCaseManiaPlayfield : OsuTestCase diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index fa8b9d35aa..967f23bfd3 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -80,8 +80,8 @@ - - + + From d7fb59ee0e84c8583b6808b1ae3e1824ffbea624 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 17:20:23 +0900 Subject: [PATCH 37/83] Expose colours of IconButton --- osu.Game/Graphics/UserInterface/IconButton.cs | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 956fac279f..9f3f5096a2 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -15,9 +15,10 @@ namespace osu.Game.Graphics.UserInterface { public class IconButton : OsuClickableContainer { - private readonly SpriteIcon icon; - private readonly Box hover; - private readonly Container content; + private const float button_size = 30; + + public Color4 FlashColour; + public Color4 NormalColour; public FontAwesome Icon { @@ -25,15 +26,28 @@ namespace osu.Game.Graphics.UserInterface set { icon.Icon = value; } } - private const float button_size = 30; - private Color4 flashColour; - public Vector2 IconScale { get { return icon.Scale; } set { icon.Scale = value; } } + public Vector2 ButtonSize + { + get { return content.Size; } + set { content.Size = value; } + } + + public Color4 HoverColour + { + get { return hover.Colour; } + set { hover.Colour = value; } + } + + private readonly Container content; + private readonly SpriteIcon icon; + private readonly Box hover; + public IconButton() { AutoSizeAxes = Axes.Both; @@ -45,7 +59,6 @@ namespace osu.Game.Graphics.UserInterface Origin = Anchor.Centre, Anchor = Anchor.Centre, Size = new Vector2(button_size), - CornerRadius = 5, Masking = true, EdgeEffect = new EdgeEffectParameters @@ -75,8 +88,8 @@ namespace osu.Game.Graphics.UserInterface [BackgroundDependencyLoader] private void load(OsuColour colours) { - hover.Colour = colours.Yellow.Opacity(0.6f); - flashColour = colours.Yellow; + HoverColour = colours.Yellow.Opacity(0.6f); + FlashColour = colours.Yellow; Enabled.ValueChanged += enabled => this.FadeColour(enabled ? Color4.White : colours.Gray9, 200, Easing.OutQuint); } @@ -95,7 +108,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnClick(InputState state) { - hover.FlashColour(flashColour, 800, Easing.OutQuint); + hover.FlashColour(FlashColour, 800, Easing.OutQuint); return base.OnClick(state); } From bbd1a7059e0785b5693cce921205fcbec4c5ae6a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 17:25:39 +0900 Subject: [PATCH 38/83] xmldoc + hook up IconColour --- osu.Game/Graphics/UserInterface/IconButton.cs | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 9f3f5096a2..5e5bfad662 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -17,27 +17,51 @@ namespace osu.Game.Graphics.UserInterface { private const float button_size = 30; + /// + /// The colour that should be flashed when the is clicked. + /// public Color4 FlashColour; - public Color4 NormalColour; + /// + /// The icon colour. This does not affect . + /// + public Color4 IconColour + { + get { return icon.Colour; } + set { icon.Colour = value; } + } + + /// + /// The icon. + /// public FontAwesome Icon { get { return icon.Icon; } set { icon.Icon = value; } } + /// + /// The icon scale. This does not affect . + /// public Vector2 IconScale { get { return icon.Scale; } set { icon.Scale = value; } } + /// + /// The size of the while it is not being pressed. + /// public Vector2 ButtonSize { get { return content.Size; } set { content.Size = value; } } + /// + /// The background colour of the while it is hovered. + /// + /// public Color4 HoverColour { get { return hover.Colour; } From 44141a38b8579cc0e5a9571ad60dac1bf8ba6ff5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 18:04:41 +0900 Subject: [PATCH 39/83] Make it possible to change colours before load() --- osu.Game/Graphics/UserInterface/IconButton.cs | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 5e5bfad662..099423938a 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -17,10 +17,15 @@ namespace osu.Game.Graphics.UserInterface { private const float button_size = 30; + private Color4? flashColour; /// /// The colour that should be flashed when the is clicked. /// - public Color4 FlashColour; + public Color4 FlashColour + { + get { return flashColour ?? Color4.White; } + set { flashColour = value; } + } /// /// The icon colour. This does not affect . @@ -31,6 +36,20 @@ namespace osu.Game.Graphics.UserInterface set { icon.Colour = value; } } + private Color4? hoverColour; + /// + /// The background colour of the while it is hovered. + /// + public Color4 HoverColour + { + get { return hoverColour ?? Color4.White; } + set + { + hoverColour = value; + hover.Colour = value; + } + } + /// /// The icon. /// @@ -58,16 +77,6 @@ namespace osu.Game.Graphics.UserInterface set { content.Size = value; } } - /// - /// The background colour of the while it is hovered. - /// - /// - public Color4 HoverColour - { - get { return hover.Colour; } - set { hover.Colour = value; } - } - private readonly Container content; private readonly SpriteIcon icon; private readonly Box hover; @@ -112,8 +121,11 @@ namespace osu.Game.Graphics.UserInterface [BackgroundDependencyLoader] private void load(OsuColour colours) { - HoverColour = colours.Yellow.Opacity(0.6f); - FlashColour = colours.Yellow; + if (hoverColour == null) + hoverColour = colours.Yellow.Opacity(0.6f); + + if (flashColour == null) + flashColour = colours.Yellow; Enabled.ValueChanged += enabled => this.FadeColour(enabled ? Color4.White : colours.Gray9, 200, Easing.OutQuint); } From 071b1b049cebedee6844a97d37cf7e150c6a5989 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 18:31:56 +0900 Subject: [PATCH 40/83] Fix properties not being set leading to colours not being set --- osu.Game/Graphics/UserInterface/IconButton.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index 099423938a..d58f5797a3 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -122,10 +122,10 @@ namespace osu.Game.Graphics.UserInterface private void load(OsuColour colours) { if (hoverColour == null) - hoverColour = colours.Yellow.Opacity(0.6f); + HoverColour = colours.Yellow.Opacity(0.6f); if (flashColour == null) - flashColour = colours.Yellow; + FlashColour = colours.Yellow; Enabled.ValueChanged += enabled => this.FadeColour(enabled ? Color4.White : colours.Gray9, 200, Easing.OutQuint); } From c2f3c0e6df60ef5579867d631cef16996eba467a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 18:32:09 +0900 Subject: [PATCH 41/83] Add TestCaseIconButton to demonstrate IconButton usages --- osu.Game/Tests/Visual/TestCaseIconButton.cs | 110 ++++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 2 files changed, 111 insertions(+) create mode 100644 osu.Game/Tests/Visual/TestCaseIconButton.cs diff --git a/osu.Game/Tests/Visual/TestCaseIconButton.cs b/osu.Game/Tests/Visual/TestCaseIconButton.cs new file mode 100644 index 0000000000..7fe2eb01f0 --- /dev/null +++ b/osu.Game/Tests/Visual/TestCaseIconButton.cs @@ -0,0 +1,110 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Testing; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseIconButton : OsuTestCase + { + public override string Description => "Various display modes of icon buttons"; + + public TestCaseIconButton() + { + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Spacing = new Vector2(10, 10), + Children = new[] + { + new NamedIconButton("No change", new IconButton()), + new NamedIconButton("Green colours", new IconButton + { + IconColour = Color4.LightGreen, + FlashColour = Color4.DarkGreen, + HoverColour = Color4.Green + }), + new NamedIconButton("Full-width", new IconButton { ButtonSize = new Vector2(200, 30) }), + new NamedIconButton("Unchanging size", new IconButton(), false) + } + }; + } + + private class NamedIconButton : Container + { + public NamedIconButton(string name, IconButton button, bool allowSizeChange = true) + { + AutoSizeAxes = Axes.Y; + Width = 200; + + Container iconContainer; + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Alpha = 0.5f, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = name + }, + new Container + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0.1f, + }, + iconContainer = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Child = button + } + } + } + } + } + }; + + if (allowSizeChange) + iconContainer.AutoSizeAxes = Axes.Both; + else + { + iconContainer.RelativeSizeAxes = Axes.X; + iconContainer.Height = 30; + } + + button.Anchor = Anchor.Centre; + button.Origin = Anchor.Centre; + button.Icon = FontAwesome.fa_osu_osu_o; + } + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ff5c492fc7..81f360f640 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -759,6 +759,7 @@ + From 8cea875f5fe830f654462d9ce24f057af8d04494 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 18:35:30 +0900 Subject: [PATCH 42/83] Remove unused using --- osu.Game/Tests/Visual/TestCaseIconButton.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Tests/Visual/TestCaseIconButton.cs b/osu.Game/Tests/Visual/TestCaseIconButton.cs index 7fe2eb01f0..bec8f8314b 100644 --- a/osu.Game/Tests/Visual/TestCaseIconButton.cs +++ b/osu.Game/Tests/Visual/TestCaseIconButton.cs @@ -6,7 +6,6 @@ using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Testing; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; From ad344eb719242da7cff0bbdbf7c7d667bd9e32a9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 19:21:38 +0900 Subject: [PATCH 43/83] Use IsNullOrWhiteSpace instead of trimming --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index a70faf5be6..2cf080746f 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -613,7 +613,7 @@ namespace osu.Game.Beatmaps.Formats string line; while ((line = stream.ReadLine()) != null) { - if (string.IsNullOrEmpty(line.Trim())) + if (string.IsNullOrWhiteSpace(line)) continue; if (line.StartsWith("//")) From b8d2a04fe1031f61cb35a7788d4e3cf0f35d1b38 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 19:24:24 +0900 Subject: [PATCH 44/83] Only split beatmap lines twice --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 2cf080746f..2493dab08c 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -679,7 +679,7 @@ namespace osu.Game.Beatmaps.Formats private KeyValuePair splitKeyVal(string line, char separator) { - var split = line.Trim().Split(separator); + var split = line.Trim().Split(new[] { separator }, 2); return new KeyValuePair ( From 03fbf47bc2f1974a9518b36aa3921dfac055c332 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Oct 2017 16:34:01 +0900 Subject: [PATCH 45/83] Add juicy streams --- .../Beatmaps/CatchBeatmapConverter.cs | 30 ++++- .../Drawable/DrawableCatchHitObject.cs | 15 ++- .../Objects/Drawable/DrawableDroplet.cs | 32 +++++ .../Objects/Drawable/DrawableFruit.cs | 40 +----- .../Objects/Drawable/DrawableJuiceStream.cs | 59 ++++++++ .../Objects/Drawable/Pieces/Pulp.cs | 40 ++++++ .../Objects/JuiceStream.cs | 126 ++++++++++++++++++ .../Tests/TestCaseCatchPlayer.cs | 12 -- .../Tests/TestCaseCatchStacker.cs | 27 ++++ osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 6 +- .../UI/CatchRulesetContainer.cs | 9 +- .../osu.Game.Rulesets.Catch.csproj | 10 +- osu.Game/Rulesets/Objects/SliderCurve.cs | 2 + 13 files changed, 346 insertions(+), 62 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/JuiceStream.cs create mode 100644 osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index 2efb0c0707..b3ff1acb02 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -5,9 +5,9 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using System.Collections.Generic; using System; +using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Osu.UI; namespace osu.Game.Rulesets.Catch.Beatmaps { @@ -17,14 +17,36 @@ namespace osu.Game.Rulesets.Catch.Beatmaps protected override IEnumerable ConvertHitObject(HitObject obj, Beatmap beatmap) { - if (!(obj is IHasXPosition)) + var curveData = obj as IHasCurve; + var positionData = obj as IHasPosition; + var comboData = obj as IHasCombo; + + if (positionData == null) yield break; + if (curveData != null) + { + yield return new JuiceStream + { + StartTime = obj.StartTime, + Samples = obj.Samples, + ControlPoints = curveData.ControlPoints, + CurveType = curveData.CurveType, + Distance = curveData.Distance, + RepeatSamples = curveData.RepeatSamples, + RepeatCount = curveData.RepeatCount, + X = positionData.X / CatchPlayfield.BASE_WIDTH, + NewCombo = comboData?.NewCombo ?? false + }; + + yield break; + } + yield return new Fruit { StartTime = obj.StartTime, - NewCombo = (obj as IHasCombo)?.NewCombo ?? false, - X = ((IHasXPosition)obj).X / OsuPlayfield.BASE_SIZE.X + NewCombo = comboData?.NewCombo ?? false, + X = positionData.X / CatchPlayfield.BASE_WIDTH }; } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index fbb93e51a7..bb2df401cb 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -3,12 +3,23 @@ using System; using osu.Framework.Graphics; -using osu.Framework.MathUtils; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Objects.Drawable { + public abstract class DrawableCatchHitObject : DrawableCatchHitObject + where TObject : CatchBaseHit + { + public new TObject HitObject; + + protected DrawableCatchHitObject(TObject hitObject) + : base(hitObject) + { + HitObject = hitObject; + } + } + public abstract class DrawableCatchHitObject : DrawableScrollingHitObject { protected DrawableCatchHitObject(CatchBaseHit hitObject) @@ -17,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Origin = Anchor.Centre; RelativePositionAxes = Axes.Both; X = hitObject.X; - Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; + Y = (float)HitObject.StartTime; } public Func CheckPosition; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs new file mode 100644 index 0000000000..fdb8c3e1e5 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + public class DrawableDroplet : DrawableCatchHitObject + { + public DrawableDroplet(Droplet h) + : base(h) + { + Size = new Vector2(Pulp.PULP_SIZE); + + AccentColour = Color4.Green; + Masking = false; + } + + [BackgroundDependencyLoader] + private void load() + { + Child = new Pulp + { + AccentColour = AccentColour, + Scale = new Vector2(0.6f), + }; + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 8e2618c64c..336647cbb9 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -2,26 +2,26 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; +using osu.Framework.MathUtils; +using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; -using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { - public class DrawableFruit : DrawableCatchHitObject + public class DrawableFruit : DrawableCatchHitObject { private const float pulp_size = 20; - public DrawableFruit(CatchBaseHit h) + public DrawableFruit(Fruit h) : base(h) { Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f); AccentColour = HitObject.ComboColour; Masking = false; + + Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; } [BackgroundDependencyLoader] @@ -71,33 +71,5 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable } }; } - - private class Pulp : Circle, IHasAccentColour - { - public Pulp() - { - Size = new Vector2(pulp_size); - - Blending = BlendingMode.Additive; - Colour = Color4.White.Opacity(0.9f); - } - - private Color4 accentColour; - public Color4 AccentColour - { - get { return accentColour; } - set - { - accentColour = value; - - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Radius = 5, - Colour = accentColour.Lighten(100), - }; - } - } - } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs new file mode 100644 index 0000000000..162fe05fc5 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -0,0 +1,59 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using OpenTK; +using OpenTK.Graphics; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + public class DrawableJuiceStream : DrawableCatchHitObject + { + private readonly Container dropletContainer; + + public DrawableJuiceStream(JuiceStream s) : base(s) + { + RelativeSizeAxes = Axes.Both; + Height = (float)HitObject.Duration; + + Child = dropletContainer = new Container + { + RelativeSizeAxes = Axes.Both, + RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime), + RelativeChildSize = new Vector2(1, (float)HitObject.Duration) + }; + + var start = new DrawableFruit(new Fruit + { + ComboColour = Color4.Blue, + StartTime = s.StartTime, + X = s.X, + }); + + AddNested(start); + + var end = new DrawableFruit(new Fruit + { + ComboColour = Color4.Red, + StartTime = s.EndTime, + X = s.EndX, + }); + + AddNested(end); + + foreach (var tick in s.Ticks) + { + var droplet = new DrawableDroplet(tick); + AddNested(droplet); + } + } + + protected override void AddNested(DrawableHitObject h) + { + dropletContainer.Add(h); + base.AddNested(h); + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs new file mode 100644 index 0000000000..6a19bfa69a --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs @@ -0,0 +1,40 @@ +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces +{ + public class Pulp : Circle, IHasAccentColour + { + public const float PULP_SIZE = 20; + + public Pulp() + { + Size = new Vector2(PULP_SIZE); + + Blending = BlendingMode.Additive; + Colour = Color4.White.Opacity(0.9f); + } + + private Color4 accentColour; + public Color4 AccentColour + { + get { return accentColour; } + set + { + accentColour = value; + + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Radius = 5, + Colour = accentColour.Lighten(100), + }; + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs new file mode 100644 index 0000000000..5213d67225 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -0,0 +1,126 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Catch.UI; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using OpenTK; + +namespace osu.Game.Rulesets.Catch.Objects +{ + public class JuiceStream : CatchBaseHit, IHasCurve + { + /// + /// Scoring distance with a speed-adjusted beat length of 1 second. + /// + private const float base_scoring_distance = 100; + + public readonly SliderCurve Curve = new SliderCurve(); + + public int RepeatCount { get; set; } = 1; + + public double Velocity; + public double TickDistance; + + public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) + { + base.ApplyDefaults(controlPointInfo, difficulty); + + TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); + DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime); + + double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier; + + Velocity = scoringDistance / timingPoint.BeatLength; + TickDistance = scoringDistance / difficulty.SliderTickRate; + } + + public IEnumerable Ticks + { + get + { + if (TickDistance == 0) yield break; + + var length = Curve.Distance; + var tickDistance = Math.Min(TickDistance, length); + var repeatDuration = length / Velocity; + + var minDistanceFromEnd = Velocity * 0.01; + + // temporary + while (tickDistance > 10) tickDistance /= 2; + + for (var repeat = 0; repeat < RepeatCount; repeat++) + { + var repeatStartTime = StartTime + repeat * repeatDuration; + var reversed = repeat % 2 == 1; + + for (var d = tickDistance; d <= length; d += tickDistance) + { + if (d > length - minDistanceFromEnd) + break; + + var distanceProgress = d / length; + var timeProgress = reversed ? 1 - distanceProgress : distanceProgress; + + yield return new Droplet + { + StartTime = repeatStartTime + timeProgress * repeatDuration, + X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, + Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + { + Bank = s.Bank, + Name = @"slidertick", + Volume = s.Volume + })) + }; + } + } + } + } + + public double EndTime => StartTime + RepeatCount * Curve.Distance / Velocity; + + public float EndX => Curve.PositionAt(ProgressAt(1)).X / CatchPlayfield.BASE_WIDTH; + + public double Duration => EndTime - StartTime; + + public double Distance + { + get { return Curve.Distance; } + set { Curve.Distance = value; } + } + + public List ControlPoints + { + get { return Curve.ControlPoints; } + set { Curve.ControlPoints = value; } + } + + public List RepeatSamples { get; set; } = new List(); + + public CurveType CurveType + { + get { return Curve.CurveType; } + set { Curve.CurveType = value; } + } + + public Vector2 PositionAt(double progress) => Curve.PositionAt(ProgressAt(progress)); + + public double ProgressAt(double progress) + { + double p = progress * RepeatCount % 1; + if (RepeatAt(progress) % 2 == 1) + p = 1 - p; + return p; + } + + public int RepeatAt(double progress) => (int)(progress * RepeatCount); + } +} diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs index 5be07e94c0..25c095426f 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs @@ -2,8 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using NUnit.Framework; -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Tests { @@ -13,15 +11,5 @@ namespace osu.Game.Rulesets.Catch.Tests public TestCaseCatchPlayer() : base(typeof(CatchRuleset)) { } - - protected override Beatmap CreateBeatmap() - { - var beatmap = new Beatmap(); - - for (int i = 0; i < 256; i++) - beatmap.HitObjects.Add(new Fruit { X = 0.5f, StartTime = i * 100, NewCombo = i % 8 == 0 }); - - return beatmap; - } } } diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs new file mode 100644 index 0000000000..7c3bb2bfd8 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Catch.Objects; + +namespace osu.Game.Rulesets.Catch.Tests +{ + [TestFixture] + public class TestCaseCatchStacker : Game.Tests.Visual.TestCasePlayer + { + public TestCaseCatchStacker() : base(typeof(CatchRuleset)) + { + } + + protected override Beatmap CreateBeatmap() + { + var beatmap = new Beatmap(); + + for (int i = 0; i < 256; i++) + beatmap.HitObjects.Add(new Fruit { X = 0.5f, StartTime = i * 100, NewCombo = i % 8 == 0 }); + + return beatmap; + } + } +} diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index c4033b562d..4d7af0f2b6 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -15,6 +15,8 @@ namespace osu.Game.Rulesets.Catch.UI { public class CatchPlayfield : ScrollingPlayfield { + public static readonly float BASE_WIDTH = 512; + protected override Container Content => content; private readonly Container content; @@ -28,8 +30,6 @@ namespace osu.Game.Rulesets.Catch.UI Reversed.Value = true; - Size = new Vector2(1); - Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; @@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Catch.UI base.Add(h); - var fruit = (DrawableFruit)h; + var fruit = (DrawableCatchHitObject)h; fruit.CheckPosition = CheckIfWeCanCatch; } diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index 8a6ef71996..92912eb177 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -32,8 +32,13 @@ namespace osu.Game.Rulesets.Catch.UI protected override DrawableHitObject GetVisualRepresentation(CatchBaseHit h) { - if (h is Fruit) - return new DrawableFruit(h); + var fruit = h as Fruit; + if (fruit != null) + return new DrawableFruit(fruit); + + var stream = h as JuiceStream; + if (stream != null) + return new DrawableJuiceStream(stream); return null; } diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index f614ec647f..906b7d663a 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -51,6 +51,10 @@ + + + + @@ -59,6 +63,7 @@ + @@ -80,11 +85,6 @@ osu.Framework False - - {C92A607B-1FDD-4954-9F92-03FF547D9080} - osu.Game.Rulesets.Osu - False - {2a66dd92-adb1-4994-89e2-c94e04acda0d} osu.Game diff --git a/osu.Game/Rulesets/Objects/SliderCurve.cs b/osu.Game/Rulesets/Objects/SliderCurve.cs index 8bf85e498c..f920f97790 100644 --- a/osu.Game/Rulesets/Objects/SliderCurve.cs +++ b/osu.Game/Rulesets/Objects/SliderCurve.cs @@ -15,6 +15,8 @@ namespace osu.Game.Rulesets.Objects public List ControlPoints; + public double Scale = 1; + public CurveType CurveType = CurveType.PerfectCurve; public Vector2 Offset; From e4f915e5af0f888a24884a8510eb2fead96a6357 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Oct 2017 20:22:57 +0900 Subject: [PATCH 46/83] Fix scoring simulation not supporting juice --- .../Scoring/CatchScoreProcessor.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 16756e65f1..66a5636b74 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -21,6 +21,19 @@ namespace osu.Game.Rulesets.Catch.Scoring { foreach (var obj in beatmap.HitObjects) { + var stream = obj as JuiceStream; + + if (stream != null) + { + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + + foreach (var unused in stream.Ticks) + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + + continue; + } + var fruit = obj as Fruit; if (fruit != null) From 1fc16693d65c45cf5d84f2f478299a75b0b44ab4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 11:20:44 +0900 Subject: [PATCH 47/83] Formatting --- .../Objects/Drawables/Pieces/SpinnerSpmCounter.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs index 57ec516484..c079d3343b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs @@ -12,6 +12,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces public class SpinnerSpmCounter : Container { private readonly OsuSpriteText spmText; + public SpinnerSpmCounter() { Children = new Drawable[] @@ -37,6 +38,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } private double spm; + public double SpinsPerMinute { get { return spm; } @@ -57,7 +59,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private readonly Queue records = new Queue(); private const double spm_count_duration = 595; // not using hundreds to avoid frame rounding issues - public void SetRotation(float currentRotation) { if (records.Count > 0) @@ -67,6 +68,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces record = records.Dequeue(); SpinsPerMinute = (currentRotation - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; } + records.Enqueue(new RotationRecord { Rotation = currentRotation, Time = Time.Current }); } } From e76961a93287de7ca383ae911b0eb9d68e86bc3c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 11:23:02 +0900 Subject: [PATCH 48/83] Remove unnecessary bool --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 0fded6ec1a..054a2067ec 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -31,8 +31,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly CirclePiece circle; private readonly GlowPiece glow; - private bool spmShown; - private readonly SpriteIcon symbol; private readonly Color4 baseColour = OsuColour.FromHex(@"002c3c"); @@ -167,11 +165,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void Update() { disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton); - if (!spmShown && disc.Tracking) - { - spmShown = true; + if (!spmCounter.IsPresent && disc.Tracking) spmCounter.FadeIn(TIME_FADEIN); - } base.Update(); } From b6cfc49b0676d7ae02ba7b3e11e80f5e5dd9de67 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 12:41:17 +0900 Subject: [PATCH 49/83] Improve resilience of beatmap import test Fixes this happening https://ci.appveyor.com/project/peppy/osu/build/master-4694/tests --- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 35bebf2d4f..a0c8fc48a5 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -118,15 +118,19 @@ namespace osu.Game.Tests.Beatmaps.IO Assert.IsTrue(resultSets.Count() == 1, $@"Incorrect result count found ({resultSets.Count()} but should be 1)."); IEnumerable resultBeatmaps = null; + IEnumerable resultBeatmapSet = null; //if we don't re-check here, the set will be inserted but the beatmaps won't be present yet. waitForOrAssert(() => (resultBeatmaps = store.QueryBeatmaps(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() == 12, @"Beatmaps did not import to the database in allocated time", timeout); - var set = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526).First(); + waitForOrAssert(() => (resultBeatmapSet = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526)).Count() == 1, + @"BeatmapSet did not import to the database in allocated time", timeout); - Assert.IsTrue(set.Beatmaps.Count == resultBeatmaps.Count(), - $@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count})."); + var set = resultBeatmapSet.First(); + + waitForOrAssert(() => set.Beatmaps.Count == resultBeatmaps.Count(), + $@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count}).", timeout); foreach (BeatmapInfo b in resultBeatmaps) Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineBeatmapID == b.OnlineBeatmapID)); From bf6ab77b0eaa77d5bb548685cbdc3a51f1fb4598 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 13:37:10 +0900 Subject: [PATCH 50/83] Always use live queries to ensure waiting asserts actually get dynamic data --- .../Beatmaps/IO/ImportBeatmapTest.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index a0c8fc48a5..cd9e765e7f 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -117,22 +117,27 @@ namespace osu.Game.Tests.Beatmaps.IO //ensure we were stored to beatmap database backing... Assert.IsTrue(resultSets.Count() == 1, $@"Incorrect result count found ({resultSets.Count()} but should be 1)."); - IEnumerable resultBeatmaps = null; - IEnumerable resultBeatmapSet = null; + Func> queryBeatmaps = () => store.QueryBeatmaps(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0); + Func> queryBeatmapSets = () => store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526); //if we don't re-check here, the set will be inserted but the beatmaps won't be present yet. - waitForOrAssert(() => (resultBeatmaps = store.QueryBeatmaps(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() == 12, + waitForOrAssert(() => queryBeatmaps().Count() == 12, @"Beatmaps did not import to the database in allocated time", timeout); - waitForOrAssert(() => (resultBeatmapSet = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526)).Count() == 1, + waitForOrAssert(() => queryBeatmapSets().Count() == 1, @"BeatmapSet did not import to the database in allocated time", timeout); - var set = resultBeatmapSet.First(); + int countBeatmapSetBeatmaps = 0; + int countBeatmaps = 0; - waitForOrAssert(() => set.Beatmaps.Count == resultBeatmaps.Count(), - $@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count}).", timeout); + waitForOrAssert(() => + (countBeatmapSetBeatmaps = queryBeatmapSets().First().Beatmaps.Count) == + (countBeatmaps = queryBeatmaps().Count()), + $@"Incorrect database beatmap count post-import ({countBeatmaps} but should be {countBeatmapSetBeatmaps}).", timeout); - foreach (BeatmapInfo b in resultBeatmaps) + var set = queryBeatmapSets().First(); + + foreach (BeatmapInfo b in set.Beatmaps) Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineBeatmapID == b.OnlineBeatmapID)); Assert.IsTrue(set.Beatmaps.Count > 0); From cf7f3411fc6298bb2fb9e955977ffcd12bfeb77f Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Wed, 27 Sep 2017 20:27:01 +0800 Subject: [PATCH 51/83] Ignore filename case in BeatmapManager. Fixes #1295. --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index a1b678392b..ce07b61ee4 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -550,7 +550,7 @@ namespace osu.Game.Beatmaps catch { return null; } } - private string getPathForFile(string filename) => BeatmapSetInfo.Files.First(f => f.Filename == filename).FileInfo.StoragePath; + private string getPathForFile(string filename) => BeatmapSetInfo.Files.First(f => string.Equals(f.Filename, filename, StringComparison.InvariantCultureIgnoreCase)).FileInfo.StoragePath; protected override Texture GetBackground() { From 76cf0e55a63b36018d2e1ed7f18a73f44013d93c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 11 Oct 2017 10:04:15 +0200 Subject: [PATCH 52/83] Fix capitalization of launch tasks --- .vscode/launch.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index b8c026d891..5e761f118b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,7 +18,7 @@ "console": "internalConsole" }, { - "name": "osu! (debug)", + "name": "osu! (Debug)", "windows": { "type": "clr" }, @@ -32,7 +32,7 @@ "console": "internalConsole" }, { - "name": "osu! (release)", + "name": "osu! (Release)", "windows": { "type": "clr" }, From 4922896636e9018db5ece66f97399f1e4d6bf161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 11 Oct 2017 10:04:44 +0200 Subject: [PATCH 53/83] Mark release build task as "build" --- .vscode/tasks.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3db43ca9bb..35bf9e7a0e 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -23,6 +23,7 @@ }, { "taskName": "Build (Release)", + "group": "build", "args": [ "/property:Configuration=Release" ], From f55b98079373b0ab1e28687660a51aa4735ed0e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 11 Oct 2017 10:05:00 +0200 Subject: [PATCH 54/83] Add launch task for visual tests in release mode --- .vscode/launch.json | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 5e761f118b..d17dc33669 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,7 +1,7 @@ { "version": "0.2.0", "configurations": [{ - "name": "osu! (VisualTests)", + "name": "osu! VisualTests (Debug)", "windows": { "type": "clr" }, @@ -17,6 +17,23 @@ "env": {}, "console": "internalConsole" }, + { + "name": "osu! VisualTests (Release)", + "windows": { + "type": "clr" + }, + "type": "mono", + "request": "launch", + "program": "${workspaceRoot}/osu.Game/bin/Release/osu!.exe", + "args": [ + "--tests" + ], + "cwd": "${workspaceRoot}", + "preLaunchTask": "Build (Release)", + "runtimeExecutable": null, + "env": {}, + "console": "internalConsole" + }, { "name": "osu! (Debug)", "windows": { From a6c54034feff7de349e5d4afe423c46ccecf349c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 17:38:21 +0900 Subject: [PATCH 55/83] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index ef889b4ec7..07e84f60b0 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit ef889b4ec7e6175d52d64411c15f4f195fd16209 +Subproject commit 07e84f60b0d2ee443f366cb2e34bf25b680983dd From 1f1bdc6162eb972da2c7557305533f8c14a74cb5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 18:18:06 +0900 Subject: [PATCH 56/83] Make juice streams interactive (and correctly positioned) --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs | 1 + .../Objects/Drawable/DrawableCatchHitObject.cs | 1 - osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs | 3 +++ osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs | 2 ++ .../Objects/Drawable/DrawableJuiceStream.cs | 4 ++++ osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 6 +++++- 7 files changed, 16 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index b3ff1acb02..0e4935aa7a 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -45,6 +45,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps yield return new Fruit { StartTime = obj.StartTime, + Samples = obj.Samples, NewCombo = comboData?.NewCombo ?? false, X = positionData.X / CatchPlayfield.BASE_WIDTH }; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index bb2df401cb..e057bf3d8e 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -25,7 +25,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected DrawableCatchHitObject(CatchBaseHit hitObject) : base(hitObject) { - Origin = Anchor.Centre; RelativePositionAxes = Axes.Both; X = hitObject.X; Y = (float)HitObject.StartTime; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index fdb8c3e1e5..aedef33cfd 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; using OpenTK.Graphics; @@ -13,6 +14,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableDroplet(Droplet h) : base(h) { + Origin = Anchor.Centre; + Size = new Vector2(Pulp.PULP_SIZE); AccentColour = Color4.Green; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 336647cbb9..cffb2981bf 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -17,6 +17,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableFruit(Fruit h) : base(h) { + Origin = Anchor.Centre; + Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f); AccentColour = HitObject.ComboColour; Masking = false; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 162fe05fc5..19fe43a862 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { RelativeSizeAxes = Axes.Both; Height = (float)HitObject.Duration; + X = 0; Child = dropletContainer = new Container { @@ -27,6 +28,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable var start = new DrawableFruit(new Fruit { + Samples = s.Samples, ComboColour = Color4.Blue, StartTime = s.StartTime, X = s.X, @@ -36,6 +38,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable var end = new DrawableFruit(new Fruit { + Samples = s.Samples, ComboColour = Color4.Red, StartTime = s.EndTime, X = s.EndX, @@ -52,6 +55,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected override void AddNested(DrawableHitObject h) { + ((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false; dropletContainer.Add(h); base.AddNested(h); } diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 5213d67225..fa19a6ff15 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Catch.Objects var minDistanceFromEnd = Velocity * 0.01; // temporary - while (tickDistance > 10) tickDistance /= 2; + while (tickDistance > 100) tickDistance /= 2; for (var repeat = 0; repeat < RepeatCount; repeat++) { diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 4d7af0f2b6..987eef5e45 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -83,7 +83,11 @@ namespace osu.Game.Rulesets.Catch.UI if (judgement.IsHit) { Vector2 screenPosition = judgedObject.ScreenSpaceDrawQuad.Centre; - Remove(judgedObject); + + // todo: don't do this + (judgedObject.Parent as Container)?.Remove(judgedObject); + (judgedObject.Parent as Container)?.Remove(judgedObject); + catcher.Add(judgedObject, screenPosition); } } From 1b732c799a5b5a9bb285e74cc145c94c45d1201d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 19:10:07 +0900 Subject: [PATCH 57/83] Make all juice nested objects from ticks --- .../Objects/Drawable/DrawableJuiceStream.cs | 29 +++++-------------- .../Objects/JuiceStream.cs | 25 ++++++++++++---- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 19fe43a862..fe54397d18 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -26,30 +26,15 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable RelativeChildSize = new Vector2(1, (float)HitObject.Duration) }; - var start = new DrawableFruit(new Fruit + foreach (CatchBaseHit tick in s.Ticks) { - Samples = s.Samples, - ComboColour = Color4.Blue, - StartTime = s.StartTime, - X = s.X, - }); + Droplet droplet = tick as Droplet; + if (droplet != null) + AddNested(new DrawableDroplet(droplet)); - AddNested(start); - - var end = new DrawableFruit(new Fruit - { - Samples = s.Samples, - ComboColour = Color4.Red, - StartTime = s.EndTime, - X = s.EndX, - }); - - AddNested(end); - - foreach (var tick in s.Ticks) - { - var droplet = new DrawableDroplet(tick); - AddNested(droplet); + Fruit fruit = tick as Fruit; + if (fruit != null) + AddNested(new DrawableFruit(fruit)); } } diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index fa19a6ff15..3ca0c8fbb6 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Catch.Objects TickDistance = scoringDistance / difficulty.SliderTickRate; } - public IEnumerable Ticks + public IEnumerable Ticks { get { @@ -53,8 +53,13 @@ namespace osu.Game.Rulesets.Catch.Objects var minDistanceFromEnd = Velocity * 0.01; - // temporary - while (tickDistance > 100) tickDistance /= 2; + yield return new Fruit + { + Samples = Samples, + ComboColour = ComboColour, + StartTime = StartTime, + X = X + }; for (var repeat = 0; repeat < RepeatCount; repeat++) { @@ -66,8 +71,10 @@ namespace osu.Game.Rulesets.Catch.Objects if (d > length - minDistanceFromEnd) break; - var distanceProgress = d / length; - var timeProgress = reversed ? 1 - distanceProgress : distanceProgress; + var timeProgress = d / length; + var distanceProgress = reversed ? 1 - timeProgress : timeProgress; + + float tinyDroplet = 0; yield return new Droplet { @@ -81,6 +88,14 @@ namespace osu.Game.Rulesets.Catch.Objects })) }; } + + yield return new Fruit + { + Samples = Samples, + ComboColour = ComboColour, + StartTime = repeatStartTime + repeatDuration, + X = Curve.PositionAt(reversed ? 1 : 0).X + }; } } } From 0b282a49bd2b6f4145ea53d8738f4cec4486c6b2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 20:11:29 +0900 Subject: [PATCH 58/83] Add tiny droplet support --- .../Objects/Drawable/DrawableDroplet.cs | 4 +- .../Objects/Drawable/DrawableJuiceStream.cs | 7 +++ .../Objects/JuiceStream.cs | 53 +++++++++++++++---- .../Objects/TinyDroplet.cs | 9 ++++ .../osu.Game.Rulesets.Catch.csproj | 1 + 5 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index aedef33cfd..fd48f11a3f 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Size = new Vector2(Pulp.PULP_SIZE); - AccentColour = Color4.Green; + AccentColour = h.ComboColour; Masking = false; } @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Child = new Pulp { AccentColour = AccentColour, - Scale = new Vector2(0.6f), + Scale = new Vector2(0.8f), }; } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index fe54397d18..19abf243b3 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -28,6 +28,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable foreach (CatchBaseHit tick in s.Ticks) { + TinyDroplet tiny = tick as TinyDroplet; + if (tiny != null) + { + AddNested(new DrawableDroplet(tiny) { Scale = new Vector2(0.5f) }); + continue; + } + Droplet droplet = tick as Droplet; if (droplet != null) AddNested(new DrawableDroplet(droplet)); diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 3ca0c8fbb6..957a6e69ea 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -11,6 +11,8 @@ using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using OpenTK; +using osu.Framework.Lists; +using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects { @@ -45,7 +47,10 @@ namespace osu.Game.Rulesets.Catch.Objects { get { - if (TickDistance == 0) yield break; + SortedList ticks = new SortedList((a, b) => a.StartTime.CompareTo(b.StartTime)); + + if (TickDistance == 0) + return ticks; var length = Curve.Distance; var tickDistance = Math.Min(TickDistance, length); @@ -53,13 +58,15 @@ namespace osu.Game.Rulesets.Catch.Objects var minDistanceFromEnd = Velocity * 0.01; - yield return new Fruit + ticks.Add(new Fruit { Samples = Samples, ComboColour = ComboColour, StartTime = StartTime, X = X - }; + }); + + double lastTickTime = StartTime; for (var repeat = 0; repeat < RepeatCount; repeat++) { @@ -74,11 +81,11 @@ namespace osu.Game.Rulesets.Catch.Objects var timeProgress = d / length; var distanceProgress = reversed ? 1 - timeProgress : timeProgress; - float tinyDroplet = 0; - - yield return new Droplet + lastTickTime = repeatStartTime + timeProgress * repeatDuration; + ticks.Add(new Droplet { - StartTime = repeatStartTime + timeProgress * repeatDuration, + StartTime = lastTickTime, + ComboColour = ComboColour, X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, Samples = new SampleInfoList(Samples.Select(s => new SampleInfo { @@ -86,17 +93,41 @@ namespace osu.Game.Rulesets.Catch.Objects Name = @"slidertick", Volume = s.Volume })) - }; + }); } - yield return new Fruit + double tinyTickInterval = (tickDistance / length) * repeatDuration; + while (tinyTickInterval > 100) + tinyTickInterval /= 2; + + for (double t = 0; t < repeatDuration; t += tinyTickInterval) + { + double progress = reversed ? 1 - t / repeatDuration : t / repeatDuration; + + ticks.Add(new TinyDroplet + { + StartTime = repeatStartTime + t, + ComboColour = ComboColour, + X = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH, + Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + { + Bank = s.Bank, + Name = @"slidertick", + Volume = s.Volume + })) + }); + } + + ticks.Add(new Fruit { Samples = Samples, ComboColour = ComboColour, StartTime = repeatStartTime + repeatDuration, - X = Curve.PositionAt(reversed ? 1 : 0).X - }; + X = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH + }); } + + return ticks; } } diff --git a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs new file mode 100644 index 0000000000..231f3d5361 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs @@ -0,0 +1,9 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Catch.Objects +{ + public class TinyDroplet : Droplet + { + } +} diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 906b7d663a..ba2c7a5f2e 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -61,6 +61,7 @@ + From 744d548738b92997f60b249413c3c431c25d6513 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 20:28:10 +0900 Subject: [PATCH 59/83] Add missing licence header --- osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs index 6a19bfa69a..00ddd365e3 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs @@ -1,4 +1,7 @@ -using osu.Framework.Extensions.Color4Extensions; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; From 4a4c01f2215f59be580e112c01919a412589f0a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 20:51:16 +0900 Subject: [PATCH 60/83] Fix CI problems --- .../Objects/Drawable/DrawableDroplet.cs | 1 - .../Objects/Drawable/DrawableJuiceStream.cs | 1 - osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 7 ++----- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index fd48f11a3f..2b2a8e7f8d 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; -using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 19abf243b3..afda91d0b4 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -4,7 +4,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using OpenTK; -using OpenTK.Graphics; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Objects.Drawable diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 957a6e69ea..f49799970d 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -12,7 +12,6 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using OpenTK; using osu.Framework.Lists; -using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects { @@ -66,8 +65,6 @@ namespace osu.Game.Rulesets.Catch.Objects X = X }); - double lastTickTime = StartTime; - for (var repeat = 0; repeat < RepeatCount; repeat++) { var repeatStartTime = StartTime + repeat * repeatDuration; @@ -81,7 +78,7 @@ namespace osu.Game.Rulesets.Catch.Objects var timeProgress = d / length; var distanceProgress = reversed ? 1 - timeProgress : timeProgress; - lastTickTime = repeatStartTime + timeProgress * repeatDuration; + var lastTickTime = repeatStartTime + timeProgress * repeatDuration; ticks.Add(new Droplet { StartTime = lastTickTime, @@ -96,7 +93,7 @@ namespace osu.Game.Rulesets.Catch.Objects }); } - double tinyTickInterval = (tickDistance / length) * repeatDuration; + double tinyTickInterval = tickDistance / length * repeatDuration; while (tinyTickInterval > 100) tinyTickInterval /= 2; From 6fbf52c3eb45a5ebcc48331efa882851c3cd4aa7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 15:32:18 +0900 Subject: [PATCH 61/83] Remove unused usings --- .../Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 2 -- .../Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 2 +- osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs | 1 - osu.Game/Tests/Visual/TestCaseWaveform.cs | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 5999241f61..c662341f20 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -1,13 +1,11 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using OpenTK; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index f4795452d5..a64f139e5a 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("222"), - Depth = float.MaxValue, + Depth = float.MaxValue }); Content.AutoSizeAxes = Axes.None; diff --git a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs index 40d617d2ea..00547145cd 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -8,7 +8,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; -using osu.Game.Screens.Edit.Screens.Compose; using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual diff --git a/osu.Game/Tests/Visual/TestCaseWaveform.cs b/osu.Game/Tests/Visual/TestCaseWaveform.cs index c87be7e4b8..fc21b86c5d 100644 --- a/osu.Game/Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game/Tests/Visual/TestCaseWaveform.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; -using osu.Game.Screens.Edit.Screens.Compose; using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual From e12fa4943609ff0b379878a819292606481e90be Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 15:37:00 +0900 Subject: [PATCH 62/83] Integrate timeline into Compose --- osu.Game/Screens/Edit/Screens/Compose/Compose.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs index 2fe40dd010..2349c261cf 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs @@ -6,6 +6,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Screens.Edit.Screens.Compose { @@ -13,6 +14,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { public Compose() { + ScrollableTimeline timeline; Children = new[] { new Container @@ -31,11 +33,22 @@ namespace osu.Game.Screens.Edit.Screens.Compose { Name = "Content", RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 17, Vertical = 10 } + Padding = new MarginPadding { Horizontal = 17, Vertical = 10 }, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Right = 115 }, + Child = timeline = new ScrollableTimeline { RelativeSizeAxes = Axes.Both } + } + } } } } }; + + timeline.Beatmap.BindTo(Beatmap); } } } From 2844764e3c86a0b0acac92c133d97fedaf50aaa7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 15:37:45 +0900 Subject: [PATCH 63/83] Hit Objects/Hit Sounds -> Hitobjects/Hitsounds --- .../Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index c662341f20..4c50dd4564 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -58,8 +58,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Spacing = new Vector2(0, 4), Children = new[] { - new OsuCheckbox { LabelText = "Hit Objects" }, - new OsuCheckbox { LabelText = "Hit Sounds" }, + new OsuCheckbox { LabelText = "Hitobjects" }, + new OsuCheckbox { LabelText = "Hitsounds" }, new OsuCheckbox { LabelText = "Waveform" } } } From de8f9325a3ed68cfc2888607a037318a37789a21 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 16:10:14 +0900 Subject: [PATCH 64/83] Implement TimelineButton and use for the magnification buttons --- .../Compose/Timeline/ScrollableTimeline.cs | 24 ++++------- .../Compose/Timeline/TimelineButton.cs | 42 +++++++++++++++++++ .../Visual/TestCaseEditorComposeTimeline.cs | 2 +- osu.Game/osu.Game.csproj | 1 + 4 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 4c50dd4564..c1959f367b 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -76,27 +76,21 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("333") }, - new FillFlowContainer + new Container { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 15 }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 30), + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Padding = new MarginPadding { Vertical = 5 }, Children = new[] { - new SpriteIcon + new TimelineButton { Icon = FontAwesome.fa_search_plus }, + new TimelineButton { - Size = new Vector2(18), - Icon = FontAwesome.fa_search_plus, - Colour = OsuColour.FromHex("555") - }, - new SpriteIcon - { - Size = new Vector2(18), - Icon = FontAwesome.fa_search_minus, - Colour = OsuColour.FromHex("555") + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Icon = FontAwesome.fa_search_minus }, } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs new file mode 100644 index 0000000000..fc657325a4 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + public class TimelineButton : CompositeDrawable + { + public Action Action; + public readonly BindableBool Enabled = new BindableBool(true); + + public FontAwesome Icon + { + get { return button.Icon; } + set { button.Icon = value; } + } + + private readonly IconButton button; + + public TimelineButton() + { + InternalChild = button = new IconButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + IconColour = OsuColour.FromHex("555"), + HoverColour = OsuColour.FromHex("3A3A3A"), + FlashColour = OsuColour.FromHex("555"), + Action = () => Action?.Invoke() + }; + + button.Enabled.BindTo(Enabled); + Size = button.ButtonSize; + } + } +} diff --git a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs index 00547145cd..02c32dfa56 100644 --- a/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game/Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -14,7 +14,7 @@ namespace osu.Game.Tests.Visual { public class TestCaseEditorComposeTimeline : OsuTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; private readonly ScrollableTimeline timeline; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b0f8d8fac2..c054bf7b4e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -275,6 +275,7 @@ + From 78f2037d84391e75325ad418911f59ef2a185fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 12 Oct 2017 09:42:06 +0200 Subject: [PATCH 65/83] Remove now obsolete RatioAdjust --- osu.Game/Graphics/Processing/RatioAdjust.cs | 27 --------------------- osu.Game/OsuGameBase.cs | 3 +-- osu.Game/osu.Game.csproj | 1 - 3 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 osu.Game/Graphics/Processing/RatioAdjust.cs diff --git a/osu.Game/Graphics/Processing/RatioAdjust.cs b/osu.Game/Graphics/Processing/RatioAdjust.cs deleted file mode 100644 index 640814d8e1..0000000000 --- a/osu.Game/Graphics/Processing/RatioAdjust.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using osu.Framework.Graphics.Containers; -using OpenTK; -using osu.Framework.Graphics; - -namespace osu.Game.Graphics.Processing -{ - internal class RatioAdjust : Container - { - public RatioAdjust() - { - RelativeSizeAxes = Axes.Both; - } - - protected override void Update() - { - base.Update(); - Vector2 parent = Parent.DrawSize; - - Scale = new Vector2(Math.Min(parent.Y / 768f, parent.X / 1024f)); - Size = new Vector2(1 / Scale.X); - } - } -} diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 8e7bfa8a76..93eb1d76df 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -15,7 +15,6 @@ using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Cursor; -using osu.Game.Graphics.Processing; using osu.Game.Online.API; using SQLite.Net; using osu.Framework.Graphics.Performance; @@ -186,7 +185,7 @@ namespace osu.Game GlobalKeyBindingInputManager globalBinding; - base.Content.Add(new RatioAdjust + base.Content.Add(new DrawSizePreservingFillContainer { Children = new Drawable[] { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 81f360f640..b7bb7de9e3 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -312,7 +312,6 @@ - From 881eeaa650f9598e8055beddfa2afe928353654d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 16:57:05 +0900 Subject: [PATCH 66/83] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 07e84f60b0..31754e8fd0 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 07e84f60b0d2ee443f366cb2e34bf25b680983dd +Subproject commit 31754e8fd0eb840b6aca03ec481b677665999211 From 4586877239ef234a7c3c1062c201fa9fde7521ff Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 17:31:21 +0900 Subject: [PATCH 67/83] Implement magnification buttons --- .../Compose/Timeline/ScrollableTimeline.cs | 9 ++++-- .../Timeline/ScrollingTimelineContainer.cs | 30 +++++++++++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index c1959f367b..14c4f2d369 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -85,12 +85,17 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Padding = new MarginPadding { Vertical = 5 }, Children = new[] { - new TimelineButton { Icon = FontAwesome.fa_search_plus }, + new TimelineButton + { + Icon = FontAwesome.fa_search_plus, + Action = () => timelineContainer.Zoom++ + }, new TimelineButton { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Icon = FontAwesome.fa_search_minus + Icon = FontAwesome.fa_search_minus, + Action = () => timelineContainer.Zoom-- }, } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index a64f139e5a..209f0c9300 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -90,23 +90,43 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline return; zoom = value; + // Make the zoom target default to the center of the graph if it hasn't been set + if (relativeContentZoomTarget == null) + relativeContentZoomTarget = ToSpaceOfOtherDrawable(DrawSize / 2, Content).X / Content.DrawSize.X; + if (localZoomTarget == null) + localZoomTarget = DrawSize.X / 2; + Content.ResizeWidthTo(Zoom); + + // Update the scroll position to focus on the zoom target + float scrollPos = Content.DrawSize.X * relativeContentZoomTarget.Value - localZoomTarget.Value; + ScrollTo(scrollPos, false); + + relativeContentZoomTarget = null; + localZoomTarget = null; } } + /// + /// Zoom target as a relative position in the space. + /// + private float? relativeContentZoomTarget; + + /// + /// Zoom target as a position in our local space. + /// + private float? localZoomTarget; + protected override bool OnWheel(InputState state) { if (!state.Keyboard.ControlPressed) return base.OnWheel(state); - float relativeContentPosition = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; - float position = ToLocalSpace(state.Mouse.NativeState.Position).X; + relativeContentZoomTarget = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; + localZoomTarget = ToLocalSpace(state.Mouse.NativeState.Position).X; Zoom += state.Mouse.WheelDelta; - float scrollPos = Content.DrawSize.X * relativeContentPosition - position; - ScrollTo(scrollPos, false); - return true; } } From 3c35a7a6ae5640fda75ce62f77f320e7ce59d676 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 17:37:40 +0900 Subject: [PATCH 68/83] graph -> waveform --- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 209f0c9300..00b7e52e27 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -16,14 +16,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public readonly Bindable Beatmap = new Bindable(); - private readonly BeatmapWaveformGraph graph; + private readonly BeatmapWaveformGraph waveform; public ScrollingTimelineContainer() : base(Direction.Horizontal) { Masking = true; - Add(graph = new BeatmapWaveformGraph + Add(waveform = new BeatmapWaveformGraph { RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("222"), @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Content.AutoSizeAxes = Axes.None; Content.RelativeSizeAxes = Axes.Both; - graph.Beatmap.BindTo(Beatmap); + waveform.Beatmap.BindTo(Beatmap); } private float minZoom = 1; From db672becbc19558b70645de20c9f59947ead1fa2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 17:50:51 +0900 Subject: [PATCH 69/83] Implement waveform checkbox --- .../Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 6 +++++- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 14c4f2d369..bf1237f1f7 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -23,6 +23,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Masking = true; CornerRadius = 5; + OsuCheckbox waveformCheckbox; InternalChildren = new Drawable[] { new Box @@ -60,7 +61,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { new OsuCheckbox { LabelText = "Hitobjects" }, new OsuCheckbox { LabelText = "Hitsounds" }, - new OsuCheckbox { LabelText = "Waveform" } + waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } } } } @@ -106,7 +107,10 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } }; + waveformCheckbox.Current.Value = true; + timelineContainer.Beatmap.BindTo(Beatmap); + timelineContainer.WaveformVisible.BindTo(waveformCheckbox.Current); } protected override void Update() diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 00b7e52e27..a15db3d0df 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -14,6 +14,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { internal class ScrollingTimelineContainer : ScrollContainer { + public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); private readonly BeatmapWaveformGraph waveform; @@ -34,6 +35,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Content.RelativeSizeAxes = Axes.Both; waveform.Beatmap.BindTo(Beatmap); + WaveformVisible.ValueChanged += waveformVisibilityChanged; } private float minZoom = 1; @@ -129,5 +131,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline return true; } + + private void waveformVisibilityChanged(bool visible) => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } } From 5ccfc1918e1a89a1639e016759e9c7b72ad29b4c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 17:51:01 +0900 Subject: [PATCH 70/83] Hook up more bindables for hitobjects/hitsounds --- .../Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 8 ++++++-- .../Compose/Timeline/ScrollingTimelineContainer.cs | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index bf1237f1f7..c64b223fa1 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -23,6 +23,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Masking = true; CornerRadius = 5; + OsuCheckbox hitObjectsCheckbox; + OsuCheckbox hitSoundsCheckbox; OsuCheckbox waveformCheckbox; InternalChildren = new Drawable[] { @@ -59,8 +61,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Spacing = new Vector2(0, 4), Children = new[] { - new OsuCheckbox { LabelText = "Hitobjects" }, - new OsuCheckbox { LabelText = "Hitsounds" }, + hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" }, + hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" }, waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } } } @@ -107,6 +109,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } }; + hitObjectsCheckbox.Current.Value = true; + hitSoundsCheckbox.Current.Value = true; waveformCheckbox.Current.Value = true; timelineContainer.Beatmap.BindTo(Beatmap); diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index a15db3d0df..c1bf2c3f57 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -14,6 +14,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { internal class ScrollingTimelineContainer : ScrollContainer { + public readonly Bindable HitObjectsVisible = new Bindable(); + public readonly Bindable HitSoundsVisible = new Bindable(); public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); From a5817e6e75f803b50886b28d348fb33d53363088 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 18:17:23 +0900 Subject: [PATCH 71/83] Add a way to change the IconButton icon colour --- osu.Game/Graphics/UserInterface/IconButton.cs | 21 +++++++++++++++++-- osu.Game/Tests/Visual/TestCaseIconButton.cs | 12 +++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index d58f5797a3..afffd930ef 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -27,13 +27,28 @@ namespace osu.Game.Graphics.UserInterface set { flashColour = value; } } + private Color4? iconColour; /// /// The icon colour. This does not affect . /// public Color4 IconColour { - get { return icon.Colour; } - set { icon.Colour = value; } + get { return iconColour ?? Color4.White; } + set + { + iconColour = value; + icon.Colour = value; + } + } + + private Color4? iconHoverColour; + /// + /// The icon colour while the is hovered. + /// + public Color4 IconHoverColour + { + get { return iconHoverColour ?? IconColour; } + set { iconHoverColour = value; } } private Color4? hoverColour; @@ -133,12 +148,14 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnHover(InputState state) { hover.FadeIn(500, Easing.OutQuint); + icon.FadeColour(IconHoverColour, 500, Easing.OutQuint); return base.OnHover(state); } protected override void OnHoverLost(InputState state) { hover.FadeOut(500, Easing.OutQuint); + icon.FadeColour(IconColour, 500, Easing.OutQuint); base.OnHoverLost(state); } diff --git a/osu.Game/Tests/Visual/TestCaseIconButton.cs b/osu.Game/Tests/Visual/TestCaseIconButton.cs index bec8f8314b..acde9df4a9 100644 --- a/osu.Game/Tests/Visual/TestCaseIconButton.cs +++ b/osu.Game/Tests/Visual/TestCaseIconButton.cs @@ -25,14 +25,18 @@ namespace osu.Game.Tests.Visual Children = new[] { new NamedIconButton("No change", new IconButton()), - new NamedIconButton("Green colours", new IconButton + new NamedIconButton("Background colours", new IconButton { - IconColour = Color4.LightGreen, FlashColour = Color4.DarkGreen, - HoverColour = Color4.Green + HoverColour = Color4.Green, }), new NamedIconButton("Full-width", new IconButton { ButtonSize = new Vector2(200, 30) }), - new NamedIconButton("Unchanging size", new IconButton(), false) + new NamedIconButton("Unchanging size", new IconButton(), false), + new NamedIconButton("Icon colours", new IconButton + { + IconColour = Color4.Green, + IconHoverColour = Color4.Red + }) } }; } From a6901c0a2714e134608afbe9453a43abf1cec5f1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 18:17:36 +0900 Subject: [PATCH 72/83] Change TimelineButton icon colour to white when hovered --- .../Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs index fc657325a4..6fad1e5bb5 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using OpenTK.Graphics; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -30,6 +31,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Anchor = Anchor.Centre, Origin = Anchor.Centre, IconColour = OsuColour.FromHex("555"), + IconHoverColour = Color4.White, HoverColour = OsuColour.FromHex("3A3A3A"), FlashColour = OsuColour.FromHex("555"), Action = () => Action?.Invoke() From 1b031ca3280d104dadf9543ebf389e2719185b2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 18:28:26 +0900 Subject: [PATCH 73/83] Fix potential read from empty queue in SPM counter --- .../Objects/Drawables/Pieces/SpinnerSpmCounter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs index c079d3343b..ebe978f659 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerSpmCounter.cs @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces if (records.Count > 0) { var record = records.Peek(); - while (Time.Current - records.Peek().Time > spm_count_duration) + while (records.Count > 0 && Time.Current - records.Peek().Time > spm_count_duration) record = records.Dequeue(); SpinsPerMinute = (currentRotation - record.Rotation) / (Time.Current - record.Time) * 1000 * 60 / 360; } From ab623903367b74d2e30032fe5b04d61c6477774b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Oct 2017 18:32:39 +0900 Subject: [PATCH 74/83] Make TimelineButtons combined take up the full height of the timeline --- .../Screens/Compose/Timeline/ScrollableTimeline.cs | 8 ++++++-- .../Edit/Screens/Compose/Timeline/TimelineButton.cs | 10 +++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index c64b223fa1..846a0d09f7 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -79,17 +79,19 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("333") }, - new Container + new Container { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, - Padding = new MarginPadding { Vertical = 5 }, + Masking = true, Children = new[] { new TimelineButton { + RelativeSizeAxes = Axes.Y, + Height = 0.5f, Icon = FontAwesome.fa_search_plus, Action = () => timelineContainer.Zoom++ }, @@ -97,6 +99,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Y, + Height = 0.5f, Icon = FontAwesome.fa_search_minus, Action = () => timelineContainer.Zoom-- }, diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs index 6fad1e5bb5..8eec53c85f 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using OpenTK; using OpenTK.Graphics; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -38,7 +39,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline }; button.Enabled.BindTo(Enabled); - Size = button.ButtonSize; + Width = button.ButtonSize.X; + } + + protected override void Update() + { + base.Update(); + + button.ButtonSize = new Vector2(button.ButtonSize.X, DrawHeight); } } } From d9bf465b9c5a99b6c98dd323825461f3ef1c1c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 12 Oct 2017 11:49:10 +0200 Subject: [PATCH 75/83] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 31754e8fd0..f1cda4873e 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 31754e8fd0eb840b6aca03ec481b677665999211 +Subproject commit f1cda4873eabc778afa323483e762491ee47f297 From 4d78a0492c78609bbee85ac78d410b55c8678951 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 19:15:59 +0900 Subject: [PATCH 76/83] Make creatorUsername a property so it is correctly deserialised --- osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs index 470e13ea7b..d216b093ee 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs @@ -51,7 +51,7 @@ namespace osu.Game.Online.API.Requests private int onlineId { get; set; } [JsonProperty(@"creator")] - private string creatorUsername; + private string creatorUsername { get; set; } [JsonProperty(@"user_id")] private long creatorId = 1; From 8a5e25ce4b6401b86782415351879c64269f9d71 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 18:50:12 +0900 Subject: [PATCH 77/83] Simplify waveform construction --- osu-framework | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/osu-framework b/osu-framework index 31754e8fd0..c5235f4ecf 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 31754e8fd0eb840b6aca03ec481b677665999211 +Subproject commit c5235f4ecfe933c04cbb2ee17adc714b9194fe0a diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index ad837b0e5b..a998b3eec3 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -574,15 +574,7 @@ namespace osu.Game.Beatmaps catch { return new TrackVirtual(); } } - protected override Waveform GetWaveform() - { - try - { - var trackData = store.GetStream(getPathForFile(Metadata.AudioFile)); - return trackData == null ? new Waveform() : new Waveform(trackData); - } - catch { return new Waveform(); } - } + protected override Waveform GetWaveform() => new Waveform(store.GetStream(getPathForFile(Metadata.AudioFile))); } /// From 70c55b23f4edecb0351a1e36afde330205a525ec Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 20:30:15 +0900 Subject: [PATCH 78/83] Remove references to CodeAnalysisRulesets Having these produce warnings under certain compile environments. --- osu-framework | 2 +- osu.Game/osu.Game.csproj | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/osu-framework b/osu-framework index f1cda4873e..b43aecdce9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit f1cda4873eabc778afa323483e762491ee47f297 +Subproject commit b43aecdce95f59912aa0b7211dde3aba1ed9afb1 diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b7bb7de9e3..f14b441960 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -57,7 +57,6 @@ false AnyCPU true - AllRules.ruleset false false false @@ -77,7 +76,6 @@ false AnyCPU true - AllRules.ruleset false false @@ -103,7 +101,6 @@ false 6 prompt - AllRules.ruleset --tests false From fb8d8ec5524861f2ad7d96edd936a6b497c24bff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 21:26:25 +0900 Subject: [PATCH 79/83] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index b43aecdce9..255b94f5dd 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit b43aecdce95f59912aa0b7211dde3aba1ed9afb1 +Subproject commit 255b94f5dde0188db1a5b37daf9649659e2b8366 From 37b88d834e2584cb8f6aaeca89124300057ccd4f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 22:10:37 +0900 Subject: [PATCH 80/83] Adjust padding slightly --- .../Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 846a0d09f7..81beb4a4de 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Y, Width = 160, - Padding = new MarginPadding { Horizontal = 25 }, + Padding = new MarginPadding { Horizontal = 15 }, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 4), Children = new[] From 37fc69b9f71161088f3238cebbc5d90ef1fed5e1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 22:19:02 +0900 Subject: [PATCH 81/83] Set a default zoom level that isn't the whole track --- .../Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index c1bf2c3f57..47a77090b2 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -38,6 +38,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline waveform.Beatmap.BindTo(Beatmap); WaveformVisible.ValueChanged += waveformVisibilityChanged; + + Zoom = 10; } private float minZoom = 1; From c0d64bf409b1e7afb9868a8040459d7e1e30fa21 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 22:19:29 +0900 Subject: [PATCH 82/83] Use Gray instead of FromHex for grays --- .../Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs index 8eec53c85f..0c6fc5d133 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineButton.cs @@ -31,10 +31,10 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { Anchor = Anchor.Centre, Origin = Anchor.Centre, - IconColour = OsuColour.FromHex("555"), + IconColour = OsuColour.Gray(0.35f), IconHoverColour = Color4.White, - HoverColour = OsuColour.FromHex("3A3A3A"), - FlashColour = OsuColour.FromHex("555"), + HoverColour = OsuColour.Gray(0.25f), + FlashColour = OsuColour.Gray(0.5f), Action = () => Action?.Invoke() }; From bb6b656ec688b6139bb5923d743e842949129766 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Oct 2017 22:27:22 +0900 Subject: [PATCH 83/83] Fix code review issues --- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs | 4 +--- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 2 +- osu.Game/Rulesets/Objects/SliderCurve.cs | 4 +--- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index cffb2981bf..4c28a9d021 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -12,14 +12,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public class DrawableFruit : DrawableCatchHitObject { - private const float pulp_size = 20; - public DrawableFruit(Fruit h) : base(h) { Origin = Anchor.Centre; - Size = new Vector2(pulp_size * 2.2f, pulp_size * 2.8f); + Size = new Vector2(Pulp.PULP_SIZE * 2.2f, Pulp.PULP_SIZE * 2.8f); AccentColour = HitObject.ComboColour; Masking = false; diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index f49799970d..6462f6f6a8 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Objects public class JuiceStream : CatchBaseHit, IHasCurve { /// - /// Scoring distance with a speed-adjusted beat length of 1 second. + /// Positional distance that results in a duration of one second, before any speed adjustments. /// private const float base_scoring_distance = 100; diff --git a/osu.Game/Rulesets/Objects/SliderCurve.cs b/osu.Game/Rulesets/Objects/SliderCurve.cs index f920f97790..363c330d3d 100644 --- a/osu.Game/Rulesets/Objects/SliderCurve.cs +++ b/osu.Game/Rulesets/Objects/SliderCurve.cs @@ -15,8 +15,6 @@ namespace osu.Game.Rulesets.Objects public List ControlPoints; - public double Scale = 1; - public CurveType CurveType = CurveType.PerfectCurve; public Vector2 Offset; @@ -202,4 +200,4 @@ namespace osu.Game.Rulesets.Objects return interpolateVertices(indexOfDistance(d), d) + Offset; } } -} \ No newline at end of file +}