diff --git a/osu-framework b/osu-framework index 7b2f4dfce7..eab5cc9fde 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 7b2f4dfce7894ca7dea7626dcc34bcc32df651b9 +Subproject commit eab5cc9fde277a9558712c69d92aed0671f2b0ad diff --git a/osu-resources b/osu-resources index 6edd5eacdd..e24414a277 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit 6edd5eacdd25cc8c4f4dbca3414678c0b7dc5deb +Subproject commit e24414a277e407ae2438e4b6d9fa9c7992dd6485 diff --git a/osu.Desktop.VisualTests/OpenTK.dll.config b/osu.Desktop.VisualTests/OpenTK.dll.config index 5620e3d9e2..1dd145f0c4 100644 --- a/osu.Desktop.VisualTests/OpenTK.dll.config +++ b/osu.Desktop.VisualTests/OpenTK.dll.config @@ -1,3 +1,8 @@ + + diff --git a/osu.Desktop.VisualTests/Platform/TestStorage.cs b/osu.Desktop.VisualTests/Platform/TestStorage.cs index 2a6b5a787c..95b767a852 100644 --- a/osu.Desktop.VisualTests/Platform/TestStorage.cs +++ b/osu.Desktop.VisualTests/Platform/TestStorage.cs @@ -1,4 +1,7 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Desktop.Platform; using SQLite.Net; using SQLite.Net.Interop; diff --git a/osu.Desktop.VisualTests/Program.cs b/osu.Desktop.VisualTests/Program.cs index f099f6c1a8..c4f5075ef9 100644 --- a/osu.Desktop.VisualTests/Program.cs +++ b/osu.Desktop.VisualTests/Program.cs @@ -1,5 +1,5 @@ -// Copyright (c) 2007-2016 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; using osu.Framework.Desktop; diff --git a/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs b/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs index 14c44bbb43..d77e2d135b 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs @@ -42,7 +42,8 @@ namespace osu.Desktop.VisualTests.Tests objects.Add(new HitCircle() { StartTime = time, - Position = new Vector2(RNG.Next(0, 512), RNG.Next(0, 384)) + Position = new Vector2(RNG.Next(0, 512), RNG.Next(0, 384)), + Scale = RNG.NextSingle(0.5f, 1.0f), }); time += RNG.Next(50, 500); @@ -85,11 +86,5 @@ namespace osu.Desktop.VisualTests.Tests } }); } - - protected override void Update() - { - base.Update(); - Clock.ProcessFrame(); - } } } diff --git a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs index 1e18ae4117..59ef75a909 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs @@ -22,7 +22,7 @@ namespace osu.Desktop.VisualTests.Tests public TestCaseHitObjects() { - var swClock = new StopwatchClock(true) { Rate = 1 }; + var swClock = new StopwatchClock(true) { Rate = 0.2f }; Clock = new FramedClock(swClock); } @@ -52,17 +52,13 @@ namespace osu.Desktop.VisualTests.Tests Origin = Anchor.Centre, Depth = i, State = ArmedState.Hit, + Judgement = new OsuJudgementInfo { Result = HitResult.Hit } }; + approachContainer.Add(d.ApproachCircle.CreateProxy()); Add(d); } } - - protected override void Update() - { - base.Update(); - Clock.ProcessFrame(); - } } } diff --git a/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs b/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs index 2be742580a..833cefc3d8 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseMusicController.cs @@ -32,11 +32,5 @@ namespace osu.Desktop.VisualTests.Tests Add(mc); AddToggle(@"Show", mc.ToggleVisibility); } - - protected override void Update() - { - base.Update(); - Clock.ProcessFrame(); - } } } diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs index 89bacb9b97..9e3ad1bbc8 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs @@ -82,11 +82,5 @@ namespace osu.Desktop.VisualTests.Tests Beatmap = beatmap }); } - - protected override void Update() - { - base.Update(); - Clock.ProcessFrame(); - } } } diff --git a/osu.Desktop.VisualTests/VisualTestGame.cs b/osu.Desktop.VisualTests/VisualTestGame.cs index 0dc260e1fd..fb949cf1ea 100644 --- a/osu.Desktop.VisualTests/VisualTestGame.cs +++ b/osu.Desktop.VisualTests/VisualTestGame.cs @@ -1,5 +1,5 @@ -// Copyright (c) 2007-2016 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework; using osu.Framework.GameModes.Testing; diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index d12ecc273d..70dd0fee46 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -150,7 +150,7 @@ {d9a367c9-4c1a-489f-9b05-a0cea2b53b58} osu.Game.Resources - + {c92a607b-1fdd-4954-9f92-03ff547d9080} osu.Game.Modes.Osu diff --git a/osu.Desktop.VisualTests/packages.config b/osu.Desktop.VisualTests/packages.config index 720b1d8382..f39a585e49 100644 --- a/osu.Desktop.VisualTests/packages.config +++ b/osu.Desktop.VisualTests/packages.config @@ -1,4 +1,9 @@  + + diff --git a/osu.Desktop/Beatmaps/IO/LegacyFilesystemReader.cs b/osu.Desktop/Beatmaps/IO/LegacyFilesystemReader.cs index 12afbddcc1..b7f727f8fd 100644 --- a/osu.Desktop/Beatmaps/IO/LegacyFilesystemReader.cs +++ b/osu.Desktop/Beatmaps/IO/LegacyFilesystemReader.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using System.IO; using System.Collections.Generic; using System.Linq; diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 95d3ad64c5..ce0e39b6d9 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -130,7 +130,7 @@ {d9a367c9-4c1a-489f-9b05-a0cea2b53b58} osu.Game.Resources - + {c92a607b-1fdd-4954-9f92-03ff547d9080} osu.Game.Modes.Osu diff --git a/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs deleted file mode 100644 index cd907fc001..0000000000 --- a/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright (c) 2007-2016 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE - -using System.Collections.Generic; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Modes.Objects.Drawables; -using OpenTK; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Transformations; -using OpenTK.Graphics; -using osu.Framework.Input; -using OpenTK.Graphics.ES30; -using osu.Framework.Allocation; -using osu.Framework.Graphics.Textures; -using osu.Game.Configuration; -using osu.Framework.Configuration; -using System; - -namespace osu.Game.Modes.Osu.Objects.Drawables -{ - class DrawableSlider : DrawableOsuHitObject - { - private Slider slider; - - private DrawableHitCircle startCircle; - private Container ball; - private Body body; - - public DrawableSlider(Slider s) : base(s) - { - slider = s; - - Origin = Anchor.TopLeft; - Position = Vector2.Zero; - RelativeSizeAxes = Axes.Both; - - Children = new Drawable[] - { - body = new Body(s) - { - Position = s.Position, - }, - ball = new Ball(), - startCircle = new DrawableHitCircle(new HitCircle - { - StartTime = s.StartTime, - Position = s.Position, - Colour = s.Colour, - }) - { - Depth = -1 //override time-based depth. - }, - }; - } - - private Bindable snakingIn; - private Bindable snakingOut; - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - snakingIn = config.GetBindable(OsuConfig.SnakingInSliders); - snakingOut = config.GetBindable(OsuConfig.SnakingOutSliders); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - //force application of the state that was set before we loaded. - UpdateState(State); - - body.PathWidth = 32; - } - - private void computeProgress(out int repeat, out double progress) - { - progress = MathHelper.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1); - - repeat = (int)(progress * slider.RepeatCount); - progress = (progress * slider.RepeatCount) % 1; - - if (repeat % 2 == 1) - progress = 1 - progress; - } - - private void updateBall(double progress) - { - ball.Alpha = Time.Current >= slider.StartTime && Time.Current <= slider.EndTime ? 1 : 0; - ball.Position = slider.Curve.PositionAt(progress); - } - - private void updateBody(int repeat, double progress) - { - double drawStartProgress = 0; - double drawEndProgress = MathHelper.Clamp((Time.Current - slider.StartTime + TIME_PREEMPT) / TIME_FADEIN, 0, 1); - - if (repeat >= slider.RepeatCount - 1) - { - if (Math.Min(repeat, slider.RepeatCount - 1) % 2 == 1) - { - drawStartProgress = 0; - drawEndProgress = progress; - } - else - { - drawStartProgress = progress; - drawEndProgress = 1; - } - } - - body.SetRange( - snakingOut ? drawStartProgress : 0, - snakingIn ? drawEndProgress : 1); - } - - protected override void Update() - { - base.Update(); - - double progress; - int repeat; - computeProgress(out repeat, out progress); - - updateBall(progress); - updateBody(repeat, progress); - } - - protected override void CheckJudgement(bool userTriggered) - { - var j = Judgement as OsuJudgementInfo; - var sc = startCircle.Judgement as OsuJudgementInfo; - - if (!userTriggered && Time.Current >= HitObject.EndTime) - { - j.Score = sc.Score; - j.Result = sc.Result; - } - } - - protected override void UpdateState(ArmedState state) - { - base.UpdateState(state); - - Delay(HitObject.Duration); - FadeOut(300); - } - - private class Ball : Container - { - private Box follow; - - public Ball() - { - Masking = true; - AutoSizeAxes = Axes.Both; - BlendingMode = BlendingMode.Additive; - Origin = Anchor.Centre; - - Children = new Drawable[] - { - follow = new Box - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Colour = Color4.Orange, - Width = 64, - Height = 64, - }, - new Container - { - Masking = true, - AutoSizeAxes = Axes.Both, - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Colour = Color4.Cyan, - CornerRadius = 32, - Children = new[] - { - new Box - { - - Width = 64, - Height = 64, - }, - } - } - - }; - } - - private InputState lastState; - - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) - { - lastState = state; - return base.OnMouseDown(state, args); - } - - protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) - { - lastState = state; - return base.OnMouseUp(state, args); - } - - protected override bool OnMouseMove(InputState state) - { - lastState = state; - return base.OnMouseMove(state); - } - - bool tracking; - protected bool Tracking - { - get { return tracking; } - set - { - if (value == tracking) return; - - tracking = value; - - follow.ScaleTo(tracking ? 2.4f : 1, 140, EasingTypes.Out); - follow.FadeTo(tracking ? 0.8f : 0, 140, EasingTypes.Out); - } - } - - protected override void Update() - { - base.Update(); - - CornerRadius = DrawWidth / 2; - Tracking = lastState != null && Contains(lastState.Mouse.NativeState.Position) && lastState.Mouse.HasMainButtonPressed; - } - } - - private class Body : Container - { - private Path path; - private BufferedContainer container; - - public float PathWidth - { - get { return path.PathWidth; } - set { path.PathWidth = value; } - } - - private double? drawnProgressStart; - private double? drawnProgressEnd; - - private Slider slider; - public Body(Slider s) - { - slider = s; - - Children = new Drawable[] - { - container = new BufferedContainer - { - CacheDrawnFrameBuffer = true, - Children = new Drawable[] - { - path = new Path - { - Colour = s.Colour, - BlendingMode = BlendingMode.None, - }, - } - } - }; - - container.Attach(RenderbufferInternalFormat.DepthComponent16); - } - - [BackgroundDependencyLoader] - private void load(TextureStore textures) - { - // Surprisingly, this looks somewhat okay and works well as a test for self-overlaps. - // TODO: Don't do this. - path.Texture = textures.Get(@"Menu/logo"); - } - - public void SetRange(double p0, double p1) - { - if (p0 > p1) - MathHelper.Swap(ref p0, ref p1); - - if (updateSnaking(p0, p1)) - { - // Autosizing does not give us the desired behaviour here. - // We want the container to have the same size as the slider, - // and to be positioned such that the slider head is at (0,0). - container.Size = path.Size; - container.Position = -path.PositionInBoundingBox(slider.Curve.PositionAt(0) - currentCurve[0]); - - container.ForceRedraw(); - } - } - - private List currentCurve = new List(); - private bool updateSnaking(double p0, double p1) - { - if (drawnProgressStart == p0 && drawnProgressEnd == p1) return false; - - drawnProgressStart = p0; - drawnProgressEnd = p1; - - slider.Curve.GetPathToProgress(currentCurve, p0, p1); - - path.ClearVertices(); - foreach (Vector2 p in currentCurve) - path.AddVertex(p - currentCurve[0]); - - return true; - } - } - } -} diff --git a/osu.Game.Mode.Osu/Objects/Drawables/HitExplosion.cs b/osu.Game.Mode.Osu/Objects/Drawables/HitExplosion.cs deleted file mode 100644 index a0ab68fa99..0000000000 --- a/osu.Game.Mode.Osu/Objects/Drawables/HitExplosion.cs +++ /dev/null @@ -1,51 +0,0 @@ -using osu.Framework.Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Transformations; -using osu.Game.Modes.Objects.Drawables; -using OpenTK; - -namespace osu.Game.Modes.Osu.Objects.Drawables -{ - public class HitExplosion : FlowContainer - { - private SpriteText line1; - private SpriteText line2; - - public HitExplosion(OsuJudgementInfo judgement) - { - AutoSizeAxes = Axes.Both; - Anchor = Anchor.Centre; - Origin = Anchor.Centre; - - Direction = FlowDirection.VerticalOnly; - Spacing = new Vector2(0, 2); - - Children = new Drawable[] - { - line1 = new SpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Text = judgement.Score.GetDescription(), - Font = @"Venera", - TextSize = 20, - }, - line2 = new SpriteText - { - Text = judgement.Combo.GetDescription(), - Font = @"Venera", - TextSize = 14, - } - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - line1.TransformSpacingTo(14, 1800, EasingTypes.OutQuint); - line2.TransformSpacingTo(14, 1800, EasingTypes.OutQuint); - } - } -} \ No newline at end of file diff --git a/osu.Game.Mode.Osu/OsuScore.cs b/osu.Game.Mode.Osu/OsuScore.cs deleted file mode 100644 index 5a70cea434..0000000000 --- a/osu.Game.Mode.Osu/OsuScore.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace osu.Game.Modes.Osu -{ - class OsuScore : Score - { - } -} diff --git a/osu.Game.Mode.Osu/packages.config b/osu.Game.Mode.Osu/packages.config deleted file mode 100644 index e1adbd7260..0000000000 --- a/osu.Game.Mode.Osu/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/osu.Game.Modes.Catch/OpenTK.dll.config b/osu.Game.Modes.Catch/OpenTK.dll.config index 5620e3d9e2..1dd145f0c4 100644 --- a/osu.Game.Modes.Catch/OpenTK.dll.config +++ b/osu.Game.Modes.Catch/OpenTK.dll.config @@ -1,3 +1,8 @@ + + diff --git a/osu.Game.Modes.Catch/Properties/AssemblyInfo.cs b/osu.Game.Modes.Catch/Properties/AssemblyInfo.cs index 4f0e60baaf..6dbfcd99a8 100644 --- a/osu.Game.Modes.Catch/Properties/AssemblyInfo.cs +++ b/osu.Game.Modes.Catch/Properties/AssemblyInfo.cs @@ -1,4 +1,7 @@ -using System.Reflection; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj b/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj index 1db852e438..e68203872e 100644 --- a/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj +++ b/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj @@ -57,6 +57,9 @@ + + osu.licenseheader + @@ -65,7 +68,7 @@ {C76BF5B3-985E-4D39-95FE-97C9C879B83A} osu.Framework - + {C92A607B-1FDD-4954-9F92-03FF547D9080} osu.Game.Modes.Osu diff --git a/osu.Game.Modes.Catch/packages.config b/osu.Game.Modes.Catch/packages.config index 4da07d9f06..3c9e7e3fdc 100644 --- a/osu.Game.Modes.Catch/packages.config +++ b/osu.Game.Modes.Catch/packages.config @@ -1,4 +1,9 @@  + + \ No newline at end of file diff --git a/osu.Game.Modes.Mania/OpenTK.dll.config b/osu.Game.Modes.Mania/OpenTK.dll.config index 5620e3d9e2..1dd145f0c4 100644 --- a/osu.Game.Modes.Mania/OpenTK.dll.config +++ b/osu.Game.Modes.Mania/OpenTK.dll.config @@ -1,3 +1,8 @@ + + diff --git a/osu.Game.Modes.Mania/Properties/AssemblyInfo.cs b/osu.Game.Modes.Mania/Properties/AssemblyInfo.cs index 0ac2657410..57e1595715 100644 --- a/osu.Game.Modes.Mania/Properties/AssemblyInfo.cs +++ b/osu.Game.Modes.Mania/Properties/AssemblyInfo.cs @@ -1,4 +1,7 @@ -using System.Reflection; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/osu.Game.Modes.Mania/app.config b/osu.Game.Modes.Mania/app.config index 44ccc4b77a..9bad888bf3 100644 --- a/osu.Game.Modes.Mania/app.config +++ b/osu.Game.Modes.Mania/app.config @@ -1,4 +1,9 @@  + + diff --git a/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj b/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj index 2ccfff5dcd..22b16c6a9a 100644 --- a/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj +++ b/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj @@ -61,7 +61,7 @@ {C76BF5B3-985E-4D39-95FE-97C9C879B83A} osu.Framework - + {C92A607B-1FDD-4954-9F92-03FF547D9080} osu.Game.Modes.Osu @@ -75,6 +75,9 @@ + + osu.licenseheader + diff --git a/osu.Game.Modes.Mania/packages.config b/osu.Game.Modes.Mania/packages.config index 4da07d9f06..3c9e7e3fdc 100644 --- a/osu.Game.Modes.Mania/packages.config +++ b/osu.Game.Modes.Mania/packages.config @@ -1,4 +1,9 @@  + + \ No newline at end of file diff --git a/osu.Game.Mode.Osu/Objects/BezierApproximator.cs b/osu.Game.Modes.Osu/Objects/BezierApproximator.cs similarity index 93% rename from osu.Game.Mode.Osu/Objects/BezierApproximator.cs rename to osu.Game.Modes.Osu/Objects/BezierApproximator.cs index f08b7aa377..f03e1c0738 100644 --- a/osu.Game.Mode.Osu/Objects/BezierApproximator.cs +++ b/osu.Game.Modes.Osu/Objects/BezierApproximator.cs @@ -1,4 +1,7 @@ -using System.Collections.Generic; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; using OpenTK; namespace osu.Game.Modes.Osu.Objects @@ -10,7 +13,7 @@ namespace osu.Game.Modes.Osu.Objects private Vector2[] subdivisionBuffer1; private Vector2[] subdivisionBuffer2; - private const float TOLERANCE = 0.5f; + private const float TOLERANCE = 0.25f; private const float TOLERANCE_SQ = TOLERANCE * TOLERANCE; public BezierApproximator(List controlPoints) @@ -33,7 +36,7 @@ namespace osu.Game.Modes.Osu.Objects private static bool IsFlatEnough(Vector2[] controlPoints) { for (int i = 1; i < controlPoints.Length - 1; i++) - if ((controlPoints[i - 1] - 2 * controlPoints[i] + controlPoints[i + 1]).LengthSquared > TOLERANCE_SQ) + if ((controlPoints[i - 1] - 2 * controlPoints[i] + controlPoints[i + 1]).LengthSquared > TOLERANCE_SQ * 4) return false; return true; @@ -93,7 +96,6 @@ namespace osu.Game.Modes.Osu.Objects /// Creates a piecewise-linear approximation of a bezier curve, by adaptively repeatedly subdividing /// the control points until their approximation error vanishes below a given threshold. /// - /// The control points describing the curve. /// A list of vectors representing the piecewise-linear approximation. public List CreateBezier() { diff --git a/osu.Game.Modes.Osu/Objects/CircularArcApproximator.cs b/osu.Game.Modes.Osu/Objects/CircularArcApproximator.cs new file mode 100644 index 0000000000..b8f84ed510 --- /dev/null +++ b/osu.Game.Modes.Osu/Objects/CircularArcApproximator.cs @@ -0,0 +1,102 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.MathUtils; +using System; +using System.Collections.Generic; + +namespace osu.Game.Modes.Osu.Objects +{ + public class CircularArcApproximator + { + private Vector2 A; + private Vector2 B; + private Vector2 C; + + private int amountPoints; + + private const float TOLERANCE = 0.1f; + + public CircularArcApproximator(Vector2 A, Vector2 B, Vector2 C) + { + this.A = A; + this.B = B; + this.C = C; + } + + /// + /// Creates a piecewise-linear approximation of a circular arc curve. + /// + /// A list of vectors representing the piecewise-linear approximation. + public List CreateArc() + { + float aSq = (B - C).LengthSquared; + float bSq = (A - C).LengthSquared; + float cSq = (A - B).LengthSquared; + + // If we have a degenerate triangle where a side-length is almost zero, then give up and fall + // back to a more numerically stable method. + if (Precision.AlmostEquals(aSq, 0) || Precision.AlmostEquals(bSq, 0) || Precision.AlmostEquals(cSq, 0)) + return new List(); + + float s = aSq * (bSq + cSq - aSq); + float t = bSq * (aSq + cSq - bSq); + float u = cSq * (aSq + bSq - cSq); + + float sum = s + t + u; + + // If we have a degenerate triangle with an almost-zero size, then give up and fall + // back to a more numerically stable method. + if (Precision.AlmostEquals(sum, 0)) + return new List(); + + Vector2 centre = (s * A + t * B + u * C) / sum; + Vector2 dA = A - centre; + Vector2 dC = C - centre; + + float r = dA.Length; + + double thetaStart = Math.Atan2(dA.Y, dA.X); + double thetaEnd = Math.Atan2(dC.Y, dC.X); + + while (thetaEnd < thetaStart) + thetaEnd += 2 * Math.PI; + + double dir = 1; + double thetaRange = thetaEnd - thetaStart; + + // Decide in which direction to draw the circle, depending on which side of + // AC B lies. + Vector2 orthoAC = C - A; + orthoAC = new Vector2(orthoAC.Y, -orthoAC.X); + if (Vector2.Dot(orthoAC, B - A) < 0) + { + dir = -dir; + thetaRange = 2 * Math.PI - thetaRange; + } + + // We select the amount of points for the approximation by requiring the discrete curvature + // to be smaller than the provided tolerance. The exact angle required to meet the tolerance + // is: 2 * Math.Acos(1 - TOLERANCE / r) + if (2 * r <= TOLERANCE) + // This special case is required for extremely short sliders where the radius is smaller than + // the tolerance. This is a pathological rather than a realistic case. + amountPoints = 2; + else + amountPoints = Math.Max(2, (int)Math.Ceiling(thetaRange / (2 * Math.Acos(1 - TOLERANCE / r)))); + + List output = new List(amountPoints); + + for (int i = 0; i < amountPoints; ++i) + { + double fract = (double)i / (amountPoints - 1); + double theta = thetaStart + dir * fract * thetaRange; + Vector2 o = new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta)) * r; + output.Add(centre + o); + } + + return output; + } + } +} diff --git a/osu.Game.Mode.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Modes.Osu/Objects/Drawables/DrawableHitCircle.cs similarity index 78% rename from osu.Game.Mode.Osu/Objects/Drawables/DrawableHitCircle.cs rename to osu.Game.Modes.Osu/Objects/Drawables/DrawableHitCircle.cs index 94e9a41c5a..b2179d95d0 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -13,7 +13,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables { public class DrawableHitCircle : DrawableOsuHitObject { - private OsuHitObject osuObject; + private HitCircle osuObject; public ApproachCircle ApproachCircle; private CirclePiece circle; @@ -22,14 +22,14 @@ namespace osu.Game.Modes.Osu.Objects.Drawables private ExplodePiece explode; private NumberPiece number; private GlowPiece glow; - private HitExplosion explosion; - public DrawableHitCircle(OsuHitObject h) : base(h) + public DrawableHitCircle(HitCircle h) : base(h) { osuObject = h; Origin = Anchor.Centre; Position = osuObject.Position; + Scale = new Vector2(osuObject.Scale); Children = new Drawable[] { @@ -64,14 +64,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables Size = circle.DrawSize; } - protected override void LoadComplete() - { - base.LoadComplete(); - - //force application of the state that was set before we loaded. - UpdateState(State); - } - double hit50 = 150; double hit100 = 80; double hit300 = 30; @@ -113,7 +105,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables ApproachCircle.Alpha = 0; ApproachCircle.Scale = new Vector2(2); explode.Alpha = 0; - Scale = new Vector2(0.5f); //this will probably need to be moved to DrawableHitObject at some point. } protected override void UpdatePreemptState() @@ -138,25 +129,12 @@ namespace osu.Game.Modes.Osu.Objects.Drawables case ArmedState.Idle: Delay(osuObject.Duration + TIME_PREEMPT); FadeOut(TIME_FADEOUT); - - explosion?.Expire(); - explosion = null; break; case ArmedState.Miss: - ring.FadeOut(); - circle.FadeOut(); - number.FadeOut(); - glow.FadeOut(); - - explosion?.Expire(); - explosion = null; - - Schedule(() => Add(explosion = new HitExplosion((OsuJudgementInfo)Judgement))); - - FadeOut(800); + FadeOut(TIME_FADEOUT / 5); break; case ArmedState.Hit: - const double flash_in = 30; + const double flash_in = 40; flash.FadeTo(0.8f, flash_in); flash.Delay(flash_in); @@ -164,8 +142,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables explode.FadeIn(flash_in); - Schedule(() => Add(explosion = new HitExplosion((OsuJudgementInfo)Judgement))); - Delay(flash_in, true); //after the flash, we can hide some elements that were behind it diff --git a/osu.Game.Mode.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs similarity index 79% rename from osu.Game.Mode.Osu/Objects/Drawables/DrawableOsuHitObject.cs rename to osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 80e1f2bb7f..9e1fb93cd5 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Generic; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + using System.ComponentModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using osu.Game.Modes.Objects; using osu.Game.Modes.Objects.Drawables; @@ -11,9 +9,9 @@ namespace osu.Game.Modes.Osu.Objects.Drawables { public class DrawableOsuHitObject : DrawableHitObject { - protected const float TIME_PREEMPT = 600; - protected const float TIME_FADEIN = 400; - protected const float TIME_FADEOUT = 500; + public const float TIME_PREEMPT = 600; + public const float TIME_FADEIN = 400; + public const float TIME_FADEOUT = 500; public DrawableOsuHitObject(OsuHitObject hitObject) : base(hitObject) @@ -26,7 +24,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables { if (!IsLoaded) return; - Flush(true); + Flush(); UpdateInitialState(); diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs new file mode 100644 index 0000000000..38cee11f23 --- /dev/null +++ b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs @@ -0,0 +1,141 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Game.Modes.Objects.Drawables; +using osu.Game.Modes.Osu.Objects.Drawables.Pieces; +using OpenTK; +using osu.Framework.Input; + +namespace osu.Game.Modes.Osu.Objects.Drawables +{ + class DrawableSlider : DrawableOsuHitObject + { + private Slider slider; + + private DrawableHitCircle initialCircle; + + private List components = new List(); + + SliderBody body; + SliderBall ball; + + SliderBouncer bouncer1, bouncer2; + + public DrawableSlider(Slider s) : base(s) + { + slider = s; + + Children = new Drawable[] + { + body = new SliderBody(s) + { + Position = s.Position, + PathWidth = s.Scale * 72, + }, + bouncer1 = new SliderBouncer(s, false) + { + Position = s.Curve.PositionAt(1), + Scale = new Vector2(s.Scale), + }, + bouncer2 = new SliderBouncer(s, true) + { + Position = s.Position, + Scale = new Vector2(s.Scale), + }, + ball = new SliderBall(s) + { + Scale = new Vector2(s.Scale), + }, + initialCircle = new DrawableHitCircle(new HitCircle + { + StartTime = s.StartTime, + Position = s.Position, + Scale = s.Scale, + Colour = s.Colour, + Sample = s.Sample, + }), + }; + + components.Add(body); + components.Add(ball); + components.Add(bouncer1); + components.Add(bouncer2); + } + + // Since the DrawableSlider itself is just a container without a size we need to + // pass all input through. + public override bool Contains(Vector2 screenSpacePos) => true; + + int currentRepeat; + + protected override void Update() + { + base.Update(); + + double progress = MathHelper.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1); + + int repeat = (int)(progress * slider.RepeatCount); + progress = (progress * slider.RepeatCount) % 1; + + if (repeat > currentRepeat) + { + if (ball.Tracking) + PlaySample(); + currentRepeat = repeat; + } + + if (repeat % 2 == 1) + progress = 1 - progress; + + bouncer2.Position = slider.Curve.PositionAt(body.SnakedEnd ?? 0); + + //todo: we probably want to reconsider this before adding scoring, but it looks and feels nice. + if (initialCircle.Judgement?.Result != HitResult.Hit) + initialCircle.Position = slider.Curve.PositionAt(progress); + + components.ForEach(c => c.UpdateProgress(progress, repeat)); + } + + protected override void CheckJudgement(bool userTriggered) + { + var j = Judgement as OsuJudgementInfo; + var sc = initialCircle.Judgement as OsuJudgementInfo; + + if (!userTriggered && Time.Current >= HitObject.EndTime) + { + j.Score = sc.Score; + j.Result = sc.Result; + } + } + + protected override void UpdateInitialState() + { + base.UpdateInitialState(); + body.Alpha = 1; + + //we need to be visible to handle input events. note that we still don't get enough events (we don't get a position if the mouse hasn't moved since the slider appeared). + ball.Alpha = 0.01f; + } + + protected override void UpdateState(ArmedState state) + { + base.UpdateState(state); + + ball.FadeIn(); + + Delay(HitObject.Duration, true); + + body.FadeOut(160); + ball.FadeOut(160); + + FadeOut(800); + } + } + + internal interface ISliderProgress + { + void UpdateProgress(double progress, int repeat); + } +} \ No newline at end of file diff --git a/osu.Game.Modes.Osu/Objects/Drawables/HitExplosion.cs b/osu.Game.Modes.Osu/Objects/Drawables/HitExplosion.cs new file mode 100644 index 0000000000..cdb087f6c3 --- /dev/null +++ b/osu.Game.Modes.Osu/Objects/Drawables/HitExplosion.cs @@ -0,0 +1,84 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transformations; +using osu.Game.Modes.Objects.Drawables; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Modes.Osu.Objects.Drawables +{ + public class HitExplosion : FlowContainer + { + private readonly OsuJudgementInfo judgement; + private SpriteText line1; + private SpriteText line2; + + public HitExplosion(OsuJudgementInfo judgement, OsuHitObject h = null) + { + this.judgement = judgement; + AutoSizeAxes = Axes.Both; + Origin = Anchor.Centre; + + Direction = FlowDirection.VerticalOnly; + Spacing = new Vector2(0, 2); + Position = (h?.EndPosition ?? Vector2.Zero) + judgement.PositionOffset; + + Children = new Drawable[] + { + line1 = new SpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = judgement.Score.GetDescription(), + Font = @"Venera", + TextSize = 16, + }, + line2 = new SpriteText + { + Text = judgement.Combo.GetDescription(), + Font = @"Venera", + TextSize = 11, + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + if (judgement.Result == HitResult.Miss) + { + FadeInFromZero(60); + + ScaleTo(1.6f); + ScaleTo(1, 100, EasingTypes.In); + + MoveToOffset(new Vector2(0, 100), 800, EasingTypes.InQuint); + RotateTo(40, 800, EasingTypes.InQuint); + + Delay(600); + FadeOut(200); + } + else + { + line1.TransformSpacingTo(new Vector2(14, 0), 1800, EasingTypes.OutQuint); + line2.TransformSpacingTo(new Vector2(14, 0), 1800, EasingTypes.OutQuint); + FadeOut(500); + } + + switch (judgement.Result) + { + case HitResult.Miss: + Colour = Color4.Red; + break; + } + + Expire(); + } + } +} \ No newline at end of file diff --git a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/ApproachCircle.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/ApproachCircle.cs similarity index 80% rename from osu.Game.Mode.Osu/Objects/Drawables/Pieces/ApproachCircle.cs rename to osu.Game.Modes.Osu/Objects/Drawables/Pieces/ApproachCircle.cs index 0932fef28f..356a6c1c35 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/ApproachCircle.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/ApproachCircle.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 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.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/CirclePiece.cs similarity index 86% rename from osu.Game.Mode.Osu/Objects/Drawables/Pieces/CirclePiece.cs rename to osu.Game.Modes.Osu/Objects/Drawables/Pieces/CirclePiece.cs index fd55a8315a..7cfd0d43ab 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/CirclePiece.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/CirclePiece.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 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.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/ExplodePiece.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/ExplodePiece.cs similarity index 74% rename from osu.Game.Mode.Osu/Objects/Drawables/Pieces/ExplodePiece.cs rename to osu.Game.Modes.Osu/Objects/Drawables/Pieces/ExplodePiece.cs index 20277f243a..6f9e2a979a 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/ExplodePiece.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/ExplodePiece.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics; +//Copyright (c) 2007-2016 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; diff --git a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/FlashPiece.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/FlashPiece.cs similarity index 75% rename from osu.Game.Mode.Osu/Objects/Drawables/Pieces/FlashPiece.cs rename to osu.Game.Modes.Osu/Objects/Drawables/Pieces/FlashPiece.cs index 60ff8d5595..7ae3306be7 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/FlashPiece.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/FlashPiece.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics; +//Copyright (c) 2007-2016 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 osu.Framework.Graphics.Sprites; using OpenTK; diff --git a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/GlowPiece.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/GlowPiece.cs similarity index 79% rename from osu.Game.Mode.Osu/Objects/Drawables/Pieces/GlowPiece.cs rename to osu.Game.Modes.Osu/Objects/Drawables/Pieces/GlowPiece.cs index 9a8118acbd..a9e1c9c369 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/GlowPiece.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/GlowPiece.cs @@ -1,4 +1,7 @@ -using osu.Framework.Allocation; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; diff --git a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/NumberPiece.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/NumberPiece.cs similarity index 78% rename from osu.Game.Mode.Osu/Objects/Drawables/Pieces/NumberPiece.cs rename to osu.Game.Modes.Osu/Objects/Drawables/Pieces/NumberPiece.cs index b005c7daae..0c5d2e9186 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/NumberPiece.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/NumberPiece.cs @@ -1,4 +1,7 @@ -using osu.Framework.Allocation; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; diff --git a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/RingPiece.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/RingPiece.cs similarity index 78% rename from osu.Game.Mode.Osu/Objects/Drawables/Pieces/RingPiece.cs rename to osu.Game.Modes.Osu/Objects/Drawables/Pieces/RingPiece.cs index 188346ce9d..c5fdbbfdfb 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/RingPiece.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/RingPiece.cs @@ -1,4 +1,7 @@ -using osu.Framework.Allocation; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBall.cs new file mode 100644 index 0000000000..0df80984bb --- /dev/null +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -0,0 +1,116 @@ +//Copyright (c) 2007-2016 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 osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transformations; +using osu.Framework.Input; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces +{ + public class SliderBall : Container, ISliderProgress + { + private readonly Slider slider; + private Box follow; + + const float width = 140; + + public SliderBall(Slider slider) + { + this.slider = slider; + Masking = true; + AutoSizeAxes = Axes.Both; + BlendingMode = BlendingMode.Additive; + Origin = Anchor.Centre; + BorderThickness = 10; + BorderColour = Color4.Orange; + + Children = new Drawable[] + { + follow = new Box + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Colour = Color4.Orange, + Width = width, + Height = width, + Alpha = 0, + }, + new Container + { + Masking = true, + AutoSizeAxes = Axes.Both, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + BorderThickness = 14, + BorderColour = Color4.White, + Alpha = 1, + CornerRadius = width / 2, + Children = new[] + { + new Box + { + Colour = slider.Colour, + Alpha = 0.4f, + Width = width, + Height = width, + }, + } + } + }; + } + + private InputState lastState; + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + lastState = state; + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + lastState = state; + return base.OnMouseUp(state, args); + } + + protected override bool OnMouseMove(InputState state) + { + lastState = state; + return base.OnMouseMove(state); + } + + bool tracking; + public bool Tracking + { + get { return tracking; } + set + { + if (value == tracking) return; + + tracking = value; + + follow.ScaleTo(tracking ? 2.8f : 1, 300, EasingTypes.OutQuint); + follow.FadeTo(tracking ? 0.2f : 0, 300, EasingTypes.OutQuint); + } + } + + private bool canCurrentlyTrack => Time.Current >= slider.StartTime && Time.Current < slider.EndTime; + + protected override void Update() + { + base.Update(); + + CornerRadius = DrawWidth / 2; + Tracking = canCurrentlyTrack && lastState != null && Contains(lastState.Mouse.NativeState.Position) && lastState.Mouse.HasMainButtonPressed; + } + + public void UpdateProgress(double progress, int repeat) + { + Position = slider.Curve.PositionAt(progress); + } + } +} \ No newline at end of file diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBody.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBody.cs new file mode 100644 index 0000000000..c0bd29bc02 --- /dev/null +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBody.cs @@ -0,0 +1,163 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.OpenGL.Textures; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Game.Configuration; +using OpenTK; +using OpenTK.Graphics.ES30; + +namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces +{ + public class SliderBody : Container, ISliderProgress + { + private Path path; + private BufferedContainer container; + + public float PathWidth + { + get { return path.PathWidth; } + set + { + path.PathWidth = value; + } + } + + public double? SnakedStart { get; private set; } + public double? SnakedEnd { get; private set; } + + private Slider slider; + public SliderBody(Slider s) + { + slider = s; + + Children = new Drawable[] + { + container = new BufferedContainer + { + CacheDrawnFrameBuffer = true, + Children = new Drawable[] + { + path = new Path + { + BlendingMode = BlendingMode.None, + }, + } + }, + }; + + container.Attach(RenderbufferInternalFormat.DepthComponent16); + } + + public void SetRange(double p0, double p1) + { + if (p0 > p1) + MathHelper.Swap(ref p0, ref p1); + + if (updateSnaking(p0, p1)) + { + // Autosizing does not give us the desired behaviour here. + // We want the container to have the same size as the slider, + // and to be positioned such that the slider head is at (0,0). + container.Size = path.Size; + container.Position = -path.PositionInBoundingBox(slider.Curve.PositionAt(0) - currentCurve[0]); + + container.ForceRedraw(); + } + } + + private Bindable snakingIn; + private Bindable snakingOut; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + snakingIn = config.GetBindable(OsuConfig.SnakingInSliders); + snakingOut = config.GetBindable(OsuConfig.SnakingOutSliders); + + int textureWidth = (int)PathWidth * 2; + + //initialise background + var upload = new TextureUpload(textureWidth * 4); + var bytes = upload.Data; + + const float aa_portion = 0.02f; + const float border_portion = 0.18f; + const float gradient_portion = 1 - border_portion; + + const float opacity_at_centre = 0.3f; + const float opacity_at_edge = 0.8f; + + for (int i = 0; i < textureWidth; i++) + { + float progress = (float)i / (textureWidth - 1); + + if (progress <= border_portion) + { + bytes[i * 4] = 255; + bytes[i * 4 + 1] = 255; + bytes[i * 4 + 2] = 255; + bytes[i * 4 + 3] = (byte)(Math.Min(progress / aa_portion, 1) * 255); + } + else + { + progress -= border_portion; + + bytes[i * 4] = (byte)(slider.Colour.R * 255); + bytes[i * 4 + 1] = (byte)(slider.Colour.G * 255); + bytes[i * 4 + 2] = (byte)(slider.Colour.B * 255); + bytes[i * 4 + 3] = (byte)((opacity_at_edge - (opacity_at_edge - opacity_at_centre) * progress / gradient_portion) * (slider.Colour.A * 255)); + } + } + + var texture = new Texture(textureWidth, 1); + texture.SetData(upload); + path.Texture = texture; + } + + private List currentCurve = new List(); + private bool updateSnaking(double p0, double p1) + { + if (SnakedStart == p0 && SnakedEnd == p1) return false; + + SnakedStart = p0; + SnakedEnd = p1; + + slider.Curve.GetPathToProgress(currentCurve, p0, p1); + + path.ClearVertices(); + foreach (Vector2 p in currentCurve) + path.AddVertex(p - currentCurve[0]); + + return true; + } + + public void UpdateProgress(double progress, int repeat) + { + double start = 0; + double end = snakingIn ? MathHelper.Clamp((Time.Current - (slider.StartTime - DrawableOsuHitObject.TIME_PREEMPT)) / DrawableOsuHitObject.TIME_FADEIN, 0, 1) : 1; + + if (repeat >= slider.RepeatCount - 1) + { + if (Math.Min(repeat, slider.RepeatCount - 1) % 2 == 1) + { + start = 0; + end = snakingOut ? progress : 1; + } + else + { + start = snakingOut ? progress : 0; + } + } + + SetRange(start, end); + } + } +} \ No newline at end of file diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBouncer.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBouncer.cs new file mode 100644 index 0000000000..47a345bdc3 --- /dev/null +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBouncer.cs @@ -0,0 +1,58 @@ +//Copyright (c) 2007-2016 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.Framework.Graphics.Sprites; +using osu.Game.Graphics; + +namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces +{ + public class SliderBouncer : Container, ISliderProgress + { + private readonly Slider slider; + private readonly bool isEnd; + private TextAwesome icon; + + public SliderBouncer(Slider slider, bool isEnd) + { + this.slider = slider; + this.isEnd = isEnd; + + AutoSizeAxes = Axes.Both; + BlendingMode = BlendingMode.Additive; + Origin = Anchor.Centre; + + Children = new Drawable[] + { + icon = new TextAwesome + { + Icon = FontAwesome.fa_eercast, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + TextSize = 48, + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + icon.RotateTo(360, 1000); + icon.Loop(); + } + + public void UpdateProgress(double progress, int repeat) + { + if (Time.Current < slider.StartTime) + Alpha = 0; + + Alpha = repeat + 1 < slider.RepeatCount && repeat % 2 == (isEnd ? 0 : 1) ? 1 : 0; + } + } +} diff --git a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/Triangles.cs b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/Triangles.cs similarity index 82% rename from osu.Game.Mode.Osu/Objects/Drawables/Pieces/Triangles.cs rename to osu.Game.Modes.Osu/Objects/Drawables/Pieces/Triangles.cs index 3ef13792de..2025934e71 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/Pieces/Triangles.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/Pieces/Triangles.cs @@ -1,4 +1,7 @@ -using osu.Framework.Allocation; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -10,6 +13,8 @@ namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces { public class Triangles : Container { + public override bool HandleInput => false; + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game.Mode.Osu/Objects/HitCircle.cs b/osu.Game.Modes.Osu/Objects/HitCircle.cs similarity index 100% rename from osu.Game.Mode.Osu/Objects/HitCircle.cs rename to osu.Game.Modes.Osu/Objects/HitCircle.cs diff --git a/osu.Game.Mode.Osu/Objects/OsuHitObject.cs b/osu.Game.Modes.Osu/Objects/OsuHitObject.cs similarity index 63% rename from osu.Game.Mode.Osu/Objects/OsuHitObject.cs rename to osu.Game.Modes.Osu/Objects/OsuHitObject.cs index 35f24699f1..12fdf1a344 100644 --- a/osu.Game.Mode.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Modes.Osu/Objects/OsuHitObject.cs @@ -5,6 +5,7 @@ using System; using osu.Game.Beatmaps.Samples; using osu.Game.Modes.Objects; using OpenTK; +using osu.Game.Beatmaps; namespace osu.Game.Modes.Osu.Objects { @@ -12,6 +13,17 @@ namespace osu.Game.Modes.Osu.Objects { public Vector2 Position { get; set; } + public float Scale { get; set; } = 1; + + public virtual Vector2 EndPosition => Position; + + public override void SetDefaultsFromBeatmap(Beatmap beatmap) + { + base.SetDefaultsFromBeatmap(beatmap); + + Scale = (1.0f - 0.7f * (beatmap.BeatmapInfo.BaseDifficulty.CircleSize - 5) / 5) / 2; + } + [Flags] internal enum HitObjectType { diff --git a/osu.Game.Mode.Osu/Objects/OsuHitObjectConverter.cs b/osu.Game.Modes.Osu/Objects/OsuHitObjectConverter.cs similarity index 100% rename from osu.Game.Mode.Osu/Objects/OsuHitObjectConverter.cs rename to osu.Game.Modes.Osu/Objects/OsuHitObjectConverter.cs diff --git a/osu.Game.Mode.Osu/Objects/OsuHitObjectParser.cs b/osu.Game.Modes.Osu/Objects/OsuHitObjectParser.cs similarity index 89% rename from osu.Game.Mode.Osu/Objects/OsuHitObjectParser.cs rename to osu.Game.Modes.Osu/Objects/OsuHitObjectParser.cs index 932a997769..43755b3996 100644 --- a/osu.Game.Mode.Osu/Objects/OsuHitObjectParser.cs +++ b/osu.Game.Modes.Osu/Objects/OsuHitObjectParser.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -80,7 +83,7 @@ namespace osu.Game.Modes.Osu.Objects s.Curve = new SliderCurve { - Path = points, + ControlPoints = points, Length = length, CurveType = curveType }; @@ -98,7 +101,10 @@ namespace osu.Game.Modes.Osu.Objects } result.Position = new Vector2(int.Parse(split[0]), int.Parse(split[1])); result.StartTime = double.Parse(split[2]); - result.Sample = new HitSampleInfo { Type = (SampleType)int.Parse(split[4]) }; + result.Sample = new HitSampleInfo { + Type = (SampleType)int.Parse(split[4]), + Set = SampleSet.Soft, + }; result.NewCombo = combo; // TODO: "addition" field return result; diff --git a/osu.Game.Mode.Osu/Objects/Slider.cs b/osu.Game.Modes.Osu/Objects/Slider.cs similarity index 79% rename from osu.Game.Mode.Osu/Objects/Slider.cs rename to osu.Game.Modes.Osu/Objects/Slider.cs index a0cdbeae7c..27210eec10 100644 --- a/osu.Game.Mode.Osu/Objects/Slider.cs +++ b/osu.Game.Modes.Osu/Objects/Slider.cs @@ -1,9 +1,8 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Database; using osu.Game.Beatmaps; -using System; +using OpenTK; namespace osu.Game.Modes.Osu.Objects { @@ -11,10 +10,14 @@ namespace osu.Game.Modes.Osu.Objects { public override double EndTime => StartTime + RepeatCount * Curve.Length / Velocity; + public override Vector2 EndPosition => RepeatCount % 2 == 0 ? Position : Curve.PositionAt(1); + public double Velocity; public override void SetDefaultsFromBeatmap(Beatmap beatmap) { + base.SetDefaultsFromBeatmap(beatmap); + Velocity = 100 / beatmap.BeatLengthAt(StartTime, true) * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier; } diff --git a/osu.Game.Mode.Osu/Objects/SliderCurve.cs b/osu.Game.Modes.Osu/Objects/SliderCurve.cs similarity index 69% rename from osu.Game.Mode.Osu/Objects/SliderCurve.cs rename to osu.Game.Modes.Osu/Objects/SliderCurve.cs index d80a441daf..961658112f 100644 --- a/osu.Game.Mode.Osu/Objects/SliderCurve.cs +++ b/osu.Game.Modes.Osu/Objects/SliderCurve.cs @@ -1,12 +1,11 @@ -// Copyright (c) 2007-2016 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; using OpenTK; using System.Linq; -using System.Diagnostics; using osu.Framework.MathUtils; -using System; +using System.Diagnostics; namespace osu.Game.Modes.Osu.Objects { @@ -14,21 +13,39 @@ namespace osu.Game.Modes.Osu.Objects { public double Length; - public List Path; + public List ControlPoints; public CurveTypes CurveType; private List calculatedPath = new List(); private List cumulativeLength = new List(); - private List calculateSubpath(List subpath) + private List calculateSubpath(List subControlPoints) { switch (CurveType) { case CurveTypes.Linear: - return subpath; + return subControlPoints; + case CurveTypes.PerfectCurve: + // If we have a different amount than 3 control points, use bezier for perfect curves. + if (ControlPoints.Count != 3) + return new BezierApproximator(subControlPoints).CreateBezier(); + else + { + Debug.Assert(subControlPoints.Count == 3); + + // Here we have exactly 3 control points. Attempt to fit a circular arc. + List subpath = new CircularArcApproximator(subControlPoints[0], subControlPoints[1], subControlPoints[2]).CreateArc(); + + if (subpath.Count == 0) + // For some reason a circular arc could not be fit to the 3 given points. Fall back + // to a numerically stable bezier approximation. + subpath = new BezierApproximator(subControlPoints).CreateBezier(); + + return subpath; + } default: - return new BezierApproximator(subpath).CreateBezier(); + return new BezierApproximator(subControlPoints).CreateBezier(); } } @@ -39,21 +56,19 @@ namespace osu.Game.Modes.Osu.Objects // Sliders may consist of various subpaths separated by two consecutive vertices // with the same position. The following loop parses these subpaths and computes // their shape independently, consecutively appending them to calculatedPath. - List subpath = new List(); - for (int i = 0; i < Path.Count; ++i) + List subControlPoints = new List(); + for (int i = 0; i < ControlPoints.Count; ++i) { - subpath.Add(Path[i]); - if (i == Path.Count - 1 || Path[i] == Path[i + 1]) + subControlPoints.Add(ControlPoints[i]); + if (i == ControlPoints.Count - 1 || ControlPoints[i] == ControlPoints[i + 1]) { - // If we already constructed a subpath previously, then the new subpath - // will have as starting position the end position of the previous subpath. - // Hence we can and should remove the previous endpoint to avoid a segment - // with 0 length. - if (calculatedPath.Count > 0) - calculatedPath.RemoveAt(calculatedPath.Count - 1); + List subpath = calculateSubpath(subControlPoints); + for (int j = 0; j < subpath.Count; ++j) + // Only add those vertices that add a new segment to the path. + if (calculatedPath.Count == 0 || calculatedPath.Last() != subpath[j]) + calculatedPath.Add(subpath[j]); - calculatedPath.AddRange(calculateSubpath(subpath)); - subpath.Clear(); + subControlPoints.Clear(); } } } diff --git a/osu.Game.Mode.Osu/Objects/Spinner.cs b/osu.Game.Modes.Osu/Objects/Spinner.cs similarity index 100% rename from osu.Game.Mode.Osu/Objects/Spinner.cs rename to osu.Game.Modes.Osu/Objects/Spinner.cs diff --git a/osu.Game.Mode.Osu/OpenTK.dll.config b/osu.Game.Modes.Osu/OpenTK.dll.config similarity index 90% rename from osu.Game.Mode.Osu/OpenTK.dll.config rename to osu.Game.Modes.Osu/OpenTK.dll.config index 5620e3d9e2..1dd145f0c4 100644 --- a/osu.Game.Mode.Osu/OpenTK.dll.config +++ b/osu.Game.Modes.Osu/OpenTK.dll.config @@ -1,3 +1,8 @@ + + diff --git a/osu.Game.Mode.Osu/OsuRuleset.cs b/osu.Game.Modes.Osu/OsuRuleset.cs similarity index 100% rename from osu.Game.Mode.Osu/OsuRuleset.cs rename to osu.Game.Modes.Osu/OsuRuleset.cs diff --git a/osu.Game.Modes.Osu/OsuScore.cs b/osu.Game.Modes.Osu/OsuScore.cs new file mode 100644 index 0000000000..d08f75fecf --- /dev/null +++ b/osu.Game.Modes.Osu/OsuScore.cs @@ -0,0 +1,15 @@ +//Copyright (c) 2007-2016 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; + +namespace osu.Game.Modes.Osu +{ + class OsuScore : Score + { + } +} diff --git a/osu.Game.Mode.Osu/OsuScoreProcessor.cs b/osu.Game.Modes.Osu/OsuScoreProcessor.cs similarity index 87% rename from osu.Game.Mode.Osu/OsuScoreProcessor.cs rename to osu.Game.Modes.Osu/OsuScoreProcessor.cs index a5ebda6834..572506050b 100644 --- a/osu.Game.Mode.Osu/OsuScoreProcessor.cs +++ b/osu.Game.Modes.Osu/OsuScoreProcessor.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 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; diff --git a/osu.Game.Mode.Osu/Properties/AssemblyInfo.cs b/osu.Game.Modes.Osu/Properties/AssemblyInfo.cs similarity index 86% rename from osu.Game.Mode.Osu/Properties/AssemblyInfo.cs rename to osu.Game.Modes.Osu/Properties/AssemblyInfo.cs index 1b0664acf5..81c3d6298a 100644 --- a/osu.Game.Mode.Osu/Properties/AssemblyInfo.cs +++ b/osu.Game.Modes.Osu/Properties/AssemblyInfo.cs @@ -1,4 +1,7 @@ -using System.Reflection; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/osu.Game.Mode.Osu/UI/OsuComboCounter.cs b/osu.Game.Modes.Osu/UI/OsuComboCounter.cs similarity index 95% rename from osu.Game.Mode.Osu/UI/OsuComboCounter.cs rename to osu.Game.Modes.Osu/UI/OsuComboCounter.cs index dc90ee2779..8a6e9a30e2 100644 --- a/osu.Game.Mode.Osu/UI/OsuComboCounter.cs +++ b/osu.Game.Modes.Osu/UI/OsuComboCounter.cs @@ -17,7 +17,7 @@ namespace osu.Game.Modes.Osu.UI protected virtual float PopOutSmallScale => 1.1f; protected virtual bool CanPopOutWhileRolling => false; - public Vector2 PopOutScale = new Vector2(2.5f); + public Vector2 PopOutScale = new Vector2(1.6f); protected override void LoadComplete() { diff --git a/osu.Game.Mode.Osu/UI/OsuHitRenderer.cs b/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs similarity index 90% rename from osu.Game.Mode.Osu/UI/OsuHitRenderer.cs rename to osu.Game.Modes.Osu/UI/OsuHitRenderer.cs index 01f95de5fb..02e7521c4f 100644 --- a/osu.Game.Mode.Osu/UI/OsuHitRenderer.cs +++ b/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs @@ -6,7 +6,6 @@ using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.Objects.Drawables; using osu.Game.Modes.UI; -using OsuConverter = osu.Game.Modes.Osu.Objects.OsuHitObjectConverter; namespace osu.Game.Modes.Osu.UI { diff --git a/osu.Game.Mode.Osu/UI/OsuPlayfield.cs b/osu.Game.Modes.Osu/UI/OsuPlayfield.cs similarity index 70% rename from osu.Game.Mode.Osu/UI/OsuPlayfield.cs rename to osu.Game.Modes.Osu/UI/OsuPlayfield.cs index 1e69cd78a3..9cf873dabf 100644 --- a/osu.Game.Mode.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Modes.Osu/UI/OsuPlayfield.cs @@ -3,19 +3,18 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.Objects.Drawables; using osu.Game.Modes.UI; using OpenTK; -using OpenTK.Graphics; namespace osu.Game.Modes.Osu.UI { public class OsuPlayfield : Playfield { private Container approachCircles; + private Container judgementLayer; public override Vector2 Size { @@ -35,24 +34,40 @@ namespace osu.Game.Modes.Osu.UI RelativeSizeAxes = Axes.Both; Size = new Vector2(0.75f); - AddInternal(new Drawable[] + Add(new Drawable[] { + judgementLayer = new Container + { + RelativeSizeAxes = Axes.Both, + Depth = 1, + }, approachCircles = new Container { RelativeSizeAxes = Axes.Both, + Depth = -1, } }); } public override void Add(DrawableHitObject h) { + h.Depth = (float)h.HitObject.StartTime; DrawableHitCircle c = h as DrawableHitCircle; if (c != null) { approachCircles.Add(c.ApproachCircle.CreateProxy()); } + h.OnJudgement += judgement; + base.Add(h); } + + private void judgement(DrawableHitObject h, JudgementInfo j) + { + HitExplosion explosion = new HitExplosion((OsuJudgementInfo)j, (OsuHitObject)h.HitObject); + + judgementLayer.Add(explosion); + } } } \ No newline at end of file diff --git a/osu.Game.Mode.Osu/UI/OsuScoreOverlay.cs b/osu.Game.Modes.Osu/UI/OsuScoreOverlay.cs similarity index 87% rename from osu.Game.Mode.Osu/UI/OsuScoreOverlay.cs rename to osu.Game.Modes.Osu/UI/OsuScoreOverlay.cs index 0c967999b3..36a1f1c100 100644 --- a/osu.Game.Mode.Osu/UI/OsuScoreOverlay.cs +++ b/osu.Game.Modes.Osu/UI/OsuScoreOverlay.cs @@ -12,18 +12,20 @@ namespace osu.Game.Modes.Osu.UI { public class OsuScoreOverlay : ScoreOverlay { - protected override PercentageCounter CreateAccuracyCounter() => new PercentageCounter() - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Position = new Vector2(0, 45) - }; - protected override ScoreCounter CreateScoreCounter() => new ScoreCounter() { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - TextSize = 60 + TextSize = 60, + Margin = new MarginPadding { Right = 5 }, + }; + + protected override PercentageCounter CreateAccuracyCounter() => new PercentageCounter() + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Position = new Vector2(0, 55), + Margin = new MarginPadding { Right = 5 }, }; protected override ComboCounter CreateComboCounter() => new OsuComboCounter() diff --git a/osu.Game.Mode.Osu/app.config b/osu.Game.Modes.Osu/app.config similarity index 74% rename from osu.Game.Mode.Osu/app.config rename to osu.Game.Modes.Osu/app.config index 757f23cb22..c42343ec69 100644 --- a/osu.Game.Mode.Osu/app.config +++ b/osu.Game.Modes.Osu/app.config @@ -1,4 +1,9 @@ + + diff --git a/osu.Game.Mode.Osu/osu.Game.Modes.Osu.csproj b/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj similarity index 90% rename from osu.Game.Mode.Osu/osu.Game.Modes.Osu.csproj rename to osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj index ba6e714e0a..a9a346f563 100644 --- a/osu.Game.Mode.Osu/osu.Game.Modes.Osu.csproj +++ b/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj @@ -42,6 +42,7 @@ + @@ -52,7 +53,10 @@ + + + @@ -81,6 +85,9 @@ + + osu.licenseheader + diff --git a/osu.Game.Modes.Osu/packages.config b/osu.Game.Modes.Osu/packages.config new file mode 100644 index 0000000000..10451d4b70 --- /dev/null +++ b/osu.Game.Modes.Osu/packages.config @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/osu.Game.Modes.Taiko/OpenTK.dll.config b/osu.Game.Modes.Taiko/OpenTK.dll.config index 5620e3d9e2..1dd145f0c4 100644 --- a/osu.Game.Modes.Taiko/OpenTK.dll.config +++ b/osu.Game.Modes.Taiko/OpenTK.dll.config @@ -1,3 +1,8 @@ + + diff --git a/osu.Game.Modes.Taiko/Properties/AssemblyInfo.cs b/osu.Game.Modes.Taiko/Properties/AssemblyInfo.cs index fe4ac44ab7..6aef41bbf8 100644 --- a/osu.Game.Modes.Taiko/Properties/AssemblyInfo.cs +++ b/osu.Game.Modes.Taiko/Properties/AssemblyInfo.cs @@ -1,4 +1,7 @@ -using System.Reflection; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj b/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj index d49c3c2466..355f71d0df 100644 --- a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj +++ b/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj @@ -55,6 +55,9 @@ + + osu.licenseheader + @@ -63,7 +66,7 @@ {C76BF5B3-985E-4D39-95FE-97C9C879B83A} osu.Framework - + {C92A607B-1FDD-4954-9F92-03FF547D9080} osu.Game.Modes.Osu diff --git a/osu.Game.Modes.Taiko/packages.config b/osu.Game.Modes.Taiko/packages.config index 4da07d9f06..3c9e7e3fdc 100644 --- a/osu.Game.Modes.Taiko/packages.config +++ b/osu.Game.Modes.Taiko/packages.config @@ -1,4 +1,9 @@  + + \ No newline at end of file diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index d59e90c2f4..5e1ce553d8 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -66,7 +66,7 @@ {c76bf5b3-985e-4d39-95fe-97c9c879b83a} osu.Framework - + {c92a607b-1fdd-4954-9f92-03ff547d9080} osu.Game.Modes.Osu diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index 3f5fe58ab5..db769bccc9 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps.Drawables } } - public BeatmapGroup(WorkingBeatmap beatmap) + public BeatmapGroup(WorkingBeatmap beatmap, BeatmapSetInfo set = null) { this.beatmap = beatmap; diff --git a/osu.Game/Beatmaps/Events/EventType.cs b/osu.Game/Beatmaps/Events/EventType.cs index 1f7e8d2aa5..a982366401 100644 --- a/osu.Game/Beatmaps/Events/EventType.cs +++ b/osu.Game/Beatmaps/Events/EventType.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; namespace osu.Game.Beatmaps.Events { public enum EventType diff --git a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs index b5dd0c995e..83cd60eca3 100644 --- a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using System.Collections.Generic; using System.IO; using osu.Game.Modes.Objects; diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index b1eaeb467d..12a26dafa8 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using System.Collections.Generic; using System.Globalization; using System.IO; diff --git a/osu.Game/Beatmaps/IO/ArchiveReader.cs b/osu.Game/Beatmaps/IO/ArchiveReader.cs index a052b9eb0d..ca90b424a6 100644 --- a/osu.Game/Beatmaps/IO/ArchiveReader.cs +++ b/osu.Game/Beatmaps/IO/ArchiveReader.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using System.Collections.Generic; using System.IO; using osu.Framework.IO.Stores; diff --git a/osu.Game/Beatmaps/IO/OszArchiveReader.cs b/osu.Game/Beatmaps/IO/OszArchiveReader.cs index 85ee2d19b9..14738802f6 100644 --- a/osu.Game/Beatmaps/IO/OszArchiveReader.cs +++ b/osu.Game/Beatmaps/IO/OszArchiveReader.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using System.IO; using System.Linq; using System.Security.Cryptography; diff --git a/osu.Game/Configuration/ConfineMouseMode.cs b/osu.Game/Configuration/ConfineMouseMode.cs new file mode 100644 index 0000000000..1af9f86d35 --- /dev/null +++ b/osu.Game/Configuration/ConfineMouseMode.cs @@ -0,0 +1,10 @@ +using System; +namespace osu.Game.Configuration +{ + public enum ConfineMouseMode + { + Never, + Fullscreen, + Always + } +} \ No newline at end of file diff --git a/osu.Game/Configuration/FrameSync.cs b/osu.Game/Configuration/FrameSync.cs new file mode 100644 index 0000000000..fc8a26db04 --- /dev/null +++ b/osu.Game/Configuration/FrameSync.cs @@ -0,0 +1,12 @@ +using System; +namespace osu.Game.Configuration +{ + public enum FrameSync + { + VSync = 1, + Limit120 = 0, + Unlimited = 2, + CompletelyUnlimited = 4, + Custom = 5 + } +} \ No newline at end of file diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 8e5fbfad42..2c5c53cc3f 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -1,6 +1,7 @@ //Copyright (c) 2007-2016 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.Platform; using osu.Game.Modes; @@ -11,6 +12,7 @@ namespace osu.Game.Configuration { protected override void InitialiseDefaults() { +#pragma warning disable CS0612 // Type or member is obsolete Set(OsuConfig.Width, 1366, 640); Set(OsuConfig.Height, 768, 480); Set(OsuConfig.MouseSpeed, 1.0); @@ -96,6 +98,7 @@ namespace osu.Game.Configuration Set(OsuConfig.MouseDisableWheel, false); Set(OsuConfig.MouseSpeed, 1, 0.4, 6); Set(OsuConfig.Offset, 0, -300, 300); + Set(OsuConfig.ScoreMeterScale, 1, 0.5, 2); //Set(OsuConfig.ScoreMeterScale, 1, 0.5, OsuGame.Tournament ? 10 : 2); Set(OsuConfig.DistanceSpacing, 0.8, 0.1, 6); Set(OsuConfig.EditorBeatDivisor, 1, 1, 16); @@ -109,18 +112,19 @@ namespace osu.Game.Configuration Set(OsuConfig.NotifyFriends, true); Set(OsuConfig.NotifySubmittedThread, true); Set(OsuConfig.PopupDuringGameplay, true); - //Set(OsuConfig.ProgressBarType, ProgressBarTypes.Pie); - //Set(OsuConfig.RankType, RankingType.Top); + Set(OsuConfig.ProgressBarType, ProgressBarType.Pie); + Set(OsuConfig.RankType, RankingType.Top); Set(OsuConfig.RefreshRate, 60); Set(OsuConfig.OverrideRefreshRate, Get(OsuConfig.RefreshRate) != 60); //Set(OsuConfig.ScaleMode, ScaleMode.WidescreenConservative); Set(OsuConfig.ScoreboardVisible, true); + Set(OsuConfig.ScoreMeter, ScoreMeterType.Error); //Set(OsuConfig.ScoreMeter, OsuGame.Tournament ? ScoreMeterType.Colour : ScoreMeterType.Error); Set(OsuConfig.ScreenshotId, 0); Set(OsuConfig.MenuSnow, false); Set(OsuConfig.MenuTriangles, true); Set(OsuConfig.SongSelectThumbnails, true); - //Set(OsuConfig.ScreenshotFormat, ImageFileFormat.Jpg); + Set(OsuConfig.ScreenshotFormat, ScreenshotFormat.Jpg); Set(OsuConfig.ShowReplayComments, true); Set(OsuConfig.ShowSpectators, true); Set(OsuConfig.ShowStoryboard, true); @@ -150,10 +154,10 @@ namespace osu.Game.Configuration Set(OsuConfig.AlternativeChatFont, false); Set(OsuConfig.Password, string.Empty); Set(OsuConfig.Username, string.Empty); - Set(OsuConfig.DisplayStarsMaximum, 10, 0, 10); - Set(OsuConfig.DisplayStarsMinimum, 0, 0, 10); + Set(OsuConfig.DisplayStarsMaximum, 10.0, 0.0, 10.0); + Set(OsuConfig.DisplayStarsMinimum, 0.0, 0.0, 10.0); Set(OsuConfig.AudioDevice, string.Empty); - //Set(OsuConfig.ReleaseStream, ReleaseStream.Lazer, true); + Set(OsuConfig.ReleaseStream, ReleaseStream.Lazer); Set(OsuConfig.UpdateFailCount, 0); Set(OsuConfig.SavePassword, false); Set(OsuConfig.SaveUsername, true); @@ -162,7 +166,7 @@ namespace osu.Game.Configuration Set(OsuConfig.Letterboxing, Get(OsuConfig.Fullscreen)); Set(OsuConfig.LetterboxPositionX, 0, -100, 100); Set(OsuConfig.LetterboxPositionY, 0, -100, 100); - //Set(OsuConfig.FrameSync, FrameSync.Limit120); + Set(OsuConfig.FrameSync, FrameSync.Limit120); bool unicodeDefault = false; switch (Get(OsuConfig.Language)) { @@ -177,6 +181,9 @@ namespace osu.Game.Configuration Set(OsuConfig.Ticker, false); Set(OsuConfig.CompatibilityContext, false); Set(OsuConfig.CanForceOptimusCompatibility, true); + Set(OsuConfig.ConfineMouse, Get(OsuConfig.ConfineMouseToFullscreen) ? + ConfineMouseMode.Fullscreen : ConfineMouseMode.Never); +#pragma warning restore CS0612 // Type or member is obsolete } //todo: make a UnicodeString class/struct rather than requiring this helper method. @@ -321,6 +328,8 @@ namespace osu.Game.Configuration RawInput, AbsoluteToOsuWindow, ConfineMouse, + [Obsolete] + ConfineMouseToFullscreen, ShowMenuTips, HiddenShowFirstApproach, ComboColourSliderBall, diff --git a/osu.Game/Configuration/ProgressBarType.cs b/osu.Game/Configuration/ProgressBarType.cs new file mode 100644 index 0000000000..e252c84558 --- /dev/null +++ b/osu.Game/Configuration/ProgressBarType.cs @@ -0,0 +1,16 @@ +using System; +using System.ComponentModel; + +namespace osu.Game.Configuration +{ + public enum ProgressBarType + { + Off, + Pie, + [Description("Top Right")] + TopRight, + [Description("Bottom Right")] + BottomRight, + Bottom + } +} \ No newline at end of file diff --git a/osu.Game/Configuration/RankingType.cs b/osu.Game/Configuration/RankingType.cs new file mode 100644 index 0000000000..e2f0b4cd00 --- /dev/null +++ b/osu.Game/Configuration/RankingType.cs @@ -0,0 +1,16 @@ +using System; +using System.ComponentModel; + +namespace osu.Game.Configuration +{ + public enum RankingType + { + Local, + [Description("Global")] + Top, + [Description("Selected Mods")] + SelectedMod, + Friends, + Country + } +} \ No newline at end of file diff --git a/osu.Game/Configuration/ReleaseStream.cs b/osu.Game/Configuration/ReleaseStream.cs new file mode 100644 index 0000000000..a03b2376a3 --- /dev/null +++ b/osu.Game/Configuration/ReleaseStream.cs @@ -0,0 +1,11 @@ +using System; +namespace osu.Game.Configuration +{ + public enum ReleaseStream + { + Lazer, + //Stable40, + //Beta40, + //Stable + } +} \ No newline at end of file diff --git a/osu.Game/Configuration/ScoreMeterType.cs b/osu.Game/Configuration/ScoreMeterType.cs new file mode 100644 index 0000000000..786de6b6bf --- /dev/null +++ b/osu.Game/Configuration/ScoreMeterType.cs @@ -0,0 +1,10 @@ +using System; +namespace osu.Game.Configuration +{ + public enum ScoreMeterType + { + None, + Colour, + Error + } +} \ No newline at end of file diff --git a/osu.Game/Configuration/ScreenshotFormat.cs b/osu.Game/Configuration/ScreenshotFormat.cs new file mode 100644 index 0000000000..993678f0b9 --- /dev/null +++ b/osu.Game/Configuration/ScreenshotFormat.cs @@ -0,0 +1,14 @@ +using System; +using System.ComponentModel; + +namespace osu.Game.Configuration +{ + public enum ScreenshotFormat + { + Bmp = 0, // TODO: Figure out the best way to hide this from the dropdown + [Description("JPG (web-friendly)")] + Jpg = 1, + [Description("PNG (lossless)")] + Png = 2 + } +} \ No newline at end of file diff --git a/osu.Game/Database/BaseDifficulty.cs b/osu.Game/Database/BaseDifficulty.cs index 265f933045..07bf971280 100644 --- a/osu.Game/Database/BaseDifficulty.cs +++ b/osu.Game/Database/BaseDifficulty.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using SQLite.Net.Attributes; namespace osu.Game.Database diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index 4bdfa1e275..896e742989 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using System.Collections; using System.Collections.Generic; using System.IO; diff --git a/osu.Game/Database/BeatmapInfo.cs b/osu.Game/Database/BeatmapInfo.cs index 736f8b9927..be47891016 100644 --- a/osu.Game/Database/BeatmapInfo.cs +++ b/osu.Game/Database/BeatmapInfo.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using System.Linq; using osu.Game.Beatmaps.Samples; using osu.Game.Modes; diff --git a/osu.Game/Database/BeatmapSetInfo.cs b/osu.Game/Database/BeatmapSetInfo.cs index 6dc0adfa01..0a83753963 100644 --- a/osu.Game/Database/BeatmapSetInfo.cs +++ b/osu.Game/Database/BeatmapSetInfo.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using System.Collections.Generic; using SQLite.Net.Attributes; using SQLiteNetExtensions.Attributes; diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 34e65f0b2a..b68b5ebc4a 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -15,6 +15,8 @@ namespace osu.Game.Graphics.Backgrounds { public class Triangles : Container { + public override bool HandleInput => false; + public Triangles() { Alpha = 0.3f; diff --git a/osu.Game/Graphics/Containers/ParallaxContainer.cs b/osu.Game/Graphics/Containers/ParallaxContainer.cs index 5cc8a4097b..3e38ac0f09 100644 --- a/osu.Game/Graphics/Containers/ParallaxContainer.cs +++ b/osu.Game/Graphics/Containers/ParallaxContainer.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics.Containers; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; using osu.Framework.Input; using OpenTK; diff --git a/osu.Game/Graphics/UserInterface/BackButton.cs b/osu.Game/Graphics/UserInterface/BackButton.cs index 7ccc5c061b..ade6cedc58 100644 --- a/osu.Game/Graphics/UserInterface/BackButton.cs +++ b/osu.Game/Graphics/UserInterface/BackButton.cs @@ -1,6 +1,9 @@ -// Copyright (c) 2007-2016 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics; @@ -16,19 +19,17 @@ namespace osu.Game.Graphics.UserInterface { private TextAwesome icon; - private Container leftContainer; - private Container rightContainer; - private Box leftBox; private Box rightBox; - private const double transform_time = 300.0; + private const double transform_time = 600; private const int pulse_length = 250; private const float shear = 0.1f; private static readonly Vector2 size_extended = new Vector2(140, 50); private static readonly Vector2 size_retracted = new Vector2(100, 50); + private AudioSample sampleClick; public BackButton() { @@ -36,7 +37,7 @@ namespace osu.Game.Graphics.UserInterface Children = new Drawable[] { - leftContainer = new Container + new Container { RelativeSizeAxes = Axes.Both, Width = 0.4f, @@ -56,7 +57,7 @@ namespace osu.Game.Graphics.UserInterface }, } }, - rightContainer = new Container + new Container { Origin = Anchor.TopRight, Anchor = Anchor.TopRight, @@ -84,10 +85,7 @@ namespace osu.Game.Graphics.UserInterface }; } - public override bool Contains(Vector2 screenSpacePos) - { - return leftBox.Contains(screenSpacePos) || rightBox.Contains(screenSpacePos); - } + public override bool Contains(Vector2 screenSpacePos) => leftBox.Contains(screenSpacePos) || rightBox.Contains(screenSpacePos); protected override bool OnHover(InputState state) { @@ -141,6 +139,12 @@ namespace osu.Game.Graphics.UserInterface }); } + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + sampleClick = audio.Sample.Get(@"Menu/menuback"); + } + protected override bool OnClick(InputState state) { var flash = new Box @@ -154,6 +158,8 @@ namespace osu.Game.Graphics.UserInterface flash.FadeOutFromOne(200); flash.Expire(); + sampleClick.Play(); + return base.OnClick(state); } } diff --git a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs index 2edc5397f4..49887dd8db 100644 --- a/osu.Game/Graphics/UserInterface/LoadingAnimation.cs +++ b/osu.Game/Graphics/UserInterface/LoadingAnimation.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using osu.Framework.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index fea9f907bc..476895e0b2 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using OpenTK.Graphics; using osu.Framework.Graphics.UserInterface; diff --git a/osu.Game/Graphics/UserInterface/PercentageCounter.cs b/osu.Game/Graphics/UserInterface/PercentageCounter.cs index b045089dcd..63c15553d5 100644 --- a/osu.Game/Graphics/UserInterface/PercentageCounter.cs +++ b/osu.Game/Graphics/UserInterface/PercentageCounter.cs @@ -20,7 +20,7 @@ namespace osu.Game.Graphics.UserInterface { protected override Type TransformType => typeof(TransformAccuracy); - protected override double RollingDuration => 20; + protected override double RollingDuration => 150; protected override bool IsRollingProportional => true; private float epsilon => 1e-10f; diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs index fd60a8ca8e..6a21da9bce 100644 --- a/osu.Game/Graphics/UserInterface/RollingCounter.cs +++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs @@ -42,7 +42,7 @@ namespace osu.Game.Graphics.UserInterface /// /// Easing for the counter rollover animation. /// - protected virtual EasingTypes RollingEasing => EasingTypes.None; + protected virtual EasingTypes RollingEasing => EasingTypes.Out; private T displayedCount; diff --git a/osu.Game/Graphics/UserInterface/StarCounter.cs b/osu.Game/Graphics/UserInterface/StarCounter.cs index 097362bc77..fa8ca7e5a9 100644 --- a/osu.Game/Graphics/UserInterface/StarCounter.cs +++ b/osu.Game/Graphics/UserInterface/StarCounter.cs @@ -35,7 +35,7 @@ namespace osu.Game.Graphics.UserInterface protected set; } - private double animationDelay => 150; + private double animationDelay => 80; private double scalingDuration => 500; private EasingTypes scalingEasing => EasingTypes.OutElasticHalf; diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index 13accc4914..cfc6b3a1c7 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using osu.Framework; using osu.Framework.Configuration; using osu.Framework.Graphics; diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs index 4416a1da80..37259289ce 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs @@ -1,4 +1,7 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs index ed57f06e51..7ce71acf3e 100644 --- a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs @@ -5,7 +5,11 @@ using System; using System.ComponentModel; using System.Diagnostics; using osu.Framework; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps.Samples; using OpenTK; using Container = osu.Framework.Graphics.Containers.Container; @@ -26,7 +30,6 @@ namespace osu.Game.Modes.Objects.Drawables public DrawableHitObject(HitObject hitObject) { HitObject = hitObject; - Depth = (float)hitObject.StartTime; } private ArmedState state; @@ -40,14 +43,42 @@ namespace osu.Game.Modes.Objects.Drawables state = value; UpdateState(state); + + Expire(); + + if (State == ArmedState.Hit) + PlaySample(); } } + AudioSample sample; + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + string hitType = (HitObject.Sample.Type == SampleType.None ? SampleType.Normal : HitObject.Sample.Type).ToString().ToLower(); + string sampleSet = HitObject.Sample.Set.ToString().ToLower(); + + sample = audio.Sample.Get($@"Gameplay/{sampleSet}-hit{hitType}"); + } + + protected void PlaySample() + { + sample?.Play(); + } + protected override void LoadComplete() { base.LoadComplete(); - Judgement = CreateJudgementInfo(); + //we may be setting a custom judgement in test cases or what not. + if (Judgement == null) + Judgement = CreateJudgementInfo(); + + //force application of the state that was set before we loaded. + UpdateState(State); + + Expire(true); } /// diff --git a/osu.Game/Modes/PlayMode.cs b/osu.Game/Modes/PlayMode.cs index d1b0f23ee4..0d78436d9f 100644 --- a/osu.Game/Modes/PlayMode.cs +++ b/osu.Game/Modes/PlayMode.cs @@ -1,7 +1,6 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - using System.ComponentModel; namespace osu.Game.Modes diff --git a/osu.Game/Modes/UI/Playfield.cs b/osu.Game/Modes/UI/Playfield.cs index ff8a03db2a..fc042d72a0 100644 --- a/osu.Game/Modes/UI/Playfield.cs +++ b/osu.Game/Modes/UI/Playfield.cs @@ -11,24 +11,37 @@ namespace osu.Game.Modes.UI public abstract class Playfield : Container { public HitObjectContainer HitObjects; + private Container content; public virtual void Add(DrawableHitObject h) => HitObjects.Add(h); public override bool Contains(Vector2 screenSpacePos) => true; + protected override Container Content => content; + public Playfield() { - AddInternal(HitObjects = new HitObjectContainer + AddInternal(content = new ScaledContainer() + { + RelativeSizeAxes = Axes.Both, + }); + + Add(HitObjects = new HitObjectContainer { RelativeSizeAxes = Axes.Both, }); } - public class HitObjectContainer : Container + public class ScaledContainer : Container { protected override Vector2 DrawScale => new Vector2(DrawSize.X / 512); public override bool Contains(Vector2 screenSpacePos) => true; } + + public class HitObjectContainer : Container + { + public override bool Contains(Vector2 screenSpacePos) => true; + } } } diff --git a/osu.Game/Online/API/Requests/GetUserRequest.cs b/osu.Game/Online/API/Requests/GetUserRequest.cs index 1f6da1e1de..22b5f32ffd 100644 --- a/osu.Game/Online/API/Requests/GetUserRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRequest.cs @@ -1,7 +1,6 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - namespace osu.Game.Online.API.Requests { public class GetUserRequest : APIRequest diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index c6e07c3a79..a4ca4c5817 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -20,6 +20,7 @@ using osu.Game.Graphics.UserInterface.Volume; using osu.Game.Database; using osu.Framework.Allocation; using osu.Framework.Graphics.Transformations; +using osu.Framework.Timing; using osu.Game.Modes; using osu.Game.Overlays.Toolbar; using osu.Game.Screens; @@ -154,11 +155,19 @@ namespace osu.Game private bool globalHotkeyPressed(InputState state, KeyDownEventArgs args) { + if (args.Repeat) return false; + switch (args.Key) { case Key.F8: chat.ToggleVisibility(); return true; + case Key.PageUp: + case Key.PageDown: + var rate = ((Clock as ThrottledFrameClock).Source as StopwatchClock).Rate * (args.Key == Key.PageUp ? 1.1f : 0.9f); + ((Clock as ThrottledFrameClock).Source as StopwatchClock).Rate = rate; + Logger.Log($@"Adjusting game clock to {rate}", LoggingTarget.Debug); + return true; } if (state.Keyboard.ControlPressed) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 4db582d799..7c1f620c93 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -1,5 +1,5 @@ -// Copyright (c) 2007-2016 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework; using osu.Framework.Allocation; diff --git a/osu.Game/Overlays/Options/Audio/AudioDevicesOptions.cs b/osu.Game/Overlays/Options/Audio/AudioDevicesOptions.cs index fb0a227d08..5ad57bef53 100644 --- a/osu.Game/Overlays/Options/Audio/AudioDevicesOptions.cs +++ b/osu.Game/Overlays/Options/Audio/AudioDevicesOptions.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics.Sprites; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.Options.Audio { diff --git a/osu.Game/Overlays/Options/Audio/AudioSection.cs b/osu.Game/Overlays/Options/Audio/AudioSection.cs index 59fbda58c9..6b55944a5c 100644 --- a/osu.Game/Overlays/Options/Audio/AudioSection.cs +++ b/osu.Game/Overlays/Options/Audio/AudioSection.cs @@ -1,4 +1,7 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Graphics; using osu.Game.Graphics; diff --git a/osu.Game/Overlays/Options/Audio/OffsetAdjustmentOptions.cs b/osu.Game/Overlays/Options/Audio/OffsetAdjustmentOptions.cs index 9bb8fb30e8..df1d6aa9f9 100644 --- a/osu.Game/Overlays/Options/Audio/OffsetAdjustmentOptions.cs +++ b/osu.Game/Overlays/Options/Audio/OffsetAdjustmentOptions.cs @@ -1,5 +1,11 @@ -using osu.Framework.Graphics; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Options.Audio @@ -7,18 +13,23 @@ namespace osu.Game.Overlays.Options.Audio public class OffsetAdjustmentOptions : OptionsSubsection { protected override string Header => "Offset Adjustment"; - - public OffsetAdjustmentOptions() - { - Children = new Drawable[] - { - new SpriteText { Text = "Universal Offset: TODO slider" }, - new OsuButton - { - RelativeSizeAxes = Axes.X, - Text = "Offset wizard" - } - }; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + Children = new Drawable[] + { + new SliderOption + { + LabelText = "Universal Offset", + Bindable = (BindableInt)config.GetBindable(OsuConfig.Offset) + }, + new OsuButton + { + RelativeSizeAxes = Axes.X, + Text = "Offset wizard" + } + }; } } -} \ No newline at end of file +} diff --git a/osu.Game/Overlays/Options/Audio/VolumeOptions.cs b/osu.Game/Overlays/Options/Audio/VolumeOptions.cs index c8dac502f3..216e2e866d 100644 --- a/osu.Game/Overlays/Options/Audio/VolumeOptions.cs +++ b/osu.Game/Overlays/Options/Audio/VolumeOptions.cs @@ -1,5 +1,9 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; @@ -11,21 +15,15 @@ namespace osu.Game.Overlays.Options.Audio { protected override string Header => "Volume"; - private CheckBoxOption ignoreHitsounds; - - public VolumeOptions() - { - } - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) + private void load(OsuConfigManager config, AudioManager audio) { Children = new Drawable[] { - new SpriteText { Text = "Master: TODO slider" }, - new SpriteText { Text = "Music: TODO slider" }, - new SpriteText { Text = "Effect: TODO slider" }, - ignoreHitsounds = new CheckBoxOption + new SliderOption { LabelText = "Master", Bindable = audio.Volume }, + new SliderOption { LabelText = "Effect", Bindable = audio.VolumeSample }, + new SliderOption { LabelText = "Music", Bindable = audio.VolumeTrack }, + new CheckBoxOption { LabelText = "Ignore beatmap hitsounds", Bindable = config.GetBindable(OsuConfig.IgnoreBeatmapSamples) diff --git a/osu.Game/Overlays/Options/CheckBoxOption.cs b/osu.Game/Overlays/Options/CheckBoxOption.cs index 18f0e59e03..2ea176378c 100644 --- a/osu.Game/Overlays/Options/CheckBoxOption.cs +++ b/osu.Game/Overlays/Options/CheckBoxOption.cs @@ -1,5 +1,11 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using osu.Framework; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -60,6 +66,8 @@ namespace osu.Game.Overlays.Options private Light light; private SpriteText labelSpriteText; + private AudioSample sampleChecked; + private AudioSample sampleUnchecked; public CheckBoxOption() { @@ -102,11 +110,19 @@ namespace osu.Game.Overlays.Options base.OnHoverLost(state); } + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + sampleChecked = audio.Sample.Get(@"Checkbox/check-on"); + sampleUnchecked = audio.Sample.Get(@"Checkbox/check-off"); + } + protected override void OnChecked() { if (bindable != null) bindable.Value = true; + sampleChecked?.Play(); light.State = CheckBoxState.Checked; } @@ -115,6 +131,7 @@ namespace osu.Game.Overlays.Options if (bindable != null) bindable.Value = false; + sampleUnchecked?.Play(); light.State = CheckBoxState.Unchecked; } diff --git a/osu.Game/Overlays/Options/DropdownOption.cs b/osu.Game/Overlays/Options/DropdownOption.cs new file mode 100644 index 0000000000..3cdc6da2ab --- /dev/null +++ b/osu.Game/Overlays/Options/DropdownOption.cs @@ -0,0 +1,166 @@ +using System; +using System.ComponentModel; +using System.Linq; +using System.Reflection; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Configuration; + +namespace osu.Game.Overlays.Options +{ + public class DropdownOption : FlowContainer + { + private DropDownMenu dropdown; + private SpriteText text; + + public string LabelText + { + get { return text.Text; } + set + { + text.Text = value; + text.Alpha = string.IsNullOrEmpty(value) ? 0 : 1; + } + } + + public Bindable Bindable + { + get { return bindable; } + set + { + if (bindable != null) + bindable.ValueChanged -= Bindable_ValueChanged; + bindable = value; + bindable.ValueChanged += Bindable_ValueChanged; + Bindable_ValueChanged(null, null); + } + } + + private Bindable bindable; + + void Bindable_ValueChanged(object sender, EventArgs e) + { + dropdown.SelectedValue = bindable.Value; + } + + void Dropdown_ValueChanged(object sender, EventArgs e) + { + bindable.Value = dropdown.SelectedValue; + } + + protected override void Dispose(bool isDisposing) + { + bindable.ValueChanged -= Bindable_ValueChanged; + dropdown.ValueChanged -= Dropdown_ValueChanged; + base.Dispose(isDisposing); + } + + public DropdownOption() + { + if (!typeof(T).IsEnum) + throw new InvalidOperationException("OptionsDropdown only supports enums as the generic type argument"); + Direction = FlowDirection.VerticalOnly; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + var items = typeof(T).GetFields().Where(f => !f.IsSpecialName).Zip( + (T[])Enum.GetValues(typeof(T)), (a, b) => new Tuple( + a.GetCustomAttribute()?.Description ?? a.Name, b)); + Children = new Drawable[] + { + text = new SpriteText { Alpha = 0 }, + dropdown = new StyledDropDownMenu + { + Margin = new MarginPadding { Top = 5 }, + RelativeSizeAxes = Axes.X, + Items = items.Select(item => new StyledDropDownMenuItem(item.Item1, item.Item2)) + } + }; + dropdown.ValueChanged += Dropdown_ValueChanged; + } + + private class StyledDropDownMenu : DropDownMenu + { + protected override float DropDownListSpacing => 4; + + protected override DropDownComboBox CreateComboBox() + { + return new StyledDropDownComboBox(); + } + + public StyledDropDownMenu() + { + ComboBox.CornerRadius = 4; + DropDown.CornerRadius = 4; + } + + protected override void AnimateOpen() + { + foreach (StyledDropDownMenuItem child in DropDownList.Children) + { + child.FadeIn(200); + child.ResizeTo(new Vector2(1, 24), 200); + } + DropDown.Show(); + } + + protected override void AnimateClose() + { + foreach (StyledDropDownMenuItem child in DropDownList.Children) + { + child.ResizeTo(new Vector2(1, 0), 200); + child.FadeOut(200); + } + } + } + + private class StyledDropDownComboBox : DropDownComboBox + { + protected override Color4 BackgroundColour => new Color4(255, 255, 255, 100); + protected override Color4 BackgroundColourHover => Color4.HotPink; + + public StyledDropDownComboBox() + { + Foreground.Padding = new MarginPadding(4); + } + } + + private class StyledDropDownMenuItem : DropDownMenuItem + { + public StyledDropDownMenuItem(string text, U value) : base(text, value) + { + AutoSizeAxes = Axes.None; + Height = 0; + Foreground.Padding = new MarginPadding(2); + } + + protected override void OnSelectChange() + { + if (!IsLoaded) + return; + + FormatBackground(); + FormatCaret(); + FormatLabel(); + } + + protected override void FormatCaret() + { + (Caret as SpriteText).Text = IsSelected ? @"+" : @"-"; + } + + protected override void FormatLabel() + { + if (IsSelected) + (Label as SpriteText).Text = @"*" + Value + @"*"; + else + (Label as SpriteText).Text = Value.ToString(); + } + } + } +} diff --git a/osu.Game/Overlays/Options/EditorSection.cs b/osu.Game/Overlays/Options/EditorSection.cs index bdd7c87431..9d7d9bde95 100644 --- a/osu.Game/Overlays/Options/EditorSection.cs +++ b/osu.Game/Overlays/Options/EditorSection.cs @@ -1,4 +1,7 @@ -using OpenTK; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game/Overlays/Options/Gameplay/GameplaySection.cs b/osu.Game/Overlays/Options/Gameplay/GameplaySection.cs index af4728e0e2..3216d55837 100644 --- a/osu.Game/Overlays/Options/Gameplay/GameplaySection.cs +++ b/osu.Game/Overlays/Options/Gameplay/GameplaySection.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; using osu.Game.Graphics; namespace osu.Game.Overlays.Options.Gameplay diff --git a/osu.Game/Overlays/Options/Gameplay/GeneralGameplayOptions.cs b/osu.Game/Overlays/Options/Gameplay/GeneralGameplayOptions.cs index fe6f118643..15ee80102d 100644 --- a/osu.Game/Overlays/Options/Gameplay/GeneralGameplayOptions.cs +++ b/osu.Game/Overlays/Options/Gameplay/GeneralGameplayOptions.cs @@ -1,46 +1,66 @@ -using osu.Framework; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.UserInterface; -using osu.Game.Configuration; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -namespace osu.Game.Overlays.Options.Gameplay -{ - public class GeneralGameplayOptions : OptionsSubsection - { - protected override string Header => "General"; - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - Children = new Drawable[] - { - new SpriteText { Text = "Background dim: TODO slider" }, - new SpriteText { Text = "Progress display: TODO dropdown" }, - new SpriteText { Text = "Score meter type: TODO dropdown" }, - new SpriteText { Text = "Score meter size: TODO slider" }, - new CheckBoxOption - { - LabelText = "Always show key overlay", - Bindable = config.GetBindable(OsuConfig.KeyOverlay) - }, - new CheckBoxOption - { - LabelText = "Show approach circle on first \"Hidden\" object", - Bindable = config.GetBindable(OsuConfig.HiddenShowFirstApproach) - }, - new CheckBoxOption - { - LabelText = "Scale osu!mania scroll speed with BPM", - Bindable = config.GetBindable(OsuConfig.ManiaSpeedBPMScale) - }, - new CheckBoxOption - { - LabelText = "Remember osu!mania scroll speed per beatmap", - Bindable = config.GetBindable(OsuConfig.UsePerBeatmapManiaSpeed) - }, - }; - } - } -} \ No newline at end of file +using osu.Framework; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Configuration; + +namespace osu.Game.Overlays.Options.Gameplay +{ + public class GeneralGameplayOptions : OptionsSubsection + { + protected override string Header => "General"; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + Children = new Drawable[] + { + new SliderOption + { + LabelText = "Background dim", + Bindable = (BindableInt)config.GetBindable(OsuConfig.DimLevel) + }, + new DropdownOption + { + LabelText = "Progress display", + Bindable = config.GetBindable(OsuConfig.ProgressBarType) + }, + new DropdownOption + { + LabelText = "Score meter type", + Bindable = config.GetBindable(OsuConfig.ScoreMeter) + }, + new SliderOption + { + LabelText = "Score meter size", + Bindable = (BindableDouble)config.GetBindable(OsuConfig.ScoreMeterScale) + }, + new CheckBoxOption + { + LabelText = "Always show key overlay", + Bindable = config.GetBindable(OsuConfig.KeyOverlay) + }, + new CheckBoxOption + { + LabelText = "Show approach circle on first \"Hidden\" object", + Bindable = config.GetBindable(OsuConfig.HiddenShowFirstApproach) + }, + new CheckBoxOption + { + LabelText = "Scale osu!mania scroll speed with BPM", + Bindable = config.GetBindable(OsuConfig.ManiaSpeedBPMScale) + }, + new CheckBoxOption + { + LabelText = "Remember osu!mania scroll speed per beatmap", + Bindable = config.GetBindable(OsuConfig.UsePerBeatmapManiaSpeed) + }, + }; + } + } +} diff --git a/osu.Game/Overlays/Options/Gameplay/SongSelectGameplayOptions.cs b/osu.Game/Overlays/Options/Gameplay/SongSelectGameplayOptions.cs index b268fdcc5f..e0f25cfea7 100644 --- a/osu.Game/Overlays/Options/Gameplay/SongSelectGameplayOptions.cs +++ b/osu.Game/Overlays/Options/Gameplay/SongSelectGameplayOptions.cs @@ -1,20 +1,37 @@ -using osu.Framework.Graphics; +//Copyright (c) 2007-2016 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.Configuration; +using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Game.Configuration; +using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Options.Gameplay { public class SongSelectGameplayOptions : OptionsSubsection { protected override string Header => "Song Select"; - - public SongSelectGameplayOptions() - { - Children = new Drawable[] - { - new SpriteText { Text = "Display beatmaps from: TODO slider" }, - new SpriteText { Text = "up to: TODO slider" }, - }; - } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + Children = new Drawable[] + { + new SliderOption + { + LabelText = "Display beatmaps from", + Bindable = (BindableDouble)config.GetBindable(OsuConfig.DisplayStarsMinimum) + }, + new SliderOption + { + LabelText = "up to", + Bindable = (BindableDouble)config.GetBindable(OsuConfig.DisplayStarsMaximum) + }, + }; + } } } diff --git a/osu.Game/Overlays/Options/General/GeneralSection.cs b/osu.Game/Overlays/Options/General/GeneralSection.cs index a9cea62270..d91734db1f 100644 --- a/osu.Game/Overlays/Options/General/GeneralSection.cs +++ b/osu.Game/Overlays/Options/General/GeneralSection.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; using osu.Game.Graphics; namespace osu.Game.Overlays.Options.General diff --git a/osu.Game/Overlays/Options/General/LanguageOptions.cs b/osu.Game/Overlays/Options/General/LanguageOptions.cs index e9009836ab..351d541bd9 100644 --- a/osu.Game/Overlays/Options/General/LanguageOptions.cs +++ b/osu.Game/Overlays/Options/General/LanguageOptions.cs @@ -1,4 +1,7 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Allocation; diff --git a/osu.Game/Overlays/Options/General/LoginOptions.cs b/osu.Game/Overlays/Options/General/LoginOptions.cs index 94eb6b1c01..03789c59c9 100644 --- a/osu.Game/Overlays/Options/General/LoginOptions.cs +++ b/osu.Game/Overlays/Options/General/LoginOptions.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using OpenTK; using osu.Framework; using osu.Framework.Allocation; diff --git a/osu.Game/Overlays/Options/General/UpdateOptions.cs b/osu.Game/Overlays/Options/General/UpdateOptions.cs index 8e68b26c1c..77cfd11273 100644 --- a/osu.Game/Overlays/Options/General/UpdateOptions.cs +++ b/osu.Game/Overlays/Options/General/UpdateOptions.cs @@ -1,8 +1,12 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Platform; +using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Options.General @@ -12,11 +16,15 @@ namespace osu.Game.Overlays.Options.General protected override string Header => "Updates"; [BackgroundDependencyLoader] - private void load(BasicStorage storage) + private void load(BasicStorage storage, OsuConfigManager config) { Children = new Drawable[] { - new SpriteText { Text = "TODO: Dropdown" }, + new DropdownOption + { + LabelText = "Release stream", + Bindable = config.GetBindable(OsuConfig.ReleaseStream), + }, new SpriteText { Text = "Your osu! is up to date" }, // TODO: map this to reality new OsuButton { diff --git a/osu.Game/Overlays/Options/Graphics/DetailOptions.cs b/osu.Game/Overlays/Options/Graphics/DetailOptions.cs index 880677ff6a..51720410a9 100644 --- a/osu.Game/Overlays/Options/Graphics/DetailOptions.cs +++ b/osu.Game/Overlays/Options/Graphics/DetailOptions.cs @@ -1,5 +1,5 @@ -// Copyright (c) 2007-2016 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -57,7 +57,11 @@ namespace osu.Game.Overlays.Options.Graphics LabelText = "Softening filter", Bindable = config.GetBindable(OsuConfig.BloomSoftening) }, - new SpriteText { Text = "Screenshot format TODO: dropdown" } + new DropdownOption + { + LabelText = "Screenshot", + Bindable = config.GetBindable(OsuConfig.ScreenshotFormat) + } }; } } diff --git a/osu.Game/Overlays/Options/Graphics/GraphicsSection.cs b/osu.Game/Overlays/Options/Graphics/GraphicsSection.cs index ec0091edde..9c8c8043bf 100644 --- a/osu.Game/Overlays/Options/Graphics/GraphicsSection.cs +++ b/osu.Game/Overlays/Options/Graphics/GraphicsSection.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; using osu.Game.Graphics; namespace osu.Game.Overlays.Options.Graphics diff --git a/osu.Game/Overlays/Options/Graphics/LayoutOptions.cs b/osu.Game/Overlays/Options/Graphics/LayoutOptions.cs index c71c5f8cae..e050f7c70c 100644 --- a/osu.Game/Overlays/Options/Graphics/LayoutOptions.cs +++ b/osu.Game/Overlays/Options/Graphics/LayoutOptions.cs @@ -1,5 +1,9 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; @@ -27,10 +31,16 @@ namespace osu.Game.Overlays.Options.Graphics LabelText = "Letterboxing", Bindable = config.GetBindable(OsuConfig.Letterboxing), }, - new SpriteText { Text = "Horizontal position" }, - new SpriteText { Text = "TODO: slider" }, - new SpriteText { Text = "Vertical position" }, - new SpriteText { Text = "TODO: slider" }, + new SliderOption + { + LabelText = "Horizontal position", + Bindable = (BindableInt)config.GetBindable(OsuConfig.LetterboxPositionX) + }, + new SliderOption + { + LabelText = "Vertical position", + Bindable = (BindableInt)config.GetBindable(OsuConfig.LetterboxPositionY) + }, }; } } diff --git a/osu.Game/Overlays/Options/Graphics/MainMenuOptions.cs b/osu.Game/Overlays/Options/Graphics/MainMenuOptions.cs index 8b1903e508..58f1bfb3b7 100644 --- a/osu.Game/Overlays/Options/Graphics/MainMenuOptions.cs +++ b/osu.Game/Overlays/Options/Graphics/MainMenuOptions.cs @@ -1,4 +1,7 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics.UserInterface; using osu.Game.Configuration; diff --git a/osu.Game/Overlays/Options/Graphics/RendererOptions.cs b/osu.Game/Overlays/Options/Graphics/RendererOptions.cs index bb46718bb6..6dce562c4b 100644 --- a/osu.Game/Overlays/Options/Graphics/RendererOptions.cs +++ b/osu.Game/Overlays/Options/Graphics/RendererOptions.cs @@ -1,4 +1,7 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; @@ -17,7 +20,12 @@ namespace osu.Game.Overlays.Options.Graphics // NOTE: Compatability mode omitted Children = new Drawable[] { - new SpriteText { Text = "Frame limiter: TODO dropdown" }, + // TODO: this needs to be a custom dropdown at some point + new DropdownOption + { + LabelText = "Frame limiter", + Bindable = config.GetBindable(OsuConfig.FrameSync) + }, new CheckBoxOption { LabelText = "Show FPS counter", diff --git a/osu.Game/Overlays/Options/Graphics/SongSelectGraphicsOptions.cs b/osu.Game/Overlays/Options/Graphics/SongSelectGraphicsOptions.cs index cda97f6eb3..0dee3544a1 100644 --- a/osu.Game/Overlays/Options/Graphics/SongSelectGraphicsOptions.cs +++ b/osu.Game/Overlays/Options/Graphics/SongSelectGraphicsOptions.cs @@ -1,4 +1,7 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics.UserInterface; using osu.Game.Configuration; diff --git a/osu.Game/Overlays/Options/Input/InputSection.cs b/osu.Game/Overlays/Options/Input/InputSection.cs index 1bbf1ece38..c436a7439f 100644 --- a/osu.Game/Overlays/Options/Input/InputSection.cs +++ b/osu.Game/Overlays/Options/Input/InputSection.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; using osu.Game.Graphics; namespace osu.Game.Overlays.Options.Input diff --git a/osu.Game/Overlays/Options/Input/KeyboardOptions.cs b/osu.Game/Overlays/Options/Input/KeyboardOptions.cs index cea5cf3b7a..521dfb88e6 100644 --- a/osu.Game/Overlays/Options/Input/KeyboardOptions.cs +++ b/osu.Game/Overlays/Options/Input/KeyboardOptions.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Options.Input diff --git a/osu.Game/Overlays/Options/Input/MouseOptions.cs b/osu.Game/Overlays/Options/Input/MouseOptions.cs index c2887fe4c0..9d0823ce07 100644 --- a/osu.Game/Overlays/Options/Input/MouseOptions.cs +++ b/osu.Game/Overlays/Options/Input/MouseOptions.cs @@ -1,5 +1,9 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; @@ -11,40 +15,43 @@ namespace osu.Game.Overlays.Options.Input { protected override string Header => "Mouse"; - private CheckBoxOption rawInput, mapRawInput, disableWheel, disableButtons, enableRipples; - - public MouseOptions() - { - } - [BackgroundDependencyLoader] private void load(OsuConfigManager config) { Children = new Drawable[] { new SpriteText { Text = "Sensitivity: TODO slider" }, - rawInput = new CheckBoxOption + new SliderOption + { + LabelText = "Sensitivity", + Bindable = (BindableDouble)config.GetBindable(OsuConfig.MouseSpeed), + }, + new CheckBoxOption { LabelText = "Raw input", Bindable = config.GetBindable(OsuConfig.RawInput) }, - mapRawInput = new CheckBoxOption + new CheckBoxOption { LabelText = "Map absolute raw input to the osu! window", Bindable = config.GetBindable(OsuConfig.AbsoluteToOsuWindow) }, - new SpriteText { Text = "Confine mouse cursor: TODO dropdown" }, - disableWheel = new CheckBoxOption + new DropdownOption + { + LabelText = "Confine mouse cursor", + Bindable = config.GetBindable(OsuConfig.ConfineMouse), + }, + new CheckBoxOption { LabelText = "Disable mouse wheel in play mode", Bindable = config.GetBindable(OsuConfig.MouseDisableWheel) }, - disableButtons = new CheckBoxOption + new CheckBoxOption { LabelText = "Disable mouse buttons in play mode", Bindable = config.GetBindable(OsuConfig.MouseDisableButtons) }, - enableRipples = new CheckBoxOption + new CheckBoxOption { LabelText = "Cursor ripples", Bindable = config.GetBindable(OsuConfig.CursorRipple) diff --git a/osu.Game/Overlays/Options/Input/OtherInputOptions.cs b/osu.Game/Overlays/Options/Input/OtherInputOptions.cs index d9cb8bb38f..02eb17c9b4 100644 --- a/osu.Game/Overlays/Options/Input/OtherInputOptions.cs +++ b/osu.Game/Overlays/Options/Input/OtherInputOptions.cs @@ -1,4 +1,7 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; diff --git a/osu.Game/Overlays/Options/MaintenanceSection.cs b/osu.Game/Overlays/Options/MaintenanceSection.cs index a76d338592..dcd90b8e50 100644 --- a/osu.Game/Overlays/Options/MaintenanceSection.cs +++ b/osu.Game/Overlays/Options/MaintenanceSection.cs @@ -1,4 +1,7 @@ -using OpenTK; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; diff --git a/osu.Game/Overlays/Options/Online/InGameChatOptions.cs b/osu.Game/Overlays/Options/Online/InGameChatOptions.cs index 91df397445..098fe39546 100644 --- a/osu.Game/Overlays/Options/Online/InGameChatOptions.cs +++ b/osu.Game/Overlays/Options/Online/InGameChatOptions.cs @@ -1,4 +1,7 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; diff --git a/osu.Game/Overlays/Options/Online/NotificationsOptions.cs b/osu.Game/Overlays/Options/Online/NotificationsOptions.cs index dc08277b8e..1648d23528 100644 --- a/osu.Game/Overlays/Options/Online/NotificationsOptions.cs +++ b/osu.Game/Overlays/Options/Online/NotificationsOptions.cs @@ -1,4 +1,7 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; diff --git a/osu.Game/Overlays/Options/Online/OnlineIntegrationOptions.cs b/osu.Game/Overlays/Options/Online/OnlineIntegrationOptions.cs index ea009e81ad..4799c5d5ca 100644 --- a/osu.Game/Overlays/Options/Online/OnlineIntegrationOptions.cs +++ b/osu.Game/Overlays/Options/Online/OnlineIntegrationOptions.cs @@ -1,4 +1,7 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; diff --git a/osu.Game/Overlays/Options/Online/OnlineSection.cs b/osu.Game/Overlays/Options/Online/OnlineSection.cs index a29f18d768..d07c6e89df 100644 --- a/osu.Game/Overlays/Options/Online/OnlineSection.cs +++ b/osu.Game/Overlays/Options/Online/OnlineSection.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; using osu.Game.Graphics; namespace osu.Game.Overlays.Options.Online diff --git a/osu.Game/Overlays/Options/Online/PrivacyOptions.cs b/osu.Game/Overlays/Options/Online/PrivacyOptions.cs index 38cfab321d..ac654cb3d4 100644 --- a/osu.Game/Overlays/Options/Online/PrivacyOptions.cs +++ b/osu.Game/Overlays/Options/Online/PrivacyOptions.cs @@ -1,4 +1,7 @@ -using osu.Framework; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; diff --git a/osu.Game/Overlays/Options/OptionsSection.cs b/osu.Game/Overlays/Options/OptionsSection.cs index 739504da80..256d5c8218 100644 --- a/osu.Game/Overlays/Options/OptionsSection.cs +++ b/osu.Game/Overlays/Options/OptionsSection.cs @@ -1,4 +1,7 @@ -using OpenTK; +//Copyright (c) 2007-2016 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; diff --git a/osu.Game/Overlays/Options/OptionsSidebar.cs b/osu.Game/Overlays/Options/OptionsSidebar.cs index d4b64a5d60..201d7878ab 100644 --- a/osu.Game/Overlays/Options/OptionsSidebar.cs +++ b/osu.Game/Overlays/Options/OptionsSidebar.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics; diff --git a/osu.Game/Overlays/Options/OptionsSubsection.cs b/osu.Game/Overlays/Options/OptionsSubsection.cs index ad98549e9e..b7b1ff4570 100644 --- a/osu.Game/Overlays/Options/OptionsSubsection.cs +++ b/osu.Game/Overlays/Options/OptionsSubsection.cs @@ -1,4 +1,7 @@ -using OpenTK; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; diff --git a/osu.Game/Overlays/Options/SidebarButton.cs b/osu.Game/Overlays/Options/SidebarButton.cs index 82a55e3fe5..a1edc997a1 100644 --- a/osu.Game/Overlays/Options/SidebarButton.cs +++ b/osu.Game/Overlays/Options/SidebarButton.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics; diff --git a/osu.Game/Overlays/Options/SkinSection.cs b/osu.Game/Overlays/Options/SkinSection.cs index 814e0d56c2..de88570a0e 100644 --- a/osu.Game/Overlays/Options/SkinSection.cs +++ b/osu.Game/Overlays/Options/SkinSection.cs @@ -1,6 +1,10 @@ -using OpenTK; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; using osu.Framework; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; @@ -59,6 +63,11 @@ namespace osu.Game.Overlays.Options Bindable = config.GetBindable(OsuConfig.UseSkinCursor) }, new SpriteText { Text = "Cursor size: TODO slider" }, + new SliderOption + { + LabelText = "Cursor size", + Bindable = (BindableDouble)config.GetBindable(OsuConfig.CursorSize) + }, new CheckBoxOption { LabelText = "Automatic cursor size", diff --git a/osu.Game/Overlays/Options/SliderOption.cs b/osu.Game/Overlays/Options/SliderOption.cs new file mode 100644 index 0000000000..44b7935945 --- /dev/null +++ b/osu.Game/Overlays/Options/SliderOption.cs @@ -0,0 +1,170 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using OpenTK; +using OpenTK.Input; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transformations; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input; + +namespace osu.Game.Overlays.Options +{ + public class SliderOption : FlowContainer where T : struct + { + private SliderBar slider; + private SpriteText text; + + public string LabelText + { + get { return text.Text; } + set + { + text.Text = value; + text.Alpha = string.IsNullOrEmpty(value) ? 0 : 1; + } + } + + public BindableNumber Bindable + { + get { return slider.Bindable; } + set { slider.Bindable = value; } + } + + public SliderOption() + { + Direction = FlowDirection.VerticalOnly; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Children = new Drawable[] + { + text = new SpriteText { Alpha = 0 }, + slider = new OsuSliderBar + { + Margin = new MarginPadding { Top = 5 }, + RelativeSizeAxes = Axes.X, + } + }; + } + + private class OsuSliderBar : SliderBar where U : struct + { + private AudioSample sample; + private double lastSampleTime; + + private Container nub; + private Box leftBox, rightBox; + + private float innerWidth + { + get + { + return DrawWidth - Height; + } + } + + public OsuSliderBar() + { + Height = 22; + Padding = new MarginPadding { Left = Height / 2, Right = Height / 2 }; + Children = new Drawable[] + { + leftBox = new Box + { + Height = 2, + RelativeSizeAxes = Axes.None, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Colour = new Color4(255, 102, 170, 255), + }, + rightBox = new Box + { + Height = 2, + RelativeSizeAxes = Axes.None, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Colour = new Color4(255, 102, 170, 255), + Alpha = 0.5f, + }, + nub = new Container + { + Width = Height, + Height = Height, + CornerRadius = Height / 2, + Origin = Anchor.TopCentre, + AutoSizeAxes = Axes.None, + RelativeSizeAxes = Axes.None, + Masking = true, + BorderColour = new Color4(255, 102, 170, 255), + BorderThickness = 3, + Children = new[] + { + new Box + { + Colour = new Color4(255, 102, 170, 0), + RelativeSizeAxes = Axes.Both + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + sample = audio.Sample.Get(@"Sliderbar/sliderbar"); + } + + private void playSample() + { + if (Clock == null || Clock.CurrentTime - lastSampleTime <= 50) + return; + lastSampleTime = Clock.CurrentTime; + sample.Frequency.Value = 1 + NormalizedValue * 0.2f; + sample.Play(); + } + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (args.Key == Key.Left || args.Key == Key.Right) + playSample(); + return base.OnKeyDown(state, args); + } + + protected override bool OnClick(InputState state) + { + playSample(); + return base.OnClick(state); + } + + protected override bool OnDrag(InputState state) + { + playSample(); + return base.OnDrag(state); + } + + protected override void Update() + { + base.Update(); + leftBox.Scale = new Vector2(MathHelper.Clamp( + nub.DrawPosition.X - nub.DrawWidth / 2 + 2, 0, innerWidth), 1); + rightBox.Scale = new Vector2(MathHelper.Clamp( + innerWidth - nub.DrawPosition.X - nub.DrawWidth / 2 + 2, 0, innerWidth), 1); + } + + protected override void UpdateValue(float value) + { + nub.MoveToX(innerWidth * value); + } + } + } +} diff --git a/osu.Game/Overlays/Options/TextBoxOption.cs b/osu.Game/Overlays/Options/TextBoxOption.cs index ffd9c86b71..c0ac08d149 100644 --- a/osu.Game/Overlays/Options/TextBoxOption.cs +++ b/osu.Game/Overlays/Options/TextBoxOption.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 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.UserInterface; diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index 70462fa5fe..80b2fcdb42 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -2,6 +2,9 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; @@ -58,6 +61,7 @@ namespace osu.Game.Overlays.Toolbar private SpriteText tooltip1; private SpriteText tooltip2; protected FlowContainer Flow; + private AudioSample sampleClick; public ToolbarButton() { @@ -75,7 +79,7 @@ namespace osu.Game.Overlays.Toolbar Direction = FlowDirection.HorizontalOnly, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Padding = new MarginPadding { Left = 15, Right = 15 }, + Padding = new MarginPadding { Left = 20, Right = 20 }, Spacing = new Vector2(5), RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, @@ -120,6 +124,12 @@ namespace osu.Game.Overlays.Toolbar RelativeSizeAxes = Axes.Y; } + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + sampleClick = audio.Sample.Get(@"Menu/menuclick"); + } + protected override void Update() { base.Update(); @@ -133,6 +143,7 @@ namespace osu.Game.Overlays.Toolbar protected override bool OnClick(InputState state) { Action?.Invoke(); + sampleClick.Play(); HoverBackground.FlashColour(new Color4(255, 255, 255, 100), 500, EasingTypes.OutQuint); return true; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs index 3a91a007ff..09708fc403 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs @@ -113,7 +113,9 @@ namespace osu.Game.Overlays.Toolbar Add(s); - s.FadeInFromZero(200); + //todo: fix this... clock dependencies are a pain + if (s.Clock != null) + s.FadeInFromZero(200); }); } } diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index f0de6e7f74..28158457dd 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -1,5 +1,11 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using osu.Framework; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -28,6 +34,7 @@ namespace osu.Game.Screens.Menu private readonly float extraWidth; private Key triggerKey; private string text; + private AudioSample sampleClick; public override bool Contains(Vector2 screenSpacePos) { @@ -211,6 +218,14 @@ namespace osu.Game.Screens.Menu box.ScaleTo(new Vector2(1, 1), 500, EasingTypes.OutElastic); } + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + sampleClick = audio.Sample.Get($@"Menu/menu-{internalName}-click"); + if (sampleClick == null) + sampleClick = audio.Sample.Get(internalName.Contains(@"back") ? @"Menu/menuback" : @"Menu/menuhit"); + } + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { trigger(); @@ -232,11 +247,9 @@ namespace osu.Game.Screens.Menu private void trigger() { - //Game.Audio.PlaySamplePositional($@"menu-{internalName}-click", internalName.Contains(@"back") ? @"menuback" : @"menuhit"); + sampleClick.Play(); clickAction?.Invoke(); - - //box.FlashColour(ColourHelper.Lighten2(colour, 0.7f), 200); } public override bool HandleInput => state != ButtonState.Exploded && box.Scale.X >= 0.8f; @@ -250,6 +263,7 @@ namespace osu.Game.Screens.Menu public int ContractStyle; ButtonState state; + public ButtonState State { get { return state; } diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index f5cf111269..6e15d458c1 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -5,6 +5,9 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -28,6 +31,8 @@ namespace osu.Game.Screens.Menu public Action OnChart; public Action OnTest; + private AudioSample sampleOsuClick; + private FlowContainerWithOrigin buttonFlow; //todo: make these non-internal somehow. @@ -111,6 +116,12 @@ namespace osu.Game.Screens.Menu buttonFlow.Add(buttonsTopLevel); } + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + sampleOsuClick = audio.Sample.Get(@"Menu/menuhit"); + } + protected override void LoadComplete() { base.LoadComplete(); @@ -144,7 +155,6 @@ namespace osu.Game.Screens.Menu private void onExit() { - State = MenuState.Exit; OnExit?.Invoke(); } @@ -158,7 +168,7 @@ namespace osu.Game.Screens.Menu switch (state) { case MenuState.Initial: - //Game.Audio.PlaySamplePositional(@"menuhit"); + sampleOsuClick.Play(); State = MenuState.TopLevel; return; case MenuState.TopLevel: diff --git a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs index cb6bc26b8a..5d99158b7a 100644 --- a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs +++ b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics; +//Copyright (c) 2007-2016 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 System.Collections.Generic; diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index ed7c0fa7e9..ca85546b10 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -25,6 +25,7 @@ namespace osu.Game.Screens.Menu MainMenu mainMenu; private AudioSample welcome; + private AudioSample seeya; private AudioTrack bgm; internal override bool ShowOverlays => (ParentGameMode as OsuGameMode)?.ShowOverlays ?? false; @@ -58,6 +59,7 @@ namespace osu.Game.Screens.Menu private void load(AudioManager audio) { welcome = audio.Sample.Get(@"welcome"); + seeya = audio.Sample.Get(@"seeya"); bgm = audio.Track.Get(@"circles"); bgm.Looping = true; @@ -106,8 +108,15 @@ namespace osu.Game.Screens.Menu protected override void OnResuming(GameMode last) { - //we are just an intro. if we are resumed, we just want to exit after a short delay (to allow the last mode to transition out). - Scheduler.AddDelayed(Exit, 600); + //we also handle the exit transition. + seeya.Play(); + + double fadeOutTime = (last.LifetimeEnd - Time.Current) + 100; + + Scheduler.AddDelayed(Exit, fadeOutTime); + + //don't want to fade out completely else we will stop running updates and shit will hit the fan. + Game.FadeTo(0.01f, fadeOutTime); base.OnResuming(last); } diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index a6f8b51536..7b000ff7d5 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -1,6 +1,7 @@ //Copyright (c) 2007-2016 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.GameModes; using osu.Framework.GameModes.Testing; @@ -49,7 +50,7 @@ namespace osu.Game.Screens.Menu OnSolo = delegate { Push(new PlaySongSelect()); }, OnMulti = delegate { Push(new Lobby()); }, OnTest = delegate { Push(new TestBrowser()); }, - OnExit = delegate { Scheduler.AddDelayed(Exit, ButtonSystem.EXIT_DELAY); }, + OnExit = delegate { Exit(); }, } } } @@ -93,5 +94,12 @@ namespace osu.Game.Screens.Menu Content.FadeIn(length, EasingTypes.OutQuint); Content.MoveTo(new Vector2(0, 0), length, EasingTypes.OutQuint); } + + protected override bool OnExiting(GameMode next) + { + buttons.State = MenuState.Exit; + Content.FadeOut(ButtonSystem.EXIT_DELAY); + return base.OnExiting(next); + } } } diff --git a/osu.Game/Screens/Menu/MenuVisualisation.cs b/osu.Game/Screens/Menu/MenuVisualisation.cs index 194b0eee02..48a1ff532d 100644 --- a/osu.Game/Screens/Menu/MenuVisualisation.cs +++ b/osu.Game/Screens/Menu/MenuVisualisation.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; namespace osu.Game.Screens.Menu { diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 2f35f1b5d5..7e6f5d2b55 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -67,12 +67,10 @@ namespace osu.Game.Screens.Play } sourceClock = (IAdjustableClock)track ?? new StopwatchClock(); - Clock = new InterpolatingFramedClock(sourceClock); Schedule(() => { sourceClock.Reset(); - sourceClock.Start(); }); var beatmap = Beatmap.Beatmap; @@ -103,6 +101,7 @@ namespace osu.Game.Screens.Play { new PlayerInputManager(game.Host) { + Clock = new InterpolatingFramedClock(sourceClock), PassThrough = false, Children = new Drawable[] { @@ -113,11 +112,27 @@ namespace osu.Game.Screens.Play }; } + protected override void LoadComplete() + { + base.LoadComplete(); + + Delay(250, true); + Content.FadeIn(250); + + Delay(500, true); + + Schedule(() => + { + sourceClock.Start(); + }); + } + private void hitRenderer_OnAllJudged() { Delay(1000); Schedule(delegate { + ValidForResume = false; Push(new Results { Score = scoreProcessor.GetScore() @@ -130,12 +145,8 @@ namespace osu.Game.Screens.Play base.OnEntering(last); (Background as BackgroundModeBeatmap)?.BlurTo(Vector2.Zero, 1000); - } - protected override void Update() - { - base.Update(); - Clock.ProcessFrame(); + Content.Alpha = 0; } class PlayerInputManager : UserInputManager diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 203d290fc3..e4aa8f27b9 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -1,4 +1,7 @@ -using System; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using osu.Framework; using osu.Framework.Allocation; using OpenTK; @@ -58,7 +61,6 @@ namespace osu.Game.Screens.Select (beatmapInfoContainer = new BufferedContainer { Depth = newDepth, - PixelSnapping = true, CacheDrawnFrameBuffer = true, Shear = -Shear, RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Screens/Select/CarouselContainer.cs b/osu.Game/Screens/Select/CarouselContainer.cs index 98bcf093af..144e4cabba 100644 --- a/osu.Game/Screens/Select/CarouselContainer.cs +++ b/osu.Game/Screens/Select/CarouselContainer.cs @@ -1,19 +1,21 @@ -//Copyright (c) 2007-2016 ppy Pty Ltd . -//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using OpenTK; -using osu.Framework.Caching; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Transformations; -using osu.Game.Database; -using System; -using System.Collections.Generic; -using System.Linq; -using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Framework.Lists; -using osu.Game.Beatmaps.Drawables; +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Caching; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Transformations; +using osu.Game.Database; +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Lists; +using osu.Game.Beatmaps.Drawables; using osu.Framework.Timing; +using osu.Framework.Input; +using OpenTK.Input; namespace osu.Game.Screens.Select { @@ -190,18 +192,45 @@ namespace osu.Game.Screens.Select return 125 + x; } + /// + /// Update a panel's x position and multiplicative alpha based on its y position and + /// the current scroll position. + /// + /// The panel to be updated. + /// Half the draw height of the carousel container. + private void updatePanel(Panel p, float halfHeight) + { + float panelDrawY = p.Position.Y - Current + p.DrawHeight / 2; + float dist = Math.Abs(1f - panelDrawY / halfHeight); + + // Setting the origin position serves as an additive position on top of potential + // local transformation we may want to apply (e.g. when a panel gets selected, we + // may want to smoothly transform it leftwards.) + p.OriginPosition = new Vector2(-offsetX(dist, halfHeight), 0); + + // We are applying a multiplicative alpha (which is internally done by nesting an + // additional container and setting that container's alpha) such that we can + // layer transformations on top, with a similar reasoning to the previous comment. + p.SetMultiplicativeAlpha(MathHelper.Clamp(1.75f - 1.5f * dist, 0, 1)); + } + protected override void Update() { base.Update(); + // Determine which items stopped being on screen for future removal from the lifetimelist. float drawHeight = DrawHeight; + float halfHeight = drawHeight / 2; - Lifetime.AliveItems.ForEach(delegate (Panel p) + foreach (Panel p in Lifetime.AliveItems) { float panelPosY = p.Position.Y; p.IsOnScreen = panelPosY >= Current - p.DrawHeight && panelPosY <= Current + drawHeight; - }); + updatePanel(p, halfHeight); + } + // Determine range of indices for items that are now definitely on screen to be added + // to the lifetimelist in the future. int firstIndex = yPositions.BinarySearch(Current - Panel.MAX_HEIGHT); if (firstIndex < 0) firstIndex = ~firstIndex; int lastIndex = yPositions.BinarySearch(Current + drawHeight); @@ -210,27 +239,54 @@ namespace osu.Game.Screens.Select Lifetime.StartIndex = firstIndex; Lifetime.EndIndex = lastIndex; - float halfHeight = drawHeight / 2; - for (int i = firstIndex; i < lastIndex; ++i) { - var panel = Lifetime[i]; - - panel.IsOnScreen = true; - - float panelDrawY = panel.Position.Y - Current + panel.DrawHeight / 2; - float dist = Math.Abs(1f - panelDrawY / halfHeight); - - // Setting the origin position serves as an additive position on top of potential - // local transformation we may want to apply (e.g. when a panel gets selected, we - // may want to smoothly transform it leftwards.) - panel.OriginPosition = new Vector2(-offsetX(dist, halfHeight), 0); - - // We are applying a multiplicative alpha (which is internally done by nesting an - // additional container and setting that container's alpha) such that we can - // layer transformations on top, with a similar reasoning to the previous comment. - panel.SetMultiplicativeAlpha(MathHelper.Clamp(1.75f - 1.5f * dist, 0, 1)); + Panel p = Lifetime[i]; + p.IsOnScreen = true; + updatePanel(p, halfHeight); } } + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + int direction = 0; + bool skipDifficulties = false; + + switch (args.Key) + { + case Key.Up: + direction = -1; + break; + case Key.Down: + direction = 1; + break; + case Key.Left: + direction = -1; + skipDifficulties = true; + break; + case Key.Right: + direction = 1; + skipDifficulties = true; + break; + } + + if (direction != 0) + { + int index = SelectedGroup.BeatmapPanels.IndexOf(SelectedPanel) + direction; + + if (!skipDifficulties && index >= 0 && index < SelectedGroup.BeatmapPanels.Count) + //changing difficulty panel, not set. + SelectGroup(SelectedGroup, SelectedGroup.BeatmapPanels[index]); + else + { + index = (groups.IndexOf(SelectedGroup) + direction + groups.Count) % groups.Count; + SelectBeatmap(groups[index].BeatmapPanels.First().Beatmap); + } + + return true; + } + + return base.OnKeyDown(state, args); + } } } diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 983d5008df..fb3f6acbdf 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -24,8 +24,12 @@ using OpenTK; using OpenTK.Graphics; using osu.Game.Screens.Play; using osu.Framework; +using osu.Framework.Audio.Sample; +using osu.Framework.Graphics.Transformations; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics.Containers; +using osu.Framework.Input; +using OpenTK.Input; namespace osu.Game.Screens.Select { @@ -45,6 +49,9 @@ namespace osu.Game.Screens.Select private static readonly Vector2 BACKGROUND_BLUR = new Vector2(20); private CancellationTokenSource initialAddSetsTask; + private AudioSample sampleChangeDifficulty; + private AudioSample sampleChangeBeatmap; + class WedgeBackground : Container { public WedgeBackground() @@ -136,17 +143,38 @@ namespace osu.Game.Screens.Select Width = 100, Text = "Play", Colour = new Color4(238, 51, 153, 255), - Action = () => Push(new Player - { - BeatmapInfo = carousel.SelectedGroup.SelectedPanel.Beatmap, - PreferredPlayMode = playMode.Value - }) + Action = start }, } } }; } + Player player; + + private void start() + { + if (player != null) + return; + + //in the future we may want to move this logic to a PlayerLoader gamemode or similar, so we can rely on the SongSelect transition + //and provide a better loading experience (at the moment song select is still accepting input during preload). + player = new Player + { + BeatmapInfo = carousel.SelectedGroup.SelectedPanel.Beatmap, + PreferredPlayMode = playMode.Value + }; + + player.Preload(Game, delegate + { + if (!Push(player)) + { + player = null; + //error occured? + } + }); + } + [BackgroundDependencyLoader(permitNulls: true)] private void load(BeatmapDatabase beatmaps, AudioManager audio, BaseGame game, OsuGame osuGame) { @@ -163,6 +191,9 @@ namespace osu.Game.Screens.Select trackManager = audio.Track; + sampleChangeDifficulty = audio.Sample.Get(@"SongSelect/select-difficulty"); + sampleChangeBeatmap = audio.Sample.Get(@"SongSelect/select-expand"); + initialAddSetsTask = new CancellationTokenSource(); Task.Factory.StartNew(() => addBeatmapSets(game, initialAddSetsTask.Token), initialAddSetsTask.Token); @@ -181,25 +212,40 @@ namespace osu.Game.Screens.Select changeBackground(Beatmap); Content.FadeInFromZero(250); + + beatmapInfoWedge.MoveTo(wedged_container_start_position + new Vector2(-100, 50)); + beatmapInfoWedge.RotateTo(10); + + beatmapInfoWedge.MoveTo(wedged_container_start_position, 800, EasingTypes.OutQuint); + beatmapInfoWedge.RotateTo(0, 800, EasingTypes.OutQuint); } protected override void OnResuming(GameMode last) { + player = null; + changeBackground(Beatmap); ensurePlayingSelected(); base.OnResuming(last); Content.FadeIn(250); + + Content.ScaleTo(1, 250, EasingTypes.OutSine); } protected override void OnSuspending(GameMode next) { + Content.ScaleTo(1.1f, 250, EasingTypes.InSine); + Content.FadeOut(250); base.OnSuspending(next); } protected override bool OnExiting(GameMode next) { + beatmapInfoWedge.MoveTo(wedged_container_start_position + new Vector2(-100, 50), 800, EasingTypes.InQuint); + beatmapInfoWedge.RotateTo(10, 800, EasingTypes.InQuint); + Content.FadeOut(100); return base.OnExiting(next); } @@ -258,13 +304,23 @@ namespace osu.Game.Screens.Select /// private void selectionChanged(BeatmapGroup group, BeatmapInfo beatmap) { - if (!beatmap.Equals(Beatmap?.BeatmapInfo)) - Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap); + bool beatmapSetChange = false; - ensurePlayingSelected(); + if (!beatmap.Equals(Beatmap?.BeatmapInfo)) + { + if (beatmap.BeatmapSetID == Beatmap?.BeatmapInfo.BeatmapSetID) + sampleChangeDifficulty.Play(); + else + { + sampleChangeBeatmap.Play(); + beatmapSetChange = true; + } + Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap); + } + ensurePlayingSelected(beatmapSetChange); } - private async Task ensurePlayingSelected() + private async Task ensurePlayingSelected(bool preview = false) { AudioTrack track = null; @@ -275,6 +331,8 @@ namespace osu.Game.Screens.Select if (track != null) { trackManager.SetExclusive(track); + if (preview) + track.Seek(Beatmap.Beatmap.Metadata.PreviewTime); track.Start(); } }); @@ -283,10 +341,15 @@ namespace osu.Game.Screens.Select private void addBeatmapSet(BeatmapSetInfo beatmapSet, BaseGame game) { beatmapSet = database.GetWithChildren(beatmapSet.BeatmapSetID); - beatmapSet.Beatmaps.ForEach(b => database.GetChildren(b)); + beatmapSet.Beatmaps.ForEach(b => + { + database.GetChildren(b); + if (b.Metadata == null) b.Metadata = beatmapSet.Metadata; + }); + beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList(); - var beatmap = database.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()); + var beatmap = new WorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault(), beatmapSet, database); var group = new BeatmapGroup(beatmap) { SelectionChanged = selectionChanged }; @@ -315,5 +378,17 @@ namespace osu.Game.Screens.Select addBeatmapSet(beatmapSet, game); } } + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + switch (args.Key) + { + case Key.Enter: + start(); + return true; + } + + return base.OnKeyDown(state, args); + } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c4915b7567..a15cd5db7d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -222,6 +222,15 @@ + + + + + + + + + @@ -250,4 +259,4 @@ --> - \ No newline at end of file + diff --git a/osu.Game/packages.config b/osu.Game/packages.config index 30ac6bb021..98448d402f 100644 --- a/osu.Game/packages.config +++ b/osu.Game/packages.config @@ -3,6 +3,7 @@ Copyright (c) 2007-2016 ppy Pty Ltd . Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE --> + diff --git a/osu.sln b/osu.sln index 9677a752fb..f3736c16c0 100644 --- a/osu.sln +++ b/osu.sln @@ -21,7 +21,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Desktop.VisualTests", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Tests", "osu.Game.Tests\osu.Game.Tests.csproj", "{54377672-20B1-40AF-8087-5CF73BF3953A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Modes.Osu", "osu.Game.Mode.Osu\osu.Game.Modes.Osu.csproj", "{C92A607B-1FDD-4954-9F92-03FF547D9080}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Modes.Osu", "osu.Game.Modes.Osu\osu.Game.Modes.Osu.csproj", "{C92A607B-1FDD-4954-9F92-03FF547D9080}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Modes.Catch", "osu.Game.Modes.Catch\osu.Game.Modes.Catch.csproj", "{58F6C80C-1253-4A0E-A465-B8C85EBEADF3}" EndProject