diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/VisualTestRunner.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/VisualTestRunner.cs
index 03ee7c9204..63c481a623 100644
--- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/VisualTestRunner.cs
+++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/VisualTestRunner.cs
@@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.EmptyFreeform.Tests
[STAThread]
public static int Main(string[] args)
{
- using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu", new HostOptions { BindIPC = true }))
+ using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu"))
{
host.Run(new OsuTestBrowser());
return 0;
diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj
index 2baa7ee0e0..5babdb47ff 100644
--- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj
+++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/VisualTestRunner.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/VisualTestRunner.cs
index 55c0cf6a3b..c44cbb845b 100644
--- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/VisualTestRunner.cs
+++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/VisualTestRunner.cs
@@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Pippidon.Tests
[STAThread]
public static int Main(string[] args)
{
- using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu", new HostOptions { BindIPC = true }))
+ using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu"))
{
host.Run(new OsuTestBrowser());
return 0;
diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
index a2308e6dfc..5d64ca832a 100644
--- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
+++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/VisualTestRunner.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/VisualTestRunner.cs
index b45505678c..5beb6616a7 100644
--- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/VisualTestRunner.cs
+++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/VisualTestRunner.cs
@@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.EmptyScrolling.Tests
[STAThread]
public static int Main(string[] args)
{
- using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu", new HostOptions { BindIPC = true }))
+ using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu"))
{
host.Run(new OsuTestBrowser());
return 0;
diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj
index e839d2657c..6796a8962b 100644
--- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj
+++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/VisualTestRunner.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/VisualTestRunner.cs
index 55c0cf6a3b..c44cbb845b 100644
--- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/VisualTestRunner.cs
+++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/VisualTestRunner.cs
@@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Pippidon.Tests
[STAThread]
public static int Main(string[] args)
{
- using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu", new HostOptions { BindIPC = true }))
+ using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu"))
{
host.Run(new OsuTestBrowser());
return 0;
diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
index a2308e6dfc..5d64ca832a 100644
--- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
+++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/osu.Desktop/Program.cs b/osu.Desktop/Program.cs
index 6b95a82703..a7453dc0e0 100644
--- a/osu.Desktop/Program.cs
+++ b/osu.Desktop/Program.cs
@@ -102,7 +102,7 @@ namespace osu.Desktop
}
}
- using (DesktopGameHost host = Host.GetSuitableDesktopHost(gameName, new HostOptions { BindIPC = !tournamentClient }))
+ using (DesktopGameHost host = Host.GetSuitableDesktopHost(gameName, new HostOptions { IPCPort = !tournamentClient ? OsuGame.IPC_PORT : null }))
{
if (!host.IsPrimaryInstance)
{
diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj
index f37cfdc5f1..d6a11fa924 100644
--- a/osu.Desktop/osu.Desktop.csproj
+++ b/osu.Desktop/osu.Desktop.csproj
@@ -23,9 +23,9 @@
-
+
-
+
diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
index 5de21a68d0..47c93fbd02 100644
--- a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
+++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
index c45c85833c..0a77845343 100644
--- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
+++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
@@ -2,7 +2,7 @@
-
+
diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneBarLine.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneBarLine.cs
index ab9f57ecc3..a5c18babe2 100644
--- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneBarLine.cs
+++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneBarLine.cs
@@ -1,10 +1,8 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using System;
using System.Collections.Generic;
using NUnit.Framework;
-using osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.UI;
@@ -16,37 +14,35 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
[Test]
public void TestMinor()
{
- AddStep("Create barlines", () => recreate());
+ AddStep("Create barlines", recreate);
}
- private void recreate(Func>? createBarLines = null)
+ private void recreate()
{
var stageDefinitions = new List
{
new StageDefinition(4),
};
- SetContents(_ => new ManiaPlayfield(stageDefinitions).With(s =>
+ SetContents(_ =>
{
- if (createBarLines != null)
+ var maniaPlayfield = new ManiaPlayfield(stageDefinitions);
+
+ // Must be scheduled so the pool is loaded before we try and retrieve from it.
+ Schedule(() =>
{
- var barLines = createBarLines();
-
- foreach (var b in barLines)
- s.Add(b);
-
- return;
- }
-
- for (int i = 0; i < 64; i++)
- {
- s.Add(new BarLine
+ for (int i = 0; i < 64; i++)
{
- StartTime = Time.Current + i * 500,
- Major = i % 4 == 0,
- });
- }
- }));
+ maniaPlayfield.Add(new BarLine
+ {
+ StartTime = Time.Current + i * 500,
+ Major = i % 4 == 0,
+ });
+ }
+ });
+
+ return maniaPlayfield;
+ });
}
}
}
diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
index b991db408c..877b9c3ea4 100644
--- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
+++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
@@ -2,7 +2,7 @@
-
+
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs
index 874130233a..5f5596cbb3 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs
@@ -25,16 +25,16 @@ namespace osu.Game.Rulesets.Osu.Tests
[Resolved]
private OsuConfigManager config { get; set; } = null!;
- private readonly List> pools;
+ private readonly List> pools = new List>();
- public TestSceneDrawableJudgement()
+ [TestCaseSource(nameof(validResults))]
+ public void Test(HitResult result)
{
- pools = new List>();
-
- foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType().Skip(1))
- showResult(result);
+ showResult(result);
}
+ private static IEnumerable validResults => Enum.GetValues().Skip(1);
+
[Test]
public void TestHitLightingDisabled()
{
@@ -72,32 +72,33 @@ namespace osu.Game.Rulesets.Osu.Tests
pools.Add(pool = new DrawablePool(1));
else
{
- pool = pools[poolIndex];
-
// We need to make sure neither the pool nor the judgement get disposed when new content is set, and they both share the same parent.
+ pool = pools[poolIndex];
((Container)pool.Parent!).Clear(false);
}
var container = new Container
{
RelativeSizeAxes = Axes.Both,
- Children = new Drawable[]
- {
- pool,
- pool.Get(j => j.Apply(new JudgementResult(new HitObject
- {
- StartTime = Time.Current
- }, new Judgement())
- {
- Type = result,
- }, null)).With(j =>
- {
- j.Anchor = Anchor.Centre;
- j.Origin = Anchor.Centre;
- })
- }
+ Child = pool,
};
+ // Must be scheduled so the pool is loaded before we try and retrieve from it.
+ Schedule(() =>
+ {
+ container.Add(pool.Get(j => j.Apply(new JudgementResult(new HitObject
+ {
+ StartTime = Time.Current
+ }, new Judgement())
+ {
+ Type = result,
+ }, null)).With(j =>
+ {
+ j.Anchor = Anchor.Centre;
+ j.Origin = Anchor.Centre;
+ }));
+ });
+
poolIndex++;
return container;
});
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs
index f41dd913ab..380a2087ac 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs
@@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Tests
{
DrawableSlider dho = null;
- AddStep("create slider", () => Child = dho = new DrawableSlider(prepareObject(new Slider
+ AddStep("create slider", () => Child = dho = new DrawableSlider(applyDefaults(new Slider
{
Position = new Vector2(256, 192),
IndexInCurrentCombo = 0,
@@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Osu.Tests
AddWaitStep("wait for progression", 1);
- AddStep("apply new slider", () => dho.Apply(prepareObject(new Slider
+ AddStep("apply new slider", () => dho.Apply(applyDefaults(new Slider
{
Position = new Vector2(256, 192),
ComboIndex = 1,
@@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Osu.Tests
Child = new SkinProvidingContainer(provider)
{
RelativeSizeAxes = Axes.Both,
- Child = dho = new DrawableSlider(prepareObject(new Slider
+ Child = dho = new DrawableSlider(applyDefaults(new Slider
{
Position = new Vector2(256, 192),
IndexInCurrentCombo = 0,
@@ -97,7 +97,38 @@ namespace osu.Game.Rulesets.Osu.Tests
AddAssert("ball is red", () => dho.ChildrenOfType().Single().BallColour == Color4.Red);
}
- private Slider prepareObject(Slider slider)
+ [Test]
+ public void TestIncreaseRepeatCount()
+ {
+ DrawableSlider dho = null;
+
+ AddStep("create slider", () =>
+ {
+ Child = dho = new DrawableSlider(applyDefaults(new Slider
+ {
+ Position = new Vector2(256, 192),
+ IndexInCurrentCombo = 0,
+ StartTime = Time.Current,
+ Path = new SliderPath(PathType.LINEAR, new[]
+ {
+ Vector2.Zero,
+ new Vector2(150, 100),
+ new Vector2(300, 0),
+ })
+ }));
+ });
+
+ AddStep("increase repeat count", () =>
+ {
+ dho.HitObject.RepeatCount++;
+ applyDefaults(dho.HitObject);
+ });
+
+ AddAssert("repeat got custom anchor", () =>
+ dho.ChildrenOfType().Single().RelativeAnchorPosition == Vector2.Divide(dho.SliderBody!.PathOffset, dho.DrawSize));
+ }
+
+ private Slider applyDefaults(Slider slider)
{
slider.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
return slider;
diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
index ea033cda45..9c248abd66 100644
--- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
+++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
@@ -3,7 +3,7 @@
-
+
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
index ed4c02a4a9..baec200107 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
@@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
private Container repeatContainer;
private PausableSkinnableSound slidingSample;
- private readonly LayoutValue drawSizeLayout;
+ private readonly LayoutValue relativeAnchorPositionLayout;
public DrawableSlider()
: this(null)
@@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
AlwaysPresent = true,
Alpha = 0
};
- AddLayout(drawSizeLayout = new LayoutValue(Invalidation.DrawSize | Invalidation.MiscGeometry));
+ AddLayout(relativeAnchorPositionLayout = new LayoutValue(Invalidation.DrawSize | Invalidation.MiscGeometry));
}
[BackgroundDependencyLoader]
@@ -190,6 +190,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
repeatContainer.Add(repeat);
break;
}
+
+ relativeAnchorPositionLayout.Invalidate();
}
protected override void ClearNestedHitObjects()
@@ -265,14 +267,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Size = SliderBody?.Size ?? Vector2.Zero;
OriginPosition = SliderBody?.PathOffset ?? Vector2.Zero;
- if (!drawSizeLayout.IsValid)
+ if (!relativeAnchorPositionLayout.IsValid)
{
Vector2 pos = Vector2.Divide(OriginPosition, DrawSize);
foreach (var obj in NestedHitObjects)
obj.RelativeAnchorPosition = pos;
Ball.RelativeAnchorPosition = pos;
- drawSizeLayout.Validate();
+ relativeAnchorPositionLayout.Validate();
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonCursor.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonCursor.cs
index 4ca6abfdf7..15838f3e1b 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonCursor.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonCursor.cs
@@ -13,7 +13,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Osu.Skinning.Argon
{
- public partial class ArgonCursor : OsuCursorSprite
+ public partial class ArgonCursor : SkinnableCursor
{
public ArgonCursor()
{
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs
index b65f46c414..272f4b5658 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs
@@ -3,47 +3,39 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
-using osu.Framework.Graphics;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Graphics.Textures;
using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Rulesets.Osu.Skinning.Default
{
- public partial class DefaultApproachCircle : SkinnableSprite
+ public partial class DefaultApproachCircle : Sprite
{
- private readonly IBindable accentColour = new Bindable();
-
[Resolved]
private DrawableHitObject drawableObject { get; set; } = null!;
- public DefaultApproachCircle()
- : base("Gameplay/osu/approachcircle")
- {
- }
+ private IBindable accentColour = null!;
[BackgroundDependencyLoader]
- private void load()
+ private void load(TextureStore textures)
{
- accentColour.BindTo(drawableObject.AccentColour);
+ Texture = textures.Get(@"Gameplay/osu/approachcircle").WithMaximumSize(OsuHitObject.OBJECT_DIMENSIONS * 2);
+
+ // account for the sprite being used for the default approach circle being taken from stable,
+ // when hitcircles have 5px padding on each size. this should be removed if we update the sprite.
+ Scale = new Vector2(128 / 118f);
}
protected override void LoadComplete()
{
base.LoadComplete();
- accentColour.BindValueChanged(colour => Colour = colour.NewValue, true);
- }
- protected override Drawable CreateDefault(ISkinComponentLookup lookup)
- {
- var drawable = base.CreateDefault(lookup);
-
- // Although this is a non-legacy component, osu-resources currently stores approach circle as a legacy-like texture.
- // See LegacyApproachCircle for documentation as to why this is required.
- drawable.Scale = new Vector2(128 / 118f);
-
- return drawable;
+ accentColour = drawableObject.AccentColour.GetBoundCopy();
+ accentColour.BindValueChanged(colour => Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true);
}
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs
index f1143cf14d..566176505d 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs
@@ -15,6 +15,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
TriangleScale = 1.2f;
HideAlphaDiscrepancies = false;
+ ClampToDrawable = false;
}
protected override void Update()
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs
index eea6606233..0bdea0cab1 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs
@@ -1,9 +1,10 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
-using osu.Framework.Graphics;
+using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Skinning;
@@ -12,40 +13,31 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
- // todo: this should probably not be a SkinnableSprite, as this is always created for legacy skins and is recreated on skin change.
- public partial class LegacyApproachCircle : SkinnableSprite
+ public partial class LegacyApproachCircle : Sprite
{
- private readonly IBindable accentColour = new Bindable();
-
[Resolved]
private DrawableHitObject drawableObject { get; set; } = null!;
- public LegacyApproachCircle()
- : base("Gameplay/osu/approachcircle", OsuHitObject.OBJECT_DIMENSIONS * 2)
- {
- }
+ private IBindable accentColour = null!;
[BackgroundDependencyLoader]
- private void load()
+ private void load(ISkinSource skin)
{
- accentColour.BindTo(drawableObject.AccentColour);
+ var texture = skin.GetTexture(@"approachcircle");
+ Debug.Assert(texture != null);
+ Texture = texture.WithMaximumSize(OsuHitObject.OBJECT_DIMENSIONS * 2);
+
+ // account for the sprite being used for the default approach circle being taken from stable,
+ // when hitcircles have 5px padding on each size. this should be removed if we update the sprite.
+ Scale = new Vector2(128 / 118f);
}
protected override void LoadComplete()
{
base.LoadComplete();
+
+ accentColour = drawableObject.AccentColour.GetBoundCopy();
accentColour.BindValueChanged(colour => Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true);
}
-
- protected override Drawable CreateDefault(ISkinComponentLookup lookup)
- {
- var drawable = base.CreateDefault(lookup);
-
- // account for the sprite being used for the default approach circle being taken from stable,
- // when hitcircles have 5px padding on each size. this should be removed if we update the sprite.
- drawable.Scale = new Vector2(128 / 118f);
-
- return drawable;
- }
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs
index b0c01d2925..375d81049d 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs
@@ -9,8 +9,11 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
- public partial class LegacyCursor : OsuCursorSprite
+ public partial class LegacyCursor : SkinnableCursor
{
+ private const float pressed_scale = 1.3f;
+ private const float released_scale = 1f;
+
private readonly ISkin skin;
private bool spin;
@@ -51,5 +54,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
if (spin)
ExpandTarget.Spin(10000, RotationDirection.Clockwise);
}
+
+ public override void Expand()
+ {
+ ExpandTarget?.ScaleTo(released_scale)
+ .ScaleTo(pressed_scale, 100, Easing.Out);
+ }
+
+ public override void Contract()
+ {
+ ExpandTarget?.ScaleTo(released_scale, 100, Easing.Out);
+ }
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs
index 780084115d..ad1fb98aef 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs
@@ -34,19 +34,19 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableObject, ISkinSource skinSource)
{
+ const string lookup_name = @"reversearrow";
+
drawableRepeat = (DrawableSliderRepeat)drawableObject;
AutoSizeAxes = Axes.Both;
- string lookupName = new OsuSkinComponentLookup(OsuSkinComponents.ReverseArrow).LookupName;
-
- var skin = skinSource.FindProvider(s => s.GetTexture(lookupName) != null);
+ var skin = skinSource.FindProvider(s => s.GetTexture(lookup_name) != null);
InternalChild = arrow = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Texture = skin?.GetTexture(lookupName)?.WithMaximumSize(maxSize: OsuHitObject.OBJECT_DIMENSIONS * 2),
+ Texture = skin?.GetTexture(lookup_name)?.WithMaximumSize(maxSize: OsuHitObject.OBJECT_DIMENSIONS * 2),
};
textureIsDefaultSkin = skin is ISkinTransformer transformer && transformer.Skin is DefaultLegacySkin;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs
index c01d28c8e1..d2ebc68c52 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs
@@ -163,7 +163,10 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
return null;
case OsuSkinComponents.ApproachCircle:
- return new LegacyApproachCircle();
+ if (GetTexture(@"approachcircle") != null)
+ return new LegacyApproachCircle();
+
+ return null;
default:
throw new UnsupportedSkinComponentException(lookup);
diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs
index 710ca9ace7..d8f50c1f5d 100644
--- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs
+++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs
@@ -24,15 +24,12 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
{
public const float SIZE = 28;
- private const float pressed_scale = 1.2f;
- private const float released_scale = 1f;
-
private bool cursorExpand;
private SkinnableDrawable cursorSprite;
private Container cursorScaleContainer = null!;
- private Drawable expandTarget => (cursorSprite.Drawable as OsuCursorSprite)?.ExpandTarget ?? cursorSprite;
+ private SkinnableCursor skinnableCursor => (SkinnableCursor)cursorSprite.Drawable;
public IBindable CursorScale => cursorScale;
@@ -108,10 +105,10 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
{
if (!cursorExpand) return;
- expandTarget.ScaleTo(released_scale).ScaleTo(pressed_scale, 400, Easing.OutElasticHalf);
+ skinnableCursor.Expand();
}
- public void Contract() => expandTarget.ScaleTo(released_scale, 400, Easing.OutQuad);
+ public void Contract() => skinnableCursor.Contract();
///
/// Get the scale applicable to the ActiveCursor based on a beatmap's circle size.
@@ -119,7 +116,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
public static float GetScaleForCircleSize(float circleSize) =>
1f - 0.7f * (1f + circleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY;
- private partial class DefaultCursor : OsuCursorSprite
+ private partial class DefaultCursor : SkinnableCursor
{
public DefaultCursor()
{
diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorSprite.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorSprite.cs
deleted file mode 100644
index aaf8949084..0000000000
--- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorSprite.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
-// See the LICENCE file in the repository root for full licence text.
-
-#nullable disable
-
-using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
-
-namespace osu.Game.Rulesets.Osu.UI.Cursor
-{
- public abstract partial class OsuCursorSprite : CompositeDrawable
- {
- ///
- /// The an optional piece of the cursor to expand when in a clicked state.
- /// If null, the whole cursor will be affected by expansion.
- ///
- public Drawable ExpandTarget { get; protected set; }
- }
-}
diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/SkinnableCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/SkinnableCursor.cs
new file mode 100644
index 0000000000..09e6f989a4
--- /dev/null
+++ b/osu.Game.Rulesets.Osu/UI/Cursor/SkinnableCursor.cs
@@ -0,0 +1,31 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+
+namespace osu.Game.Rulesets.Osu.UI.Cursor
+{
+ public abstract partial class SkinnableCursor : CompositeDrawable
+ {
+ private const float pressed_scale = 1.2f;
+ private const float released_scale = 1f;
+
+ public virtual void Expand()
+ {
+ ExpandTarget?.ScaleTo(released_scale)
+ .ScaleTo(pressed_scale, 400, Easing.OutElasticHalf);
+ }
+
+ public virtual void Contract()
+ {
+ ExpandTarget?.ScaleTo(released_scale, 400, Easing.OutQuad);
+ }
+
+ ///
+ /// The an optional piece of the cursor to expand when in a clicked state.
+ /// If null, the whole cursor will be affected by expansion.
+ ///
+ public Drawable? ExpandTarget { get; protected set; }
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
index 48465bb119..4eb6b0ab3d 100644
--- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
+++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
@@ -2,7 +2,7 @@
-
+
diff --git a/osu.Game.Tests/NonVisual/Skinning/LegacySkinTextureFallbackTest.cs b/osu.Game.Tests/NonVisual/Skinning/LegacySkinTextureFallbackTest.cs
index ff954211eb..fbe5a0e4d7 100644
--- a/osu.Game.Tests/NonVisual/Skinning/LegacySkinTextureFallbackTest.cs
+++ b/osu.Game.Tests/NonVisual/Skinning/LegacySkinTextureFallbackTest.cs
@@ -56,24 +56,6 @@ namespace osu.Game.Tests.NonVisual.Skinning
"Gameplay/osu/followpoint", 1
},
new object[]
- {
- new[] { "followpoint@2x", "followpoint" },
- "Gameplay/osu/followpoint",
- "followpoint@2x", 2
- },
- new object[]
- {
- new[] { "followpoint@2x" },
- "Gameplay/osu/followpoint",
- "followpoint@2x", 2
- },
- new object[]
- {
- new[] { "followpoint" },
- "Gameplay/osu/followpoint",
- "followpoint", 1
- },
- new object[]
{
// Looking up a filename with extension specified should work.
new[] { "followpoint.png" },
diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs
index 378dd99664..4733b7f92f 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs
@@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.Background
AddSliderStep("Triangle scale", 0f, 10f, 1f, s => triangles.TriangleScale = s);
AddSliderStep("Seed", 0, 1000, 0, s => triangles.Reset(s));
- AddToggleStep("Masking", m => triangles.Masking = m);
+ AddToggleStep("ClampToDrawable", c => triangles.ClampToDrawable = c);
}
}
}
diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs
index 01a2464b8e..71d1baddc8 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs
@@ -128,7 +128,7 @@ namespace osu.Game.Tests.Visual.Background
AddStep("White colour", () => box.Colour = triangles.Colour = maskedTriangles.Colour = Color4.White);
AddStep("Vertical gradient", () => box.Colour = triangles.Colour = maskedTriangles.Colour = ColourInfo.GradientVertical(Color4.White, Color4.Red));
AddStep("Horizontal gradient", () => box.Colour = triangles.Colour = maskedTriangles.Colour = ColourInfo.GradientHorizontal(Color4.White, Color4.Red));
- AddToggleStep("Masking", m => maskedTriangles.Masking = m);
+ AddToggleStep("ClampToDrawable", c => maskedTriangles.ClampToDrawable = c);
}
}
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs
index ec3b3e0822..73aa3be73d 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs
@@ -93,15 +93,12 @@ namespace osu.Game.Tests.Visual.Gameplay
double currentTime = masterClock.CurrentTime;
- bool goingForward = currentTime >= (masterClock.LastStopTime ?? lastStopTime);
+ bool goingForward = currentTime >= lastStopTime;
alwaysGoingForward &= goingForward;
if (!goingForward)
Logger.Log($"Went too far backwards (last stop: {lastStopTime:N1} current: {currentTime:N1})");
-
- if (masterClock.LastStopTime != null)
- lastStopTime = masterClock.LastStopTime.Value;
};
});
@@ -125,7 +122,7 @@ namespace osu.Game.Tests.Visual.Gameplay
resumeAndConfirm();
- AddAssert("Resumed without seeking forward", () => Player.LastResumeTime, () => Is.LessThanOrEqualTo(Player.LastPauseTime));
+ AddAssert("continued playing forward", () => Player.LastResumeTime, () => Is.GreaterThanOrEqualTo(Player.LastPauseTime));
AddUntilStep("player playing", () => Player.LocalUserPlaying.Value);
}
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneInterProcessCommunication.cs b/osu.Game.Tests/Visual/Navigation/TestSceneInterProcessCommunication.cs
index 1ecd38e1d3..83430b5665 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneInterProcessCommunication.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneInterProcessCommunication.cs
@@ -63,7 +63,7 @@ namespace osu.Game.Tests.Visual.Navigation
});
AddStep("create IPC sender channels", () =>
{
- ipcSenderHost = new HeadlessGameHost(gameHost.Name, new HostOptions { BindIPC = true });
+ ipcSenderHost = new HeadlessGameHost(gameHost.Name, new HostOptions { IPCPort = OsuGame.IPC_PORT });
osuSchemeLinkIPCSender = new OsuSchemeLinkIPCChannel(ipcSenderHost);
archiveImportIPCSender = new ArchiveImportIPCChannel(ipcSenderHost);
});
diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs
index 2926b11067..ee0c64aa3f 100644
--- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs
+++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs
@@ -40,8 +40,15 @@ namespace osu.Game.Tests.Visual.Settings
AddStep("change value from default", () => textBox.Current.Value = "non-default");
AddUntilStep("restore button shown", () => revertToDefaultButton.Alpha > 0);
+ AddStep("disable setting", () => textBox.Current.Disabled = true);
+ AddUntilStep("restore button still shown", () => revertToDefaultButton.Alpha > 0);
+
+ AddStep("enable setting", () => textBox.Current.Disabled = false);
AddStep("restore default", () => textBox.Current.SetDefault());
AddUntilStep("restore button hidden", () => revertToDefaultButton.Alpha == 0);
+
+ AddStep("disable setting", () => textBox.Current.Disabled = true);
+ AddUntilStep("restore button still hidden", () => revertToDefaultButton.Alpha == 0);
}
[Test]
diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj
index ef6c16f2c4..7b08524240 100644
--- a/osu.Game.Tests/osu.Game.Tests.csproj
+++ b/osu.Game.Tests/osu.Game.Tests.csproj
@@ -4,7 +4,7 @@
-
+
diff --git a/osu.Game.Tournament.Tests/TournamentTestRunner.cs b/osu.Game.Tournament.Tests/TournamentTestRunner.cs
index 5f642b14f5..e09d1be22c 100644
--- a/osu.Game.Tournament.Tests/TournamentTestRunner.cs
+++ b/osu.Game.Tournament.Tests/TournamentTestRunner.cs
@@ -12,7 +12,7 @@ namespace osu.Game.Tournament.Tests
[STAThread]
public static int Main(string[] args)
{
- using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu-development", new HostOptions { BindIPC = true }))
+ using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu-development"))
{
host.Run(new TournamentTestBrowser());
return 0;
diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
index 2cc07dd9ed..3b00f103c4 100644
--- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
+++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/osu.Game.Tournament/Components/SongBar.cs b/osu.Game.Tournament/Components/SongBar.cs
index cc1d00f62f..ae59e92e33 100644
--- a/osu.Game.Tournament/Components/SongBar.cs
+++ b/osu.Game.Tournament/Components/SongBar.cs
@@ -12,6 +12,7 @@ using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Legacy;
using osu.Game.Extensions;
using osu.Game.Graphics;
+using osu.Game.Models;
using osu.Game.Rulesets;
using osu.Game.Screens.Menu;
using osuTK;
@@ -101,11 +102,25 @@ namespace osu.Game.Tournament.Components
private void refreshContent()
{
- if (beatmap == null)
+ beatmap ??= new BeatmapInfo
{
- flow.Clear();
- return;
- }
+ Metadata = new BeatmapMetadata
+ {
+ Artist = "unknown",
+ Title = "no beatmap selected",
+ Author = new RealmUser { Username = "unknown" },
+ },
+ DifficultyName = "unknown",
+ BeatmapSet = new BeatmapSetInfo(),
+ StarRating = 0,
+ Difficulty = new BeatmapDifficulty
+ {
+ CircleSize = 0,
+ DrainRate = 0,
+ OverallDifficulty = 0,
+ ApproachRate = 0,
+ },
+ };
double bpm = beatmap.BPM;
double length = beatmap.Length;
diff --git a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs
index 4e0adb30ac..514ba482c4 100644
--- a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs
+++ b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs
@@ -194,7 +194,7 @@ namespace osu.Game.Tournament.Components
// Use DelayedLoadWrapper to avoid content unloading when switching away to another screen.
protected override DelayedLoadWrapper CreateDelayedLoadWrapper(Func createContentFunc, double timeBeforeLoad)
- => new DelayedLoadWrapper(createContentFunc, timeBeforeLoad);
+ => new DelayedLoadWrapper(createContentFunc(), timeBeforeLoad);
}
}
}
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
index 1665ec52fa..eecf79aa34 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
@@ -92,7 +92,6 @@ namespace osu.Game.Beatmaps.Drawables
EdgeEffect = new EdgeEffectParameters
{
Colour = Color4.Black.Opacity(0.06f),
-
Type = EdgeEffectType.Shadow,
Radius = 3,
},
diff --git a/osu.Game/Beatmaps/FramedBeatmapClock.cs b/osu.Game/Beatmaps/FramedBeatmapClock.cs
index 587e6bbeed..d0ffbdd459 100644
--- a/osu.Game/Beatmaps/FramedBeatmapClock.cs
+++ b/osu.Game/Beatmaps/FramedBeatmapClock.cs
@@ -27,11 +27,6 @@ namespace osu.Game.Beatmaps
{
private readonly bool applyOffsets;
- ///
- /// The total frequency adjustment from pause transforms. Should eventually be handled in a better way.
- ///
- public readonly BindableDouble ExternalPauseFrequencyAdjust = new BindableDouble(1);
-
private readonly OffsetCorrectionClock? userGlobalOffsetClock;
private readonly OffsetCorrectionClock? platformOffsetClock;
private readonly OffsetCorrectionClock? userBeatmapOffsetClock;
@@ -69,13 +64,13 @@ namespace osu.Game.Beatmaps
{
// Audio timings in general with newer BASS versions don't match stable.
// This only seems to be required on windows. We need to eventually figure out why, with a bit of luck.
- platformOffsetClock = new OffsetCorrectionClock(interpolatedTrack, ExternalPauseFrequencyAdjust) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 15 : 0 };
+ platformOffsetClock = new OffsetCorrectionClock(interpolatedTrack) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 15 : 0 };
// User global offset (set in settings) should also be applied.
- userGlobalOffsetClock = new OffsetCorrectionClock(platformOffsetClock, ExternalPauseFrequencyAdjust);
+ userGlobalOffsetClock = new OffsetCorrectionClock(platformOffsetClock);
// User per-beatmap offset will be applied to this final clock.
- finalClockSource = userBeatmapOffsetClock = new OffsetCorrectionClock(userGlobalOffsetClock, ExternalPauseFrequencyAdjust);
+ finalClockSource = userBeatmapOffsetClock = new OffsetCorrectionClock(userGlobalOffsetClock);
}
else
{
diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs
index c05831d043..6b2cb4ee74 100644
--- a/osu.Game/Configuration/OsuConfigManager.cs
+++ b/osu.Game/Configuration/OsuConfigManager.cs
@@ -142,6 +142,7 @@ namespace osu.Game.Configuration
SetDefault(OsuSetting.FadePlayfieldWhenHealthLow, true);
SetDefault(OsuSetting.KeyOverlay, false);
SetDefault(OsuSetting.ReplaySettingsOverlay, true);
+ SetDefault(OsuSetting.ReplayPlaybackControlsExpanded, true);
SetDefault(OsuSetting.GameplayLeaderboard, true);
SetDefault(OsuSetting.AlwaysPlayFirstComboBreak, true);
@@ -421,6 +422,7 @@ namespace osu.Game.Configuration
ProfileCoverExpanded,
EditorLimitedDistanceSnap,
ReplaySettingsOverlay,
+ ReplayPlaybackControlsExpanded,
AutomaticallyDownloadMissingBeatmaps,
EditorShowSpeedChanges,
TouchDisableGameplayTaps,
diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs
index 1a78c1ec5e..d7bfeb7731 100644
--- a/osu.Game/Graphics/Backgrounds/Triangles.cs
+++ b/osu.Game/Graphics/Backgrounds/Triangles.cs
@@ -15,7 +15,6 @@ using osu.Framework.Graphics.Primitives;
using osu.Framework.Allocation;
using System.Collections.Generic;
using osu.Framework.Graphics.Rendering;
-using osu.Framework.Graphics.Rendering.Vertices;
using osu.Framework.Lists;
using osu.Framework.Bindables;
@@ -79,9 +78,9 @@ namespace osu.Game.Graphics.Backgrounds
///
/// If enabled, only the portion of triangles that falls within this 's
- /// shape is drawn to the screen.
+ /// shape is drawn to the screen. Default is true.
///
- public bool Masking { get; set; }
+ public bool ClampToDrawable { get; set; } = true;
///
/// Whether we should drop-off alpha values of triangles more quickly to improve
@@ -258,13 +257,12 @@ namespace osu.Game.Graphics.Backgrounds
private IShader shader;
private Texture texture;
- private bool masking;
+ private bool clamp;
private readonly List parts = new List();
private readonly Vector2 triangleSize = new Vector2(1f, equilateral_triangle_ratio) * triangle_size;
private Vector2 size;
- private IVertexBatch vertexBatch;
public TrianglesDrawNode(Triangles source)
: base(source)
@@ -278,7 +276,7 @@ namespace osu.Game.Graphics.Backgrounds
shader = Source.shader;
texture = Source.texture;
size = Source.DrawSize;
- masking = Source.Masking;
+ clamp = Source.ClampToDrawable;
parts.Clear();
parts.AddRange(Source.parts);
@@ -290,12 +288,6 @@ namespace osu.Game.Graphics.Backgrounds
{
base.Draw(renderer);
- if (Source.AimCount > 0 && (vertexBatch == null || vertexBatch.Size != Source.AimCount))
- {
- vertexBatch?.Dispose();
- vertexBatch = renderer.CreateQuadBatch(Source.AimCount, 1);
- }
-
borderDataBuffer ??= renderer.CreateUniformBuffer();
borderDataBuffer.Data = borderDataBuffer.Data with
{
@@ -314,7 +306,7 @@ namespace osu.Game.Graphics.Backgrounds
Vector2 topLeft = particle.Position - new Vector2(relativeSize.X * 0.5f, 0f);
- Quad triangleQuad = masking ? clampToDrawable(topLeft, relativeSize) : new Quad(topLeft.X, topLeft.Y, relativeSize.X, relativeSize.Y);
+ Quad triangleQuad = clamp ? clampToDrawable(topLeft, relativeSize) : new Quad(topLeft.X, topLeft.Y, relativeSize.X, relativeSize.Y);
var drawQuad = new Quad(
Vector2Extensions.Transform(triangleQuad.TopLeft * size, DrawInfo.Matrix),
@@ -333,7 +325,7 @@ namespace osu.Game.Graphics.Backgrounds
triangleQuad.Height
) / relativeSize;
- renderer.DrawQuad(texture, drawQuad, colourInfo, new RectangleF(0, 0, 1, 1), vertexBatch.AddAction, textureCoords: textureCoords);
+ renderer.DrawQuad(texture, drawQuad, colourInfo, new RectangleF(0, 0, 1, 1), textureCoords: textureCoords);
}
shader.Unbind();
@@ -356,7 +348,6 @@ namespace osu.Game.Graphics.Backgrounds
{
base.Dispose(isDisposing);
- vertexBatch?.Dispose();
borderDataBuffer?.Dispose();
}
}
diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs
index a20fd78569..f723b1b358 100644
--- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs
+++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs
@@ -10,7 +10,6 @@ using osu.Framework.Graphics.Primitives;
using osu.Framework.Allocation;
using System.Collections.Generic;
using osu.Framework.Graphics.Rendering;
-using osu.Framework.Graphics.Rendering.Vertices;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -35,9 +34,9 @@ namespace osu.Game.Graphics.Backgrounds
///
/// If enabled, only the portion of triangles that falls within this 's
- /// shape is drawn to the screen.
+ /// shape is drawn to the screen. Default is true.
///
- public bool Masking { get; set; }
+ public bool ClampToDrawable { get; set; } = true;
private readonly BindableFloat spawnRatio = new BindableFloat(1f);
@@ -194,9 +193,7 @@ namespace osu.Game.Graphics.Backgrounds
private Vector2 size;
private float thickness;
private float texelSize;
- private bool masking;
-
- private IVertexBatch? vertexBatch;
+ private bool clamp;
public TrianglesDrawNode(TrianglesV2 source)
: base(source)
@@ -211,7 +208,7 @@ namespace osu.Game.Graphics.Backgrounds
texture = Source.texture;
size = Source.DrawSize;
thickness = Source.Thickness;
- masking = Source.Masking;
+ clamp = Source.ClampToDrawable;
Quad triangleQuad = new Quad(
Vector2Extensions.Transform(Vector2.Zero, DrawInfo.Matrix),
@@ -235,12 +232,6 @@ namespace osu.Game.Graphics.Backgrounds
if (Source.AimCount == 0 || thickness == 0)
return;
- if (vertexBatch == null || vertexBatch.Size != Source.AimCount)
- {
- vertexBatch?.Dispose();
- vertexBatch = renderer.CreateQuadBatch(Source.AimCount, 1);
- }
-
borderDataBuffer ??= renderer.CreateUniformBuffer();
borderDataBuffer.Data = borderDataBuffer.Data with
{
@@ -257,7 +248,7 @@ namespace osu.Game.Graphics.Backgrounds
{
Vector2 topLeft = particle.Position - new Vector2(relativeSize.X * 0.5f, 0f);
- Quad triangleQuad = masking ? clampToDrawable(topLeft, relativeSize) : new Quad(topLeft.X, topLeft.Y, relativeSize.X, relativeSize.Y);
+ Quad triangleQuad = clamp ? clampToDrawable(topLeft, relativeSize) : new Quad(topLeft.X, topLeft.Y, relativeSize.X, relativeSize.Y);
var drawQuad = new Quad(
Vector2Extensions.Transform(triangleQuad.TopLeft * size, DrawInfo.Matrix),
@@ -273,7 +264,7 @@ namespace osu.Game.Graphics.Backgrounds
triangleQuad.Height
) / relativeSize;
- renderer.DrawQuad(texture, drawQuad, DrawColourInfo.Colour.Interpolate(triangleQuad), new RectangleF(0, 0, 1, 1), vertexBatch.AddAction, textureCoords: textureCoords);
+ renderer.DrawQuad(texture, drawQuad, DrawColourInfo.Colour.Interpolate(triangleQuad), new RectangleF(0, 0, 1, 1), textureCoords: textureCoords);
}
shader.Unbind();
@@ -296,7 +287,6 @@ namespace osu.Game.Graphics.Backgrounds
{
base.Dispose(isDisposing);
- vertexBatch?.Dispose();
borderDataBuffer?.Dispose();
}
}
diff --git a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs
index 7722374c69..63ac84fcf7 100644
--- a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs
+++ b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs
@@ -4,7 +4,6 @@
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Effects;
using osuTK;
namespace osu.Game.Graphics.Containers
@@ -17,21 +16,9 @@ namespace osu.Game.Graphics.Containers
public Drawable Icon
{
get => InternalChild;
-
set => InternalChild = value;
}
- ///
- /// Determines an edge effect of this .
- /// Edge effects are e.g. glow or a shadow.
- /// Only has an effect when is true.
- ///
- public new EdgeEffectParameters EdgeEffect
- {
- get => base.EdgeEffect;
- set => base.EdgeEffect = value;
- }
-
protected override void Update()
{
base.Update();
@@ -49,10 +36,5 @@ namespace osu.Game.Graphics.Containers
InternalChild.Origin = Anchor.Centre;
}
}
-
- public ConstrainedIconContainer()
- {
- Masking = true;
- }
}
}
diff --git a/osu.Game/Graphics/UserInterface/DialogButton.cs b/osu.Game/Graphics/UserInterface/DialogButton.cs
index c920597a95..10aca017f1 100644
--- a/osu.Game/Graphics/UserInterface/DialogButton.cs
+++ b/osu.Game/Graphics/UserInterface/DialogButton.cs
@@ -150,6 +150,7 @@ namespace osu.Game.Graphics.UserInterface
TriangleScale = 4,
ColourDark = OsuColour.Gray(0.88f),
Shear = new Vector2(-0.2f, 0),
+ ClampToDrawable = false
},
},
},
diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs
index 5a39c02185..436334cfe1 100644
--- a/osu.Game/Input/Bindings/GlobalActionContainer.cs
+++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs
@@ -170,6 +170,8 @@ namespace osu.Game.Input.Bindings
new KeyBinding(InputKey.MouseMiddle, GlobalAction.TogglePauseReplay),
new KeyBinding(InputKey.Left, GlobalAction.SeekReplayBackward),
new KeyBinding(InputKey.Right, GlobalAction.SeekReplayForward),
+ new KeyBinding(InputKey.Comma, GlobalAction.StepReplayBackward),
+ new KeyBinding(InputKey.Period, GlobalAction.StepReplayForward),
new KeyBinding(new[] { InputKey.Control, InputKey.H }, GlobalAction.ToggleReplaySettings),
};
@@ -411,7 +413,13 @@ namespace osu.Game.Input.Bindings
IncreaseOffset,
[LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.DecreaseOffset))]
- DecreaseOffset
+ DecreaseOffset,
+
+ [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.StepReplayForward))]
+ StepReplayForward,
+
+ [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.StepReplayBackward))]
+ StepReplayBackward,
}
public enum GlobalActionCategory
diff --git a/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs b/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs
index ca27d0ff95..703e0ff1ca 100644
--- a/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs
+++ b/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs
@@ -324,6 +324,16 @@ namespace osu.Game.Localisation
///
public static LocalisableString SeekReplayBackward => new TranslatableString(getKey(@"seek_replay_backward"), @"Seek replay backward");
+ ///
+ /// "Seek replay forward one frame"
+ ///
+ public static LocalisableString StepReplayForward => new TranslatableString(getKey(@"step_replay_forward"), @"Seek replay forward one frame");
+
+ ///
+ /// "Step replay backward one frame"
+ ///
+ public static LocalisableString StepReplayBackward => new TranslatableString(getKey(@"step_replay_backward"), @"Step replay backward one frame");
+
///
/// "Toggle chat focus"
///
diff --git a/osu.Game/Localisation/PlayerSettingsOverlayStrings.cs b/osu.Game/Localisation/PlayerSettingsOverlayStrings.cs
index 1aedd9fc5b..60874da561 100644
--- a/osu.Game/Localisation/PlayerSettingsOverlayStrings.cs
+++ b/osu.Game/Localisation/PlayerSettingsOverlayStrings.cs
@@ -9,6 +9,16 @@ namespace osu.Game.Localisation
{
private const string prefix = @"osu.Game.Resources.Localisation.PlaybackSettings";
+ ///
+ /// "Step backward one frame"
+ ///
+ public static LocalisableString StepBackward => new TranslatableString(getKey(@"step_backward_frame"), @"Step backward one frame");
+
+ ///
+ /// "Step forward one frame"
+ ///
+ public static LocalisableString StepForward => new TranslatableString(getKey(@"step_forward_frame"), @"Step forward one frame");
+
///
/// "Seek backward {0} seconds"
///
diff --git a/osu.Game/Online/API/Requests/Responses/APIUpdateStream.cs b/osu.Game/Online/API/Requests/Responses/APIUpdateStream.cs
index 76d1941d9d..dac72f2488 100644
--- a/osu.Game/Online/API/Requests/Responses/APIUpdateStream.cs
+++ b/osu.Game/Online/API/Requests/Responses/APIUpdateStream.cs
@@ -28,6 +28,9 @@ namespace osu.Game.Online.API.Requests.Responses
[JsonProperty("latest_build")]
public APIChangelogBuild LatestBuild { get; set; }
+ [JsonProperty("user_count")]
+ public int UserCount { get; set; }
+
public bool Equals(APIUpdateStream other) => Id == other?.Id;
internal static readonly Dictionary KNOWN_STREAMS = new Dictionary
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index 0d6eb1ea44..c244708385 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -80,6 +80,13 @@ namespace osu.Game
[Cached(typeof(OsuGame))]
public partial class OsuGame : OsuGameBase, IKeyBindingHandler, ILocalUserPlayInfo, IPerformFromScreenRunner, IOverlayManager, ILinkHandler
{
+#if DEBUG
+ // Different port allows runnning release and debug builds alongside each other.
+ public const int IPC_PORT = 44824;
+#else
+ public const int IPC_PORT = 44823;
+#endif
+
///
/// The amount of global offset to apply when a left/right anchored overlay is displayed (ie. settings or notifications).
///
diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs
index 08ea373fb1..30273d2405 100644
--- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs
+++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs
@@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Changelog
protected override LocalisableString AdditionalText => Value.LatestBuild.DisplayVersion;
- protected override LocalisableString InfoText => Value.LatestBuild.Users > 0 ? $"{"user".ToQuantity(Value.LatestBuild.Users, "N0")} online" : null;
+ protected override LocalisableString InfoText => Value.UserCount > 0 ? $"{"user".ToQuantity(Value.UserCount, "N0")} online" : null;
protected override Color4 GetBarColour(OsuColour colours) => Value.Colour;
}
diff --git a/osu.Game/Overlays/Mods/ModSelectColumn.cs b/osu.Game/Overlays/Mods/ModSelectColumn.cs
index 1c56763bd9..05454159c7 100644
--- a/osu.Game/Overlays/Mods/ModSelectColumn.cs
+++ b/osu.Game/Overlays/Mods/ModSelectColumn.cs
@@ -95,6 +95,7 @@ namespace osu.Game.Overlays.Mods
Height = header_height,
Shear = new Vector2(-ShearedOverlayContainer.SHEAR, 0),
Velocity = 0.7f,
+ ClampToDrawable = false
},
headerText = new OsuTextFlowContainer(t =>
{
diff --git a/osu.Game/Overlays/RevertToDefaultButton.cs b/osu.Game/Overlays/RevertToDefaultButton.cs
index 582138b0b4..6fa5209f64 100644
--- a/osu.Game/Overlays/RevertToDefaultButton.cs
+++ b/osu.Game/Overlays/RevertToDefaultButton.cs
@@ -115,7 +115,12 @@ namespace osu.Game.Overlays
Enabled.Value = !current.Disabled;
- this.FadeTo(current.Disabled ? 0.2f : (current.IsDefault ? 0 : 1), fade_duration, Easing.OutQuint);
+ if (current.IsDefault)
+ this.FadeTo(0, fade_duration, Easing.OutQuint);
+ else if (current.Disabled)
+ this.FadeTo(0.2f, fade_duration, Easing.OutQuint);
+ else
+ this.FadeTo(1, fade_duration, Easing.OutQuint);
if (IsHovered && Enabled.Value)
{
diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs
index c224f0f9c9..3287ac6eaa 100644
--- a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs
+++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs
@@ -4,7 +4,6 @@
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
@@ -58,15 +57,7 @@ namespace osu.Game.Overlays.Toolbar
{
set => Scheduler.AddOnce(() =>
{
- if (value)
- {
- IconContainer.Colour = Color4Extensions.FromHex("#00FFAA");
- }
- else
- {
- IconContainer.Colour = colours.GrayF;
- IconContainer.EdgeEffect = new EdgeEffectParameters();
- }
+ IconContainer.Colour = value ? Color4Extensions.FromHex("#00FFAA") : colours.GrayF;
});
}
diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs
index c07bd3aef5..8c9cb262af 100644
--- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs
+++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs
@@ -34,8 +34,6 @@ namespace osu.Game.Rulesets.UI
///
internal bool FrameStablePlayback { get; set; } = true;
- protected override bool RequiresChildrenUpdate => base.RequiresChildrenUpdate && state != PlaybackState.NotValid;
-
private readonly Bindable isCatchingUp = new Bindable();
private readonly Bindable waitingOnFrames = new Bindable();
@@ -126,7 +124,7 @@ namespace osu.Game.Rulesets.UI
// if waiting on frames, run one update loop to determine if frames have arrived.
state = PlaybackState.Valid;
}
- else if (IsPaused.Value)
+ else if (IsPaused.Value && !hasReplayAttached)
{
// time should not advance while paused, nor should anything run.
state = PlaybackState.NotValid;
diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
index 110beb0fa6..2d6e234e57 100644
--- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
@@ -114,7 +114,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
protected override bool OnMouseDown(MouseDownEvent e)
{
bool selectionPerformed = performMouseDownActions(e);
- bool movementPossible = prepareSelectionMovement();
+ bool movementPossible = prepareSelectionMovement(e);
// check if selection has occurred
if (selectionPerformed)
@@ -536,9 +536,13 @@ namespace osu.Game.Screens.Edit.Compose.Components
///
/// Attempts to begin the movement of any selected blueprints.
///
+ /// The defining the beginning of a movement.
/// Whether a movement is possible.
- private bool prepareSelectionMovement()
+ private bool prepareSelectionMovement(MouseDownEvent e)
{
+ if (e.Button == MouseButton.Right)
+ return false;
+
if (!SelectionHandler.SelectedBlueprints.Any())
return false;
diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs
index 4def1d36bb..c039d1e535 100644
--- a/osu.Game/Screens/Play/GameplayClockContainer.cs
+++ b/osu.Game/Screens/Play/GameplayClockContainer.cs
@@ -78,8 +78,6 @@ namespace osu.Game.Screens.Play
isPaused.Value = false;
- PrepareStart();
-
// The case which caused this to be added is FrameStabilityContainer, which manages its own current and elapsed time.
// Because we generally update our own current time quicker than children can query it (via Start/Seek/Update),
// this means that the first frame ever exposed to children may have a non-zero current time.
@@ -99,14 +97,6 @@ namespace osu.Game.Screens.Play
});
}
- ///
- /// When is called, this will be run to give an opportunity to prepare the clock at the correct
- /// start location.
- ///
- protected virtual void PrepareStart()
- {
- }
-
///
/// Seek to a specific time in gameplay.
///
diff --git a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs
index 0921a9f18a..1cf3d25dad 100644
--- a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs
+++ b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs
@@ -16,6 +16,7 @@ using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Framework.Threading;
using osu.Framework.Utils;
+using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
@@ -44,6 +45,8 @@ namespace osu.Game.Screens.Play.HUD
Direction = FillDirection.Horizontal;
Spacing = new Vector2(20, 0);
Margin = new MarginPadding(10);
+
+ AlwaysPresent = true;
}
[BackgroundDependencyLoader(true)]
@@ -66,9 +69,15 @@ namespace osu.Game.Screens.Play.HUD
Action = () => Action(),
}
};
+
AutoSizeAxes = Axes.Both;
}
+ [Resolved]
+ private SessionStatics sessionStatics { get; set; }
+
+ private Bindable touchActive;
+
protected override void LoadComplete()
{
button.HoldActivationDelay.BindValueChanged(v =>
@@ -78,7 +87,20 @@ namespace osu.Game.Screens.Play.HUD
: "press for menu";
}, true);
- text.FadeInFromZero(500, Easing.OutQuint).Delay(1500).FadeOut(500, Easing.OutQuint);
+ touchActive = sessionStatics.GetBindable(Static.TouchInputActive);
+
+ if (touchActive.Value)
+ {
+ Alpha = 1f;
+ text.FadeInFromZero(500, Easing.OutQuint)
+ .Delay(1500)
+ .FadeOut(500, Easing.OutQuint);
+ }
+ else
+ {
+ Alpha = 0;
+ text.Alpha = 0f;
+ }
base.LoadComplete();
}
@@ -99,9 +121,11 @@ namespace osu.Game.Screens.Play.HUD
Alpha = 1;
else
{
+ float minAlpha = touchActive.Value ? .08f : 0;
+
Alpha = Interpolation.ValueAt(
Math.Clamp(Clock.ElapsedFrameTime, 0, 200),
- Alpha, Math.Clamp(1 - positionalAdjust, 0.04f, 1), 0, 200, Easing.OutQuint);
+ Alpha, Math.Clamp(1 - positionalAdjust, minAlpha, 1), 0, 200, Easing.OutQuint);
}
}
diff --git a/osu.Game/Screens/Play/MasterGameplayClockContainer.cs b/osu.Game/Screens/Play/MasterGameplayClockContainer.cs
index 12f541167f..93bdcb1cab 100644
--- a/osu.Game/Screens/Play/MasterGameplayClockContainer.cs
+++ b/osu.Game/Screens/Play/MasterGameplayClockContainer.cs
@@ -7,7 +7,6 @@ using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables;
-using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
@@ -60,17 +59,6 @@ namespace osu.Game.Screens.Play
private readonly double skipTargetTime;
- ///
- /// Stores the time at which the last call was triggered.
- /// This is used to ensure we resume from that precise point in time, ignoring the proceeding frequency ramp.
- ///
- /// Optimally, we'd have gameplay ramp down with the frequency, but I believe this was intentionally disabled
- /// to avoid fails occurring after the pause screen has been shown.
- ///
- /// In the future I want to change this.
- ///
- internal double? LastStopTime;
-
[Resolved]
private MusicController musicController { get; set; } = null!;
@@ -113,71 +101,17 @@ namespace osu.Game.Screens.Play
return time;
}
- protected override void StopGameplayClock()
- {
- LastStopTime = GameplayClock.CurrentTime;
-
- if (IsLoaded)
- {
- // During normal operation, the source is stopped after performing a frequency ramp.
- this.TransformBindableTo(GameplayClock.ExternalPauseFrequencyAdjust, 0, 200, Easing.Out).OnComplete(_ =>
- {
- if (IsPaused.Value)
- base.StopGameplayClock();
- });
- }
- else
- {
- base.StopGameplayClock();
-
- // If not yet loaded, we still want to ensure relevant state is correct, as it is used for offset calculations.
- GameplayClock.ExternalPauseFrequencyAdjust.Value = 0;
-
- // We must also process underlying gameplay clocks to update rate-adjusted offsets with the new frequency adjustment.
- // Without doing this, an initial seek may be performed with the wrong offset.
- GameplayClock.ProcessFrame();
- }
- }
-
public override void Seek(double time)
{
- // Safety in case the clock is seeked while stopped.
- LastStopTime = null;
elapsedValidationTime = null;
base.Seek(time);
}
- protected override void PrepareStart()
- {
- if (LastStopTime != null)
- {
- Seek(LastStopTime.Value);
- LastStopTime = null;
- }
- else
- base.PrepareStart();
- }
-
protected override void StartGameplayClock()
{
addAdjustmentsToTrack();
-
base.StartGameplayClock();
-
- if (IsLoaded)
- {
- this.TransformBindableTo(GameplayClock.ExternalPauseFrequencyAdjust, 1, 200, Easing.In);
- }
- else
- {
- // If not yet loaded, we still want to ensure relevant state is correct, as it is used for offset calculations.
- GameplayClock.ExternalPauseFrequencyAdjust.Value = 1;
-
- // We must also process underlying gameplay clocks to update rate-adjusted offsets with the new frequency adjustment.
- // Without doing this, an initial seek may be performed with the wrong offset.
- GameplayClock.ProcessFrame();
- }
}
///
@@ -273,7 +207,6 @@ namespace osu.Game.Screens.Play
musicController.ResetTrackAdjustments();
track.BindAdjustments(AdjustmentsFromMods);
- track.AddAdjustment(AdjustableProperty.Frequency, GameplayClock.ExternalPauseFrequencyAdjust);
track.AddAdjustment(AdjustableProperty.Frequency, UserPlaybackRate);
speedAdjustmentsApplied = true;
@@ -285,7 +218,6 @@ namespace osu.Game.Screens.Play
return;
track.UnbindAdjustments(AdjustmentsFromMods);
- track.RemoveAdjustment(AdjustableProperty.Frequency, GameplayClock.ExternalPauseFrequencyAdjust);
track.RemoveAdjustment(AdjustableProperty.Frequency, UserPlaybackRate);
speedAdjustmentsApplied = false;
diff --git a/osu.Game/Screens/Play/OffsetCorrectionClock.cs b/osu.Game/Screens/Play/OffsetCorrectionClock.cs
index 207980f45c..e83ed7e464 100644
--- a/osu.Game/Screens/Play/OffsetCorrectionClock.cs
+++ b/osu.Game/Screens/Play/OffsetCorrectionClock.cs
@@ -1,15 +1,12 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using osu.Framework.Bindables;
using osu.Framework.Timing;
namespace osu.Game.Screens.Play
{
public class OffsetCorrectionClock : FramedOffsetClock
{
- private readonly BindableDouble pauseRateAdjust;
-
private double offset;
public new double Offset
@@ -28,10 +25,9 @@ namespace osu.Game.Screens.Play
public double RateAdjustedOffset => base.Offset;
- public OffsetCorrectionClock(IClock source, BindableDouble pauseRateAdjust)
+ public OffsetCorrectionClock(IClock source)
: base(source)
{
- this.pauseRateAdjust = pauseRateAdjust;
}
public override void ProcessFrame()
@@ -42,12 +38,8 @@ namespace osu.Game.Screens.Play
private void updateOffset()
{
- // changing this during the pause transform effect will cause a potentially large offset to be suddenly applied as we approach zero rate.
- if (pauseRateAdjust.Value == 1)
- {
- // we always want to apply the same real-time offset, so it should be adjusted by the difference in playback rate (from realtime) to achieve this.
- base.Offset = Offset * Rate;
- }
+ // we always want to apply the same real-time offset, so it should be adjusted by the difference in playback rate (from realtime) to achieve this.
+ base.Offset = Offset * Rate;
}
}
}
diff --git a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs
index 44cfa8d811..b3d07421ed 100644
--- a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs
+++ b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs
@@ -1,19 +1,17 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
-using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Localisation;
using osu.Game.Screens.Edit.Timing;
using osuTK;
-using osu.Game.Localisation;
namespace osu.Game.Screens.Play.PlayerSettings
{
@@ -28,26 +26,28 @@ namespace osu.Game.Screens.Play.PlayerSettings
Precision = 0.01,
};
- private readonly PlayerSliderBar rateSlider;
+ private PlayerSliderBar rateSlider = null!;
- private readonly OsuSpriteText multiplierText;
+ private OsuSpriteText multiplierText = null!;
- private readonly BindableBool isPaused = new BindableBool();
+ private readonly IBindable isPaused = new BindableBool();
[Resolved]
- private GameplayClockContainer? gameplayClock { get; set; }
+ private ReplayPlayer replayPlayer { get; set; } = null!;
[Resolved]
- private GameplayState? gameplayState { get; set; }
+ private GameplayClockContainer gameplayClock { get; set; } = null!;
+
+ private IconButton pausePlay = null!;
public PlaybackSettings()
: base("playback")
{
- const double seek_amount = 5000;
- const double seek_fast_amount = 10000;
-
- IconButton play;
+ }
+ [BackgroundDependencyLoader]
+ private void load()
+ {
Children = new Drawable[]
{
new FillFlowContainer
@@ -71,50 +71,62 @@ namespace osu.Game.Screens.Play.PlayerSettings
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.Solid.FastBackward,
- Action = () => seek(-1, seek_fast_amount),
- TooltipText = PlayerSettingsOverlayStrings.SeekBackwardSeconds(seek_fast_amount / 1000),
+ Action = () => replayPlayer.SeekInDirection(-10),
+ TooltipText = PlayerSettingsOverlayStrings.SeekBackwardSeconds(10 * ReplayPlayer.BASE_SEEK_AMOUNT / 1000),
},
new SeekButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.Solid.Backward,
- Action = () => seek(-1, seek_amount),
- TooltipText = PlayerSettingsOverlayStrings.SeekBackwardSeconds(seek_amount / 1000),
+ Action = () => replayPlayer.SeekInDirection(-1),
+ TooltipText = PlayerSettingsOverlayStrings.SeekBackwardSeconds(ReplayPlayer.BASE_SEEK_AMOUNT / 1000),
},
- play = new IconButton
+ new SeekButton
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Icon = FontAwesome.Solid.StepBackward,
+ Action = () => replayPlayer.StepFrame(-1),
+ TooltipText = PlayerSettingsOverlayStrings.StepBackward,
+ },
+ pausePlay = new IconButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(1.4f),
IconScale = new Vector2(1.4f),
- Icon = FontAwesome.Regular.PlayCircle,
Action = () =>
{
- if (gameplayClock != null)
- {
- if (gameplayClock.IsRunning)
- gameplayClock.Stop();
- else
- gameplayClock.Start();
- }
+ if (gameplayClock.IsRunning)
+ gameplayClock.Stop();
+ else
+ gameplayClock.Start();
},
},
new SeekButton
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Icon = FontAwesome.Solid.StepForward,
+ Action = () => replayPlayer.StepFrame(1),
+ TooltipText = PlayerSettingsOverlayStrings.StepForward,
+ },
+ new SeekButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.Solid.Forward,
- Action = () => seek(1, seek_amount),
- TooltipText = PlayerSettingsOverlayStrings.SeekForwardSeconds(seek_amount / 1000),
+ Action = () => replayPlayer.SeekInDirection(1),
+ TooltipText = PlayerSettingsOverlayStrings.SeekForwardSeconds(ReplayPlayer.BASE_SEEK_AMOUNT / 1000),
},
new SeekButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.Solid.FastForward,
- Action = () => seek(1, seek_fast_amount),
- TooltipText = PlayerSettingsOverlayStrings.SeekForwardSeconds(seek_fast_amount / 1000),
+ Action = () => replayPlayer.SeekInDirection(10),
+ TooltipText = PlayerSettingsOverlayStrings.SeekForwardSeconds(10 * ReplayPlayer.BASE_SEEK_AMOUNT / 1000),
},
},
},
@@ -141,26 +153,6 @@ namespace osu.Game.Screens.Play.PlayerSettings
},
},
};
-
- isPaused.BindValueChanged(paused =>
- {
- if (!paused.NewValue)
- {
- play.TooltipText = ToastStrings.PauseTrack;
- play.Icon = FontAwesome.Regular.PauseCircle;
- }
- else
- {
- play.TooltipText = ToastStrings.PlayTrack;
- play.Icon = FontAwesome.Regular.PlayCircle;
- }
- }, true);
-
- void seek(int direction, double amount)
- {
- double target = Math.Clamp((gameplayClock?.CurrentTime ?? 0) + (direction * amount), 0, gameplayState?.Beatmap.GetLastObjectTime() ?? 0);
- gameplayClock?.Seek(target);
- }
}
protected override void LoadComplete()
@@ -168,8 +160,20 @@ namespace osu.Game.Screens.Play.PlayerSettings
base.LoadComplete();
rateSlider.Current.BindValueChanged(multiplier => multiplierText.Text = $"{multiplier.NewValue:0.00}x", true);
- if (gameplayClock != null)
- isPaused.BindTarget = gameplayClock.IsPaused;
+ isPaused.BindTo(gameplayClock.IsPaused);
+ isPaused.BindValueChanged(paused =>
+ {
+ if (!paused.NewValue)
+ {
+ pausePlay.TooltipText = ToastStrings.PauseTrack;
+ pausePlay.Icon = FontAwesome.Regular.PauseCircle;
+ }
+ else
+ {
+ pausePlay.TooltipText = ToastStrings.PlayTrack;
+ pausePlay.Icon = FontAwesome.Regular.PlayCircle;
+ }
+ }, true);
}
private partial class SeekButton : IconButton
diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs
index 805f907466..a26a2b9904 100644
--- a/osu.Game/Screens/Play/ReplayPlayer.cs
+++ b/osu.Game/Screens/Play/ReplayPlayer.cs
@@ -12,6 +12,7 @@ using osu.Framework.Bindables;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Beatmaps;
+using osu.Game.Configuration;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
@@ -22,8 +23,11 @@ using osu.Game.Users;
namespace osu.Game.Screens.Play
{
+ [Cached]
public partial class ReplayPlayer : Player, IKeyBindingHandler
{
+ public const double BASE_SEEK_AMOUNT = 1000;
+
private readonly Func, Score> createScore;
private readonly bool replayIsFailedScore;
@@ -52,7 +56,7 @@ namespace osu.Game.Screens.Play
}
[BackgroundDependencyLoader]
- private void load()
+ private void load(OsuConfigManager config)
{
if (!LoadedBeatmapSuccessfully)
return;
@@ -60,7 +64,7 @@ namespace osu.Game.Screens.Play
var playbackSettings = new PlaybackSettings
{
Depth = float.MaxValue,
- Expanded = { Value = false }
+ Expanded = { BindTarget = config.GetBindable(OsuSetting.ReplayPlaybackControlsExpanded) }
};
if (GameplayClockContainer is MasterGameplayClockContainer master)
@@ -92,16 +96,22 @@ namespace osu.Game.Screens.Play
public bool OnPressed(KeyBindingPressEvent e)
{
- const double keyboard_seek_amount = 5000;
-
switch (e.Action)
{
+ case GlobalAction.StepReplayBackward:
+ StepFrame(-1);
+ return true;
+
+ case GlobalAction.StepReplayForward:
+ StepFrame(1);
+ return true;
+
case GlobalAction.SeekReplayBackward:
- keyboardSeek(-1);
+ SeekInDirection(-1);
return true;
case GlobalAction.SeekReplayForward:
- keyboardSeek(1);
+ SeekInDirection(1);
return true;
case GlobalAction.TogglePauseReplay:
@@ -113,13 +123,28 @@ namespace osu.Game.Screens.Play
}
return false;
+ }
- void keyboardSeek(int direction)
- {
- double target = Math.Clamp(GameplayClockContainer.CurrentTime + direction * keyboard_seek_amount, 0, GameplayState.Beatmap.GetLastObjectTime());
+ public void StepFrame(int direction)
+ {
+ GameplayClockContainer.Stop();
- Seek(target);
- }
+ var frames = GameplayState.Score.Replay.Frames;
+
+ if (frames.Count == 0)
+ return;
+
+ GameplayClockContainer.Seek(direction < 0
+ ? (frames.LastOrDefault(f => f.Time < GameplayClockContainer.CurrentTime) ?? frames.First()).Time
+ : (frames.FirstOrDefault(f => f.Time > GameplayClockContainer.CurrentTime) ?? frames.Last()).Time
+ );
+ }
+
+ public void SeekInDirection(float amount)
+ {
+ double target = Math.Clamp(GameplayClockContainer.CurrentTime + amount * BASE_SEEK_AMOUNT, 0, GameplayState.Beatmap.GetLastObjectTime());
+
+ Seek(target);
}
public void OnReleased(KeyBindingReleaseEvent e)
diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs
index 4408634787..70ecde3858 100644
--- a/osu.Game/Screens/Select/BeatmapCarousel.cs
+++ b/osu.Game/Screens/Select/BeatmapCarousel.cs
@@ -868,7 +868,7 @@ namespace osu.Game.Screens.Select
{
var toDisplay = visibleItems.GetRange(displayedRange.first, displayedRange.last - displayedRange.first + 1);
- foreach (var panel in Scroll.Children)
+ foreach (var panel in Scroll)
{
Debug.Assert(panel.Item != null);
@@ -899,7 +899,7 @@ namespace osu.Game.Screens.Select
// Update externally controlled state of currently visible items (e.g. x-offset and opacity).
// This is a per-frame update on all drawable panels.
- foreach (DrawableCarouselItem item in Scroll.Children)
+ foreach (DrawableCarouselItem item in Scroll)
{
updateItem(item);
@@ -1094,7 +1094,7 @@ namespace osu.Game.Screens.Select
// to enter clamp-special-case mode where it animates completely differently to normal.
float scrollChange = scrollTarget.Value - Scroll.Current;
Scroll.ScrollTo(scrollTarget.Value, false);
- foreach (var i in Scroll.Children)
+ foreach (var i in Scroll)
i.Y += scrollChange;
break;
}
diff --git a/osu.Game/Skinning/GameplaySkinComponentLookup.cs b/osu.Game/Skinning/GameplaySkinComponentLookup.cs
index a44bf3a43d..ec159873f8 100644
--- a/osu.Game/Skinning/GameplaySkinComponentLookup.cs
+++ b/osu.Game/Skinning/GameplaySkinComponentLookup.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
-using System.Linq;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
@@ -28,8 +27,5 @@ namespace osu.Game.Skinning
protected virtual string RulesetPrefix => string.Empty;
protected virtual string ComponentName => Component.ToString();
-
- public string LookupName =>
- string.Join('/', new[] { "Gameplay", RulesetPrefix, ComponentName }.Where(s => !string.IsNullOrEmpty(s)));
}
}
diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs
index 10913e7369..cfa5f972d2 100644
--- a/osu.Game/Skinning/LegacySkin.cs
+++ b/osu.Game/Skinning/LegacySkin.cs
@@ -491,39 +491,30 @@ namespace osu.Game.Skinning
break;
}
- foreach (string name in getFallbackNames(componentName))
+ Texture? texture = null;
+ float ratio = 1;
+
+ if (AllowHighResolutionSprites)
{
- string lookupName = name;
- Texture? texture = null;
- float ratio = 1;
+ // some component names (especially user-controlled ones, like `HitX` in mania)
+ // may contain `@2x` scale specifications.
+ // stable happens to check for that and strip them, so do the same to match stable behaviour.
+ componentName = componentName.Replace(@"@2x", string.Empty);
- if (AllowHighResolutionSprites)
- {
- // some component names (especially user-controlled ones, like `HitX` in mania)
- // may contain `@2x` scale specifications.
- // stable happens to check for that and strip them, so do the same to match stable behaviour.
- lookupName = name.Replace(@"@2x", string.Empty);
+ string twoTimesFilename = $"{Path.ChangeExtension(componentName, null)}@2x{Path.GetExtension(componentName)}";
- string twoTimesFilename = $"{Path.ChangeExtension(lookupName, null)}@2x{Path.GetExtension(lookupName)}";
+ texture = Textures?.Get(twoTimesFilename, wrapModeS, wrapModeT);
- texture = Textures?.Get(twoTimesFilename, wrapModeS, wrapModeT);
+ if (texture != null)
ratio = 2;
- }
-
- if (texture == null)
- {
- ratio = 1;
- texture = Textures?.Get(lookupName, wrapModeS, wrapModeT);
- }
-
- if (texture == null)
- continue;
-
- texture.ScaleAdjust = ratio;
- return texture;
}
- return null;
+ texture ??= Textures?.Get(componentName, wrapModeS, wrapModeT);
+
+ if (texture != null)
+ texture.ScaleAdjust = ratio;
+
+ return texture;
}
public override ISample? GetSample(ISampleInfo sampleInfo)
@@ -534,7 +525,7 @@ namespace osu.Game.Skinning
lookupNames = getLegacyLookupNames(hitSample);
else
{
- lookupNames = sampleInfo.LookupNames.SelectMany(getFallbackNames);
+ lookupNames = sampleInfo.LookupNames.SelectMany(getFallbackSampleNames);
}
foreach (string lookup in lookupNames)
@@ -552,7 +543,7 @@ namespace osu.Game.Skinning
private IEnumerable getLegacyLookupNames(HitSampleInfo hitSample)
{
- var lookupNames = hitSample.LookupNames.SelectMany(getFallbackNames);
+ var lookupNames = hitSample.LookupNames.SelectMany(getFallbackSampleNames);
if (!UseCustomSampleBanks && !string.IsNullOrEmpty(hitSample.Suffix))
{
@@ -571,13 +562,13 @@ namespace osu.Game.Skinning
yield return hitSample.Name;
}
- private IEnumerable getFallbackNames(string componentName)
+ private IEnumerable getFallbackSampleNames(string name)
{
- // May be something like "Gameplay/osu/approachcircle" from lazer, or "Arrows/note1" from a user skin.
- yield return componentName;
+ // May be something like "Gameplay/normal-hitnormal" from lazer.
+ yield return name;
- // Fall back to using the last piece for components coming from lazer (e.g. "Gameplay/osu/approachcircle" -> "approachcircle").
- yield return componentName.Split('/').Last();
+ // Fall back to using the last piece for components coming from lazer (e.g. "Gameplay/normal-hitnormal" -> "normal-hitnormal").
+ yield return name.Split('/').Last();
}
}
}
diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs
index cefd51b2aa..fae9ec7f2e 100644
--- a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs
+++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs
@@ -129,7 +129,7 @@ namespace osu.Game.Storyboards.Drawables
// When reading from a skin, we match stables weird behaviour where `FrameCount` is ignored
// and resources are retrieved until the end of the animation.
- var skinTextures = skin.GetTextures(Path.GetFileNameWithoutExtension(Animation.Path)!, default, default, true, string.Empty, null, out _);
+ var skinTextures = skin.GetTextures(Path.ChangeExtension(Animation.Path, null), default, default, true, string.Empty, null, out _);
if (skinTextures.Length > 0)
{
diff --git a/osu.Game/Tests/CleanRunHeadlessGameHost.cs b/osu.Game/Tests/CleanRunHeadlessGameHost.cs
index f3c69201e2..00e5b38b1a 100644
--- a/osu.Game/Tests/CleanRunHeadlessGameHost.cs
+++ b/osu.Game/Tests/CleanRunHeadlessGameHost.cs
@@ -27,7 +27,7 @@ namespace osu.Game.Tests
[CallerMemberName] string callingMethodName = @"")
: base($"{callingMethodName}-{Guid.NewGuid()}", new HostOptions
{
- BindIPC = bindIPC,
+ IPCPort = bindIPC ? OsuGame.IPC_PORT : null,
}, bypassCleanup: bypassCleanupOnDispose, realtime: realtime)
{
this.bypassCleanupOnSetup = bypassCleanupOnSetup;
diff --git a/osu.Game/Tests/VisualTestRunner.cs b/osu.Game/Tests/VisualTestRunner.cs
index e04c71d193..1a9e03b2a4 100644
--- a/osu.Game/Tests/VisualTestRunner.cs
+++ b/osu.Game/Tests/VisualTestRunner.cs
@@ -12,7 +12,7 @@ namespace osu.Game.Tests
[STAThread]
public static int Main(string[] args)
{
- using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu-development", new HostOptions { BindIPC = true, }))
+ using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu-development"))
{
host.Run(new OsuTestBrowser());
return 0;
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index f33ddac66f..1b1abe3971 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -21,12 +21,12 @@
-
+
-
-
-
-
+
+
+
+
@@ -36,13 +36,13 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
+
-
-
-
+
+
+