diff --git a/Directory.Build.props b/Directory.Build.props
index 734374c840..b08283f071 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -35,7 +35,7 @@
https://github.com/ppy/osu
Automated release.
ppy Pty Ltd
- Copyright (c) 2022 ppy Pty Ltd
+ Copyright (c) 2024 ppy Pty Ltd
osu game
diff --git a/LICENCE b/LICENCE
index d3e7537cef..3bb8b62d5d 100644
--- a/LICENCE
+++ b/LICENCE
@@ -1,4 +1,4 @@
-Copyright (c) 2022 ppy Pty Ltd .
+Copyright (c) 2024 ppy Pty Ltd .
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index d5dc0723af..d7e710f392 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ A few resources are available as starting points to getting involved and underst
- Detailed release changelogs are available on the [official osu! site](https://osu.ppy.sh/home/changelog/lazer).
- You can learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management).
-- Track our current efforts [towards full "ranked play" support](https://github.com/orgs/ppy/projects/13?query=is%3Aopen+sort%3Aupdated-desc).
+- Track our current efforts [towards improving the game](https://github.com/orgs/ppy/projects/7/views/6).
## Running osu!
diff --git a/Templates/osu.Game.Templates.csproj b/Templates/osu.Game.Templates.csproj
index b8c3ad373a..186a6093f5 100644
--- a/Templates/osu.Game.Templates.csproj
+++ b/Templates/osu.Game.Templates.csproj
@@ -1,4 +1,4 @@
-
+
Template
ppy.osu.Game.Templates
@@ -8,7 +8,7 @@
https://github.com/ppy/osu/blob/master/Templates
https://github.com/ppy/osu
Automated release.
- Copyright (c) 2022 ppy Pty Ltd
+ Copyright (c) 2024 ppy Pty Ltd
Templates to use when creating a ruleset for consumption in osu!.
dotnet-new;templates;osu
netstandard2.1
diff --git a/assets/lazer-nuget.png b/assets/lazer-nuget.png
index c2a587fdc2..fed2f45149 100644
Binary files a/assets/lazer-nuget.png and b/assets/lazer-nuget.png differ
diff --git a/assets/lazer.png b/assets/lazer.png
index 1e40e844cc..2ee44225bf 100644
Binary files a/assets/lazer.png and b/assets/lazer.png differ
diff --git a/osu.Android.props b/osu.Android.props
index a7376aa5a7..969fd52340 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -10,7 +10,7 @@
true
-
+
diff --git a/osu.Android/Resources/drawable/ic_launcher_background.xml b/osu.Android/Resources/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000000..1af30228ec
--- /dev/null
+++ b/osu.Android/Resources/drawable/ic_launcher_background.xml
@@ -0,0 +1,618 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/osu.Android/Resources/drawable/lazer.png b/osu.Android/Resources/drawable/lazer.png
deleted file mode 100644
index fc7aa8a092..0000000000
Binary files a/osu.Android/Resources/drawable/lazer.png and /dev/null differ
diff --git a/osu.Android/Resources/drawable/monochrome.xml b/osu.Android/Resources/drawable/monochrome.xml
new file mode 100644
index 0000000000..e12af03bfb
--- /dev/null
+++ b/osu.Android/Resources/drawable/monochrome.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
diff --git a/osu.Android/Resources/mipmap-anydpi-v26/ic_launcher.xml b/osu.Android/Resources/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000000..7133c9c861
--- /dev/null
+++ b/osu.Android/Resources/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/osu.Android/Resources/mipmap-hdpi/ic_launcher.png b/osu.Android/Resources/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000000..7870430484
Binary files /dev/null and b/osu.Android/Resources/mipmap-hdpi/ic_launcher.png differ
diff --git a/osu.Android/Resources/mipmap-hdpi/ic_launcher_foreground.png b/osu.Android/Resources/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000000..b2ec3e49da
Binary files /dev/null and b/osu.Android/Resources/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/osu.Android/Resources/mipmap-mdpi/ic_launcher.png b/osu.Android/Resources/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000000..2a01d8f781
Binary files /dev/null and b/osu.Android/Resources/mipmap-mdpi/ic_launcher.png differ
diff --git a/osu.Android/Resources/mipmap-mdpi/ic_launcher_foreground.png b/osu.Android/Resources/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000000..e22f256562
Binary files /dev/null and b/osu.Android/Resources/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/osu.Android/Resources/mipmap-xhdpi/ic_launcher.png b/osu.Android/Resources/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000..b5e1a9e379
Binary files /dev/null and b/osu.Android/Resources/mipmap-xhdpi/ic_launcher.png differ
diff --git a/osu.Android/Resources/mipmap-xhdpi/ic_launcher_foreground.png b/osu.Android/Resources/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000000..1cc3fa9072
Binary files /dev/null and b/osu.Android/Resources/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/osu.Android/Resources/mipmap-xxhdpi/ic_launcher.png b/osu.Android/Resources/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..8a37b0449e
Binary files /dev/null and b/osu.Android/Resources/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/osu.Android/Resources/mipmap-xxhdpi/ic_launcher_foreground.png b/osu.Android/Resources/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000000..1b856a31b2
Binary files /dev/null and b/osu.Android/Resources/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/osu.Android/Resources/mipmap-xxxhdpi/ic_launcher.png b/osu.Android/Resources/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..65751e15c9
Binary files /dev/null and b/osu.Android/Resources/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/osu.Android/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png b/osu.Android/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000000..05c6829a47
Binary files /dev/null and b/osu.Android/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/osu.Desktop/lazer.ico b/osu.Desktop/lazer.ico
old mode 100755
new mode 100644
index a6aa8abb9f..f84866b8e9
Binary files a/osu.Desktop/lazer.ico and b/osu.Desktop/lazer.ico differ
diff --git a/osu.Desktop/osu.nuspec b/osu.Desktop/osu.nuspec
index db58c325bd..3b7d6cbe79 100644
--- a/osu.Desktop/osu.nuspec
+++ b/osu.Desktop/osu.nuspec
@@ -7,11 +7,12 @@
ppy Pty Ltd
Dean Herbert
https://osu.ppy.sh/
- https://puu.sh/tYyXZ/9a01a5d1b0.ico
+ https://github.com/ppy/osu/blob/master/assets/lazer-nuget.png?raw=true
+ icon.png
false
A free-to-win rhythm game. Rhythm is just a *click* away!
testing
- Copyright (c) 2022 ppy Pty Ltd
+ Copyright (c) 2024 ppy Pty Ltd
en-AU
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs
index 95896c7c91..148cf79337 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs
@@ -215,8 +215,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
if (headCircleHitAction == null)
timeToAcceptAnyKeyAfter = null;
- var actions = slider.OsuActionInputManager?.PressedActions;
-
// if the head circle was hit with a specific key, tracking should only occur while that key is pressed.
if (headCircleHitAction != null && timeToAcceptAnyKeyAfter == null)
{
@@ -227,6 +225,20 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
timeToAcceptAnyKeyAfter = Time.Current;
}
+ if (slider.OsuActionInputManager == null)
+ return;
+
+ lastPressedActions.Clear();
+ bool validTrackingAction = false;
+
+ foreach (OsuAction action in slider.OsuActionInputManager.PressedActions)
+ {
+ if (isValidTrackingAction(action))
+ validTrackingAction = true;
+
+ lastPressedActions.Add(action);
+ }
+
Tracking =
// even in an edge case where current time has exceeded the slider's time, we may not have finished judging.
// we don't want to potentially update from Tracking=true to Tracking=false at this point.
@@ -234,11 +246,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
// in valid position range
&& isValidTrackingPosition
// valid action
- && (actions?.Any(isValidTrackingAction) ?? false);
-
- lastPressedActions.Clear();
- if (actions != null)
- lastPressedActions.AddRange(actions);
+ && validTrackingAction;
}
private OsuAction? getInitialHitAction() => slider.HeadCircle?.HitAction;
diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneInputDrum.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneInputDrum.cs
index 3c6319ddf9..900d6523cf 100644
--- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneInputDrum.cs
+++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneInputDrum.cs
@@ -30,8 +30,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Size = new Vector2(200),
- Child = new InputDrum()
+ Size = new Vector2(180f, 200f),
+ Child = new InputDrum
+ {
+ RelativeSizeAxes = Axes.Both,
+ }
}
});
}
diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs
index c89e2b727b..d1a8a048ed 100644
--- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs
+++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs
@@ -1,17 +1,19 @@
// 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 NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions.IEnumerableExtensions;
+using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Taiko.Beatmaps;
using osu.Game.Rulesets.Taiko.UI;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Tests.Visual;
+using osuTK;
namespace osu.Game.Rulesets.Taiko.Tests.Skinning
{
@@ -37,11 +39,14 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
Beatmap.Value.Track.Start();
});
- AddStep("Load playfield", () => SetContents(_ => new TaikoPlayfield
+ AddStep("Load playfield", () => SetContents(_ => new Container
{
- Height = 0.2f,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
+ RelativeSizeAxes = Axes.Both,
+ Size = new Vector2(2f, 1f),
+ Scale = new Vector2(0.5f),
+ Child = new TaikoPlayfieldAdjustmentContainer { Child = new TaikoPlayfield() },
}));
}
@@ -54,7 +59,20 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
[Test]
public void TestHeightChanges()
{
- AddRepeatStep("change height", () => this.ChildrenOfType().ForEach(p => p.Height = Math.Max(0.2f, (p.Height + 0.2f) % 1f)), 50);
+ int value = 0;
+
+ AddRepeatStep("change height", () =>
+ {
+ value = (value + 1) % 5;
+
+ this.ChildrenOfType().ForEach(p =>
+ {
+ var parent = (Container)p.Parent.AsNonNull();
+ parent.Scale = new Vector2(0.5f + 0.1f * value);
+ parent.Width = 1f / parent.Scale.X;
+ parent.Height = 0.5f / parent.Scale.Y;
+ });
+ }, 50);
}
[Test]
diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs
index 8b1a4f688c..329fff5b42 100644
--- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs
@@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
{
InternalChild = piece = new HitPiece
{
- Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.DEFAULT_HEIGHT)
+ Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.BASE_HEIGHT)
};
}
diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs
index b0919417a4..cd52398086 100644
--- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs
@@ -39,15 +39,15 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
{
headPiece = new HitPiece
{
- Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.DEFAULT_HEIGHT)
+ Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.BASE_HEIGHT)
},
lengthPiece = new LengthPiece
{
- Height = TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.DEFAULT_HEIGHT
+ Height = TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.BASE_HEIGHT
},
tailPiece = new HitPiece
{
- Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.DEFAULT_HEIGHT)
+ Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.BASE_HEIGHT)
}
};
}
diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs
index cdeaafde10..f63d6c2673 100644
--- a/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs
+++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs
@@ -16,9 +16,6 @@ namespace osu.Game.Rulesets.Taiko.Mods
{
var drawableTaikoRuleset = (DrawableTaikoRuleset)drawableRuleset;
drawableTaikoRuleset.LockPlayfieldAspectRange.Value = false;
-
- var playfield = (TaikoPlayfield)drawableRuleset.Playfield;
- playfield.ClassicHitTargetPosition.Value = true;
}
public void ApplyToDrawableHitObject(DrawableHitObject drawable)
diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs
index 733772e21f..64f2f4c18a 100644
--- a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs
+++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs
@@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
///
private Vector2 adjustSizeForPlayfieldAspectRatio(float size)
{
- return new Vector2(0, size * taikoPlayfield.DrawHeight / TaikoPlayfield.DEFAULT_HEIGHT);
+ return new Vector2(0, size * taikoPlayfield.Parent!.Scale.Y);
}
protected override void UpdateFlashlightSize(float size)
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs
index f7b7105bdc..f22c7bf017 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs
@@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon
public ArgonInputDrum()
{
- RelativeSizeAxes = Axes.Y;
+ RelativeSizeAxes = Axes.X;
}
[BackgroundDependencyLoader]
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs
index 60bacf6413..3eb4f6b8a6 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs
@@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
{
public DefaultInputDrum()
{
- RelativeSizeAxes = Axes.Y;
+ RelativeSizeAxes = Axes.X;
}
[BackgroundDependencyLoader]
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs
index 28415bb72a..838f172186 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs
@@ -7,6 +7,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
+using osu.Game.Rulesets.Taiko.UI;
using osu.Game.Skinning;
using osuTK;
@@ -17,22 +18,20 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
///
internal partial class LegacyInputDrum : Container
{
- private Container content = null!;
private LegacyHalfDrum left = null!;
private LegacyHalfDrum right = null!;
public LegacyInputDrum()
{
- RelativeSizeAxes = Axes.Y;
- AutoSizeAxes = Axes.X;
+ RelativeSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load(ISkinSource skin)
{
- Child = content = new Container
+ Child = new Container
{
- Size = new Vector2(180, 200),
+ RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new Sprite
@@ -65,33 +64,24 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
const float ratio = 1.6f;
// because the right half is flipped, we need to position using width - position to get the true "topleft" origin position
- float negativeScaleAdjust = content.Width / ratio;
+ const float negative_scale_adjust = TaikoPlayfield.INPUT_DRUM_WIDTH / ratio;
if (skin.GetConfig(SkinConfiguration.LegacySetting.Version)?.Value >= 2.1m)
{
left.Centre.Position = new Vector2(0, taiko_bar_y) * ratio;
- right.Centre.Position = new Vector2(negativeScaleAdjust - 56, taiko_bar_y) * ratio;
+ right.Centre.Position = new Vector2(negative_scale_adjust - 56, taiko_bar_y) * ratio;
left.Rim.Position = new Vector2(0, taiko_bar_y) * ratio;
- right.Rim.Position = new Vector2(negativeScaleAdjust - 56, taiko_bar_y) * ratio;
+ right.Rim.Position = new Vector2(negative_scale_adjust - 56, taiko_bar_y) * ratio;
}
else
{
left.Centre.Position = new Vector2(18, taiko_bar_y + 31) * ratio;
- right.Centre.Position = new Vector2(negativeScaleAdjust - 54, taiko_bar_y + 31) * ratio;
+ right.Centre.Position = new Vector2(negative_scale_adjust - 54, taiko_bar_y + 31) * ratio;
left.Rim.Position = new Vector2(8, taiko_bar_y + 23) * ratio;
- right.Rim.Position = new Vector2(negativeScaleAdjust - 53, taiko_bar_y + 23) * ratio;
+ right.Rim.Position = new Vector2(negative_scale_adjust - 53, taiko_bar_y + 23) * ratio;
}
}
- protected override void Update()
- {
- base.Update();
-
- // Relying on RelativeSizeAxes.Both + FillMode.Fit doesn't work due to the precise pixel layout requirements.
- // This is a bit ugly but makes the non-legacy implementations a lot cleaner to implement.
- content.Scale = new Vector2(DrawHeight / content.Size.Y);
- }
-
///
/// A half-drum. Contains one centre and one rim hit.
///
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs
index 492782f0d1..0b43f1c845 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs
@@ -5,7 +5,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
-using osu.Game.Rulesets.Taiko.UI;
using osu.Game.Skinning;
using osuTK;
@@ -13,47 +12,30 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
{
public partial class TaikoLegacyHitTarget : CompositeDrawable
{
- private Container content = null!;
-
[BackgroundDependencyLoader]
private void load(ISkinSource skin)
{
RelativeSizeAxes = Axes.Both;
- InternalChild = content = new Container
+ InternalChildren = new Drawable[]
{
- RelativeSizeAxes = Axes.Both,
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Children = new Drawable[]
+ new Sprite
{
- new Sprite
- {
- Texture = skin.GetTexture("approachcircle"),
- Scale = new Vector2(0.83f),
- Alpha = 0.47f, // eyeballed to match stable
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- },
- new Sprite
- {
- Texture = skin.GetTexture("taikobigcircle"),
- Scale = new Vector2(0.8f),
- Alpha = 0.22f, // eyeballed to match stable
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- },
- }
+ Texture = skin.GetTexture("approachcircle"),
+ Scale = new Vector2(0.83f),
+ Alpha = 0.47f, // eyeballed to match stable
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ },
+ new Sprite
+ {
+ Texture = skin.GetTexture("taikobigcircle"),
+ Scale = new Vector2(0.8f),
+ Alpha = 0.22f, // eyeballed to match stable
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ },
};
}
-
- protected override void Update()
- {
- base.Update();
-
- // Relying on RelativeSizeAxes.Both + FillMode.Fit doesn't work due to the precise pixel layout requirements.
- // This is a bit ugly but makes the non-legacy implementations a lot cleaner to implement.
- content.Scale = new Vector2(DrawHeight / TaikoPlayfield.DEFAULT_HEIGHT);
- }
}
}
diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
index 725857ed34..d0a8cf647d 100644
--- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
+++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
@@ -14,12 +14,6 @@ namespace osu.Game.Rulesets.Taiko.UI
///
internal partial class InputDrum : Container
{
- public InputDrum()
- {
- AutoSizeAxes = Axes.X;
- RelativeSizeAxes = Axes.Y;
- }
-
[BackgroundDependencyLoader]
private void load()
{
@@ -27,8 +21,7 @@ namespace osu.Game.Rulesets.Taiko.UI
{
new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.InputDrum), _ => new DefaultInputDrum())
{
- RelativeSizeAxes = Axes.Y,
- AutoSizeAxes = Axes.X,
+ RelativeSizeAxes = Axes.Both,
},
};
}
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
index 7e3ed7a4d4..0510f08068 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
@@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
-using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
@@ -21,21 +20,17 @@ using osu.Game.Rulesets.Taiko.Judgements;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Scoring;
using osu.Game.Skinning;
-using osuTK;
namespace osu.Game.Rulesets.Taiko.UI
{
public partial class TaikoPlayfield : ScrollingPlayfield
{
///
- /// Default height of a when inside a .
+ /// Base height of a when inside a .
///
- public const float DEFAULT_HEIGHT = 200;
+ public const float BASE_HEIGHT = 200;
- ///
- /// Whether the hit target should be nudged further towards the left area, matching the stable "classic" position.
- ///
- public Bindable ClassicHitTargetPosition = new BindableBool();
+ public const float INPUT_DRUM_WIDTH = 180f;
public Container UnderlayElements { get; private set; } = null!;
@@ -44,14 +39,12 @@ namespace osu.Game.Rulesets.Taiko.UI
private JudgementContainer judgementContainer = null!;
private ScrollingHitObjectContainer drumRollHitContainer = null!;
internal Drawable HitTarget = null!;
- private SkinnableDrawable mascot = null!;
private JudgementPooler judgementPooler = null!;
private readonly IDictionary explosionPools = new Dictionary();
private ProxyContainer topLevelHitContainer = null!;
private InputDrum inputDrum = null!;
- private Container rightArea = null!;
///
/// is purposefully not called on this to prevent i.e. being able to interact
@@ -59,19 +52,18 @@ namespace osu.Game.Rulesets.Taiko.UI
///
private BarLinePlayfield barLinePlayfield = null!;
- private Container barLineContent = null!;
- private Container hitObjectContent = null!;
- private Container overlayContent = null!;
-
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
+ const float hit_target_width = BASE_HEIGHT;
+ const float hit_target_offset = -24f;
+
inputDrum = new InputDrum
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
- AutoSizeAxes = Axes.X,
RelativeSizeAxes = Axes.Y,
+ Width = INPUT_DRUM_WIDTH,
};
InternalChildren = new[]
@@ -80,8 +72,8 @@ namespace osu.Game.Rulesets.Taiko.UI
new Container
{
Name = "Left overlay",
- RelativeSizeAxes = Axes.Both,
- FillMode = FillMode.Fit,
+ RelativeSizeAxes = Axes.Y,
+ Width = INPUT_DRUM_WIDTH,
BorderColour = colours.Gray0,
Children = new[]
{
@@ -89,7 +81,7 @@ namespace osu.Game.Rulesets.Taiko.UI
inputDrum.CreateProxy(),
}
},
- mascot = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Mascot), _ => Empty())
+ new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Mascot), _ => Empty())
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.TopLeft,
@@ -97,18 +89,19 @@ namespace osu.Game.Rulesets.Taiko.UI
RelativeSizeAxes = Axes.None,
Y = 0.2f
},
- rightArea = new Container
+ new Container
{
Name = "Right area",
RelativeSizeAxes = Axes.Both,
- RelativePositionAxes = Axes.Both,
+ Padding = new MarginPadding { Left = INPUT_DRUM_WIDTH },
Children = new Drawable[]
{
new Container
{
- Name = "Elements before hit objects",
- RelativeSizeAxes = Axes.Both,
- FillMode = FillMode.Fit,
+ Name = "Elements behind hit objects",
+ RelativeSizeAxes = Axes.Y,
+ Width = hit_target_width,
+ X = hit_target_offset,
Children = new[]
{
new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.KiaiGlow), _ => Empty())
@@ -125,10 +118,11 @@ namespace osu.Game.Rulesets.Taiko.UI
}
}
},
- barLineContent = new Container
+ new Container
{
Name = "Bar line content",
RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Left = hit_target_width / 2 + hit_target_offset },
Children = new Drawable[]
{
UnderlayElements = new Container
@@ -138,17 +132,19 @@ namespace osu.Game.Rulesets.Taiko.UI
barLinePlayfield = new BarLinePlayfield(),
}
},
- hitObjectContent = new Container
+ new Container
{
Name = "Masked hit objects content",
RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Left = hit_target_width / 2 + hit_target_offset },
Masking = true,
Child = HitObjectContainer,
},
- overlayContent = new Container
+ new Container
{
- Name = "Elements after hit objects",
+ Name = "Overlay content",
RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Left = hit_target_width / 2 + hit_target_offset },
Children = new Drawable[]
{
drumRollHitContainer = new DrumRollHitContainer(),
@@ -222,20 +218,6 @@ namespace osu.Game.Rulesets.Taiko.UI
topLevelHitContainer.Add(taikoObject.CreateProxiedContent());
}
- protected override void Update()
- {
- base.Update();
-
- // Padding is required to be updated for elements which are based on "absolute" X sized elements.
- // This is basically allowing for correct alignment as relative pieces move around them.
- rightArea.Padding = new MarginPadding { Left = inputDrum.Width };
- barLineContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 };
- hitObjectContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 };
- overlayContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 };
-
- mascot.Scale = new Vector2(DrawHeight / DEFAULT_HEIGHT);
- }
-
#region Pooling support
public override void Add(HitObject h)
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs
index 54608b77de..c10e505f50 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs
@@ -5,23 +5,33 @@ using System;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.UI;
+using osuTK;
namespace osu.Game.Rulesets.Taiko.UI
{
public partial class TaikoPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer
{
- private const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768;
-
public const float MAXIMUM_ASPECT = 16f / 9f;
public const float MINIMUM_ASPECT = 5f / 4f;
public readonly IBindable LockPlayfieldAspectRange = new BindableBool(true);
+ public TaikoPlayfieldAdjustmentContainer()
+ {
+ RelativeSizeAxes = Axes.X;
+ RelativePositionAxes = Axes.Y;
+ Height = TaikoPlayfield.BASE_HEIGHT;
+ }
+
protected override void Update()
{
base.Update();
- float height = default_relative_height;
+ const float base_relative_height = TaikoPlayfield.BASE_HEIGHT / 768;
+ // Matches stable, see https://github.com/peppy/osu-stable-reference/blob/7519cafd1823f1879c0d9c991ba0e5c7fd3bfa02/osu!/GameModes/Play/Rulesets/Taiko/RulesetTaiko.cs#L514
+ const float base_position = 135f / 480f;
+
+ float relativeHeight = base_relative_height;
// Players coming from stable expect to be able to change the aspect ratio regardless of the window size.
// We originally wanted to limit this more, but there was considerable pushback from the community.
@@ -33,19 +43,18 @@ namespace osu.Game.Rulesets.Taiko.UI
float currentAspect = Parent!.ChildSize.X / Parent!.ChildSize.Y;
if (currentAspect > MAXIMUM_ASPECT)
- height *= currentAspect / MAXIMUM_ASPECT;
+ relativeHeight *= currentAspect / MAXIMUM_ASPECT;
else if (currentAspect < MINIMUM_ASPECT)
- height *= currentAspect / MINIMUM_ASPECT;
+ relativeHeight *= currentAspect / MINIMUM_ASPECT;
}
// Limit the maximum relative height of the playfield to one-third of available area to avoid it masking out on extreme resolutions.
- height = Math.Min(height, 1f / 3f);
- Height = height;
+ relativeHeight = Math.Min(relativeHeight, 1f / 3f);
- // Position the taiko playfield exactly one playfield from the top of the screen, if there is enough space for it.
- // Note that the relative height cannot exceed one-third - if that limit is hit, the playfield will be exactly centered.
- RelativePositionAxes = Axes.Y;
- Y = height;
+ Y = base_position;
+
+ Scale = new Vector2(Math.Max((Parent!.ChildSize.Y / 768f) * (relativeHeight / base_relative_height), 1f));
+ Width = 1 / Scale.X;
}
}
}
diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs
index 706b05f5ad..4143a6d76d 100644
--- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs
+++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs
@@ -1,17 +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 osu.Framework.Utils;
-using osuTK;
using System;
-using osu.Framework.Graphics.Shaders;
-using osu.Framework.Graphics.Textures;
-using osu.Framework.Graphics.Primitives;
-using osu.Framework.Allocation;
using System.Collections.Generic;
-using osu.Framework.Graphics.Rendering;
+using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Primitives;
+using osu.Framework.Graphics.Rendering;
+using osu.Framework.Graphics.Shaders;
+using osu.Framework.Graphics.Textures;
+using osu.Framework.Utils;
+using osuTK;
namespace osu.Game.Graphics.Backgrounds
{
@@ -27,6 +27,8 @@ namespace osu.Game.Graphics.Backgrounds
public float Thickness { get; set; } = 0.02f; // No need for invalidation since it's happening in Update()
+ public float ScaleAdjust { get; set; } = 1;
+
///
/// Whether we should create new triangles as others expire.
///
@@ -106,7 +108,7 @@ namespace osu.Game.Graphics.Backgrounds
parts[i] = newParticle;
- float bottomPos = parts[i].Position.Y + triangle_size * equilateral_triangle_ratio / DrawHeight;
+ float bottomPos = parts[i].Position.Y + triangle_size * ScaleAdjust * equilateral_triangle_ratio / DrawHeight;
if (bottomPos < 0)
parts.RemoveAt(i);
}
@@ -149,7 +151,7 @@ namespace osu.Game.Graphics.Backgrounds
if (randomY)
{
// since triangles are drawn from the top - allow them to be positioned a bit above the screen
- float maxOffset = triangle_size * equilateral_triangle_ratio / DrawHeight;
+ float maxOffset = triangle_size * ScaleAdjust * equilateral_triangle_ratio / DrawHeight;
y = Interpolation.ValueAt(nextRandom(), -maxOffset, 1f, 0f, 1f);
}
@@ -188,7 +190,7 @@ namespace osu.Game.Graphics.Backgrounds
private readonly List parts = new List();
- private readonly Vector2 triangleSize = new Vector2(1f, equilateral_triangle_ratio) * triangle_size;
+ private Vector2 triangleSize;
private Vector2 size;
private float thickness;
@@ -209,6 +211,7 @@ namespace osu.Game.Graphics.Backgrounds
size = Source.DrawSize;
thickness = Source.Thickness;
clampAxes = Source.ClampAxes;
+ triangleSize = new Vector2(1f, equilateral_triangle_ratio) * triangle_size * Source.ScaleAdjust;
Quad triangleQuad = new Quad(
Vector2Extensions.Transform(Vector2.Zero, DrawInfo.Matrix),
diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs
index 75ef8be02e..25101730e7 100644
--- a/osu.Game/Screens/Menu/OsuLogo.cs
+++ b/osu.Game/Screens/Menu/OsuLogo.cs
@@ -10,6 +10,7 @@ using osu.Framework.Audio.Sample;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
@@ -31,15 +32,13 @@ namespace osu.Game.Screens.Menu
///
public partial class OsuLogo : BeatSyncedContainer
{
- public readonly Color4 OsuPink = Color4Extensions.FromHex(@"e967a1");
-
private const double transition_length = 300;
///
/// The osu! logo sprite has a shadow included in its texture.
/// This adjustment vector is used to match the precise edge of the border of the logo.
///
- public static readonly Vector2 SCALE_ADJUST = new Vector2(0.96f);
+ public static readonly Vector2 SCALE_ADJUST = new Vector2(0.94f);
private readonly Sprite logo;
private readonly CircularContainer logoContainer;
@@ -58,7 +57,7 @@ namespace osu.Game.Screens.Menu
private Sample sampleDownbeat;
private readonly Container colourAndTriangles;
- private readonly Triangles triangles;
+ private readonly TrianglesV2 triangles;
///
/// Return value decides whether the logo should play its own sample for the click action.
@@ -184,13 +183,16 @@ namespace osu.Game.Screens.Menu
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = OsuPink,
+ Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex(@"ff66ab"), Color4Extensions.FromHex(@"cc5289")),
},
- triangles = new Triangles
+ triangles = new TrianglesV2
{
- TriangleScale = 4,
- ColourLight = Color4Extensions.FromHex(@"ff7db7"),
- ColourDark = Color4Extensions.FromHex(@"de5b95"),
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Thickness = 0.009f,
+ ScaleAdjust = 3,
+ SpawnRatio = 1.4f,
+ Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex(@"ff66ab"), Color4Extensions.FromHex(@"b6346f")),
RelativeSizeAxes = Axes.Both,
},
}
diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs
index b5482f2a5b..32ebb82f15 100644
--- a/osu.Game/Screens/Play/HUDOverlay.cs
+++ b/osu.Game/Screens/Play/HUDOverlay.cs
@@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@@ -259,13 +258,12 @@ namespace osu.Game.Screens.Play
Vector2? highestBottomScreenSpace = null;
- // LINQ cast can be removed when IDrawable interface includes Anchor / RelativeSizeAxes.
- foreach (var element in mainComponents.Components.Cast())
+ foreach (var element in mainComponents.Components)
processDrawable(element);
if (rulesetComponents != null)
{
- foreach (var element in rulesetComponents.Components.Cast())
+ foreach (var element in rulesetComponents.Components)
processDrawable(element);
}
@@ -284,33 +282,36 @@ namespace osu.Game.Screens.Play
else
bottomRightElements.Y = 0;
- void processDrawable(Drawable element)
+ void processDrawable(ISerialisableDrawable element)
{
+ // Cast can be removed when IDrawable interface includes Anchor / RelativeSizeAxes.
+ Drawable drawable = (Drawable)element;
+
// for now align some top components with the bottom-edge of the lowest top-anchored hud element.
- if (element.Anchor.HasFlagFast(Anchor.y0))
+ if (drawable.Anchor.HasFlagFast(Anchor.y0))
{
// health bars are excluded for the sake of hacky legacy skins which extend the health bar to take up the full screen area.
if (element is LegacyHealthDisplay)
return;
- float bottom = element.ScreenSpaceDrawQuad.BottomRight.Y;
+ float bottom = drawable.ScreenSpaceDrawQuad.BottomRight.Y;
- bool isRelativeX = element.RelativeSizeAxes == Axes.X;
+ bool isRelativeX = drawable.RelativeSizeAxes == Axes.X;
- if (element.Anchor.HasFlagFast(Anchor.TopRight) || isRelativeX)
+ if (drawable.Anchor.HasFlagFast(Anchor.TopRight) || isRelativeX)
{
if (lowestTopScreenSpaceRight == null || bottom > lowestTopScreenSpaceRight.Value)
lowestTopScreenSpaceRight = bottom;
}
- if (element.Anchor.HasFlagFast(Anchor.TopLeft) || isRelativeX)
+ if (drawable.Anchor.HasFlagFast(Anchor.TopLeft) || isRelativeX)
{
if (lowestTopScreenSpaceLeft == null || bottom > lowestTopScreenSpaceLeft.Value)
lowestTopScreenSpaceLeft = bottom;
}
}
// and align bottom-right components with the top-edge of the highest bottom-anchored hud element.
- else if (element.Anchor.HasFlagFast(Anchor.BottomRight) || (element.Anchor.HasFlagFast(Anchor.y2) && element.RelativeSizeAxes == Axes.X))
+ else if (drawable.Anchor.HasFlagFast(Anchor.BottomRight) || (drawable.Anchor.HasFlagFast(Anchor.y2) && drawable.RelativeSizeAxes == Axes.X))
{
var topLeft = element.ScreenSpaceDrawQuad.TopLeft;
if (highestBottomScreenSpace == null || topLeft.Y < highestBottomScreenSpace.Value.Y)
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 1b1abe3971..6f71424130 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -36,8 +36,8 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 98e8b136e5..bbcabc6360 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -23,6 +23,6 @@
iossimulator-x64
-
+
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/300076680-5cbe0121-ed68-414f-9ddc-dd993ac97e62.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/300076680-5cbe0121-ed68-414f-9ddc-dd993ac97e62.png
new file mode 100644
index 0000000000..21f5f0f3a0
Binary files /dev/null and b/osu.iOS/Assets.xcassets/AppIcon.appiconset/300076680-5cbe0121-ed68-414f-9ddc-dd993ac97e62.png differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/osu.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
index af4b103867..29df54b400 100644
--- a/osu.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/osu.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -1 +1,14 @@
-{"images":[{"size":"20x20","idiom":"iphone","filename":"iPhoneNotification2x.png","scale":"2x"},{"size":"20x20","idiom":"iphone","filename":"iPhoneNotification3x.png","scale":"3x"},{"size":"29x29","idiom":"iphone","filename":"iPhoneSettings2x.png","scale":"2x"},{"size":"29x29","idiom":"iphone","filename":"iPhoneSettings3x.png","scale":"3x"},{"size":"40x40","idiom":"iphone","filename":"iPhoneSpotlight2x.png","scale":"2x"},{"size":"40x40","idiom":"iphone","filename":"iPhoneSpotlight3x.png","scale":"3x"},{"size":"60x60","idiom":"iphone","filename":"iPhoneApp2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"iPhoneApp3x.png","scale":"3x"},{"size":"20x20","idiom":"ipad","filename":"iPadNotification1x.png","scale":"1x"},{"size":"20x20","idiom":"ipad","filename":"iPadNotification2x.png","scale":"2x"},{"size":"29x29","idiom":"ipad","filename":"iPadSettings1x.png","scale":"1x"},{"size":"29x29","idiom":"ipad","filename":"iPadSettings2x.png","scale":"2x"},{"size":"40x40","idiom":"ipad","filename":"iPadSpotlight1x.png","scale":"1x"},{"size":"40x40","idiom":"ipad","filename":"iPadSpotlight2x.png","scale":"2x"},{"size":"76x76","idiom":"ipad","filename":"iPadApp1x.png","scale":"1x"},{"size":"76x76","idiom":"ipad","filename":"iPadApp2x.png","scale":"2x"},{"size":"83.5x83.5","idiom":"ipad","filename":"iPadProApp2x.png","scale":"2x"},{"size":"1024x1024","idiom":"ios-marketing","filename":"iOSAppStore.png","scale":"1x"}],"info":{"version":1,"author":"xcode"}}
\ No newline at end of file
+{
+ "images" : [
+ {
+ "filename" : "300076680-5cbe0121-ed68-414f-9ddc-dd993ac97e62.png",
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iOSAppStore.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iOSAppStore.png
deleted file mode 100644
index 0e8bb029bc..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iOSAppStore.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadApp1x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadApp1x.png
deleted file mode 100644
index 42fead2364..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadApp1x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadApp2x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadApp2x.png
deleted file mode 100644
index 785db50cb2..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadApp2x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadNotification1x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadNotification1x.png
deleted file mode 100644
index 8c483a0a7a..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadNotification1x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadNotification2x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadNotification2x.png
deleted file mode 100644
index a45b01b91c..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadNotification2x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadProApp2x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadProApp2x.png
deleted file mode 100644
index d2ba8f3a7e..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadProApp2x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadSettings1x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadSettings1x.png
deleted file mode 100644
index 43d577040e..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadSettings1x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadSettings2x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadSettings2x.png
deleted file mode 100644
index 1ebec1390b..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadSettings2x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadSpotlight1x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadSpotlight1x.png
deleted file mode 100644
index a45b01b91c..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadSpotlight1x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadSpotlight2x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadSpotlight2x.png
deleted file mode 100644
index 717603dd68..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPadSpotlight2x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneApp2x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneApp2x.png
deleted file mode 100644
index 6b61c09db5..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneApp2x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneApp3x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneApp3x.png
deleted file mode 100644
index 78ef8d12b7..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneApp3x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneNotification2x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneNotification2x.png
deleted file mode 100644
index a45b01b91c..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneNotification2x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneNotification3x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneNotification3x.png
deleted file mode 100644
index 46ddf1179d..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneNotification3x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneSettings2x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneSettings2x.png
deleted file mode 100644
index 1ebec1390b..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneSettings2x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneSettings3x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneSettings3x.png
deleted file mode 100644
index a8145f0246..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneSettings3x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneSpotlight2x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneSpotlight2x.png
deleted file mode 100644
index 717603dd68..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneSpotlight2x.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneSpotlight3x.png b/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneSpotlight3x.png
deleted file mode 100644
index 6b61c09db5..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/iPhoneSpotlight3x.png and /dev/null differ
diff --git a/osu.iOS/iTunesArtwork b/osu.iOS/iTunesArtwork
deleted file mode 100644
index 1939459992..0000000000
Binary files a/osu.iOS/iTunesArtwork and /dev/null differ
diff --git a/osu.iOS/iTunesArtwork@2x b/osu.iOS/iTunesArtwork@2x
deleted file mode 100644
index 0e8bb029bc..0000000000
Binary files a/osu.iOS/iTunesArtwork@2x and /dev/null differ