From 40a27c810a7dabba9082475ed36aa0aa71872029 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 29 Sep 2017 19:24:14 +0800 Subject: [PATCH 01/31] 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/31] 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/31] 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 134e1299bb4a71e219edfd7746df79fa33cdc888 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Thu, 5 Oct 2017 19:23:58 +0800 Subject: [PATCH 04/31] 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 05/31] 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 06/31] 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 07/31] 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 08/31] 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 09/31] 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 10/31] 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 29c2a2979852f00ddafbf1d58560a681c2a2ea78 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 9 Oct 2017 18:47:12 +0900 Subject: [PATCH 11/31] 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 d5892cf54e7632ddfb7f410aeff1123f1a4bc4fd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Oct 2017 20:17:05 +0900 Subject: [PATCH 12/31] 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 9cb9151811526690b5c6b31391cb4e7f728f8f0c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 10 Oct 2017 16:00:11 +0900 Subject: [PATCH 13/31] 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 14/31] 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 15/31] 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 16/31] 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 17/31] 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 18/31] 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 19/31] 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 20/31] 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 21/31] 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 22/31] 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 1fc16693d65c45cf5d84f2f478299a75b0b44ab4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Oct 2017 11:20:44 +0900 Subject: [PATCH 23/31] 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 24/31] 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 25/31] 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 26/31] 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 27/31] 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 28/31] 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 29/31] 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 30/31] 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 31/31] 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