diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs
index 9755c9f49f..00bdd07ded 100644
--- a/osu.Desktop/OsuGameDesktop.cs
+++ b/osu.Desktop/OsuGameDesktop.cs
@@ -150,9 +150,13 @@ namespace osu.Desktop
{
base.SetHost(host);
- var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
- if (iconStream != null)
- host.Window.SetIconFromStream(iconStream);
+ // Apple operating systems use a better icon provided via external assets.
+ if (!RuntimeInfo.IsApple)
+ {
+ var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
+ if (iconStream != null)
+ host.Window.SetIconFromStream(iconStream);
+ }
host.Window.Title = Name;
}
diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/Info.plist b/osu.Game.Rulesets.Catch.Tests.iOS/Info.plist
index f87043e1d1..a3b9dda48c 100644
--- a/osu.Game.Rulesets.Catch.Tests.iOS/Info.plist
+++ b/osu.Game.Rulesets.Catch.Tests.iOS/Info.plist
@@ -35,11 +35,9 @@
UIInterfaceOrientationLandscapeRight
UIInterfaceOrientationLandscapeLeft
- XSAppIconAssets
- Assets.xcassets/AppIcon.appiconset
UIApplicationSupportsIndirectInputEvents
CADisableMinimumFrameDurationOnPhone
-
\ No newline at end of file
+
diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/Info.plist b/osu.Game.Rulesets.Mania.Tests.iOS/Info.plist
index 740036309f..83cb8f2e8c 100644
--- a/osu.Game.Rulesets.Mania.Tests.iOS/Info.plist
+++ b/osu.Game.Rulesets.Mania.Tests.iOS/Info.plist
@@ -35,11 +35,9 @@
UIInterfaceOrientationLandscapeRight
UIInterfaceOrientationLandscapeLeft
- XSAppIconAssets
- Assets.xcassets/AppIcon.appiconset
UIApplicationSupportsIndirectInputEvents
CADisableMinimumFrameDurationOnPhone
-
\ No newline at end of file
+
diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/Info.plist b/osu.Game.Rulesets.Osu.Tests.iOS/Info.plist
index 7f489874e7..6f0ea84107 100644
--- a/osu.Game.Rulesets.Osu.Tests.iOS/Info.plist
+++ b/osu.Game.Rulesets.Osu.Tests.iOS/Info.plist
@@ -35,11 +35,9 @@
UIInterfaceOrientationLandscapeRight
UIInterfaceOrientationLandscapeLeft
- XSAppIconAssets
- Assets.xcassets/AppIcon.appiconset
UIApplicationSupportsIndirectInputEvents
CADisableMinimumFrameDurationOnPhone
-
\ No newline at end of file
+
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs
index 0d6b02a7d1..65ab6001c9 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs
@@ -1,7 +1,9 @@
// 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 System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
@@ -71,6 +73,8 @@ namespace osu.Game.Rulesets.Osu.Mods
}
}
+ public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModTargetPractice)).ToArray();
+
protected override void ApplySettings(BeatmapDifficulty difficulty)
{
base.ApplySettings(difficulty);
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs
index 368d76d1ba..fe45199ae4 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs
@@ -27,8 +27,10 @@ namespace osu.Game.Rulesets.Osu.Mods
public override LocalisableString Description => "Burn the notes into your memory.";
- //Alters the transforms of the approach circles, breaking the effects of these mods.
- public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModApproachDifferent), typeof(OsuModTransform), typeof(OsuModDepth) }).ToArray();
+ ///
+ /// Incompatible with all mods that directly modify or indirectly depend on , or alter the behaviour of approach circles.
+ ///
+ public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModApproachDifferent), typeof(OsuModTransform), typeof(OsuModDepth), typeof(OsuModHidden) }).ToArray();
public override ModType Type => ModType.Fun;
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs
index 6dc0d5d522..c9b5fb29f7 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs
@@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override LocalisableString Description => @"Play with no approach circles and fading circles/sliders.";
public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.06 : 1;
- public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModDepth) };
+ public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModDepth), typeof(OsuModFreezeFrame) };
public const double FADE_IN_DURATION_MULTIPLIER = 0.4;
public const double FADE_OUT_DURATION_MULTIPLIER = 0.3;
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs
index e82ec2fb10..22dcd5079a 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs
@@ -48,7 +48,8 @@ namespace osu.Game.Rulesets.Osu.Mods
typeof(OsuModSpunOut),
typeof(OsuModStrictTracking),
typeof(OsuModSuddenDeath),
- typeof(OsuModDepth)
+ typeof(OsuModDepth),
+ typeof(OsuModDifficultyAdjust),
}).ToArray();
[SettingSource("Seed", "Use a custom seed instead of a random one", SettingControlType = typeof(SettingsNumberBox))]
diff --git a/osu.Game.Rulesets.Taiko.Tests.iOS/Info.plist b/osu.Game.Rulesets.Taiko.Tests.iOS/Info.plist
index 162ee75c22..1ef6b69ff3 100644
--- a/osu.Game.Rulesets.Taiko.Tests.iOS/Info.plist
+++ b/osu.Game.Rulesets.Taiko.Tests.iOS/Info.plist
@@ -35,11 +35,9 @@
UIInterfaceOrientationLandscapeRight
UIInterfaceOrientationLandscapeLeft
- XSAppIconAssets
- Assets.xcassets/AppIcon.appiconset
UIApplicationSupportsIndirectInputEvents
CADisableMinimumFrameDurationOnPhone
-
\ No newline at end of file
+
diff --git a/osu.Game.Tests.iOS/Info.plist b/osu.Game.Tests.iOS/Info.plist
index d2d0583e46..e08b9bf6e6 100644
--- a/osu.Game.Tests.iOS/Info.plist
+++ b/osu.Game.Tests.iOS/Info.plist
@@ -35,8 +35,31 @@
UIInterfaceOrientationLandscapeRight
UIInterfaceOrientationLandscapeLeft
- XSAppIconAssets
- Assets.xcassets/AppIcon.appiconset
+ CFBundleIcons~ipad
+
+ CFBundlePrimaryIcon
+
+ CFBundleIconFiles
+
+ AppIcon60x60
+
+ CFBundleIconName
+ AppIcon
+
+
+ CFBundleIcons
+
+ CFBundlePrimaryIcon
+
+ CFBundleIconFiles
+
+ AppIcon60x60
+ AppIcon76x76
+
+ CFBundleIconName
+ AppIcon
+
+
UIApplicationSupportsIndirectInputEvents
CADisableMinimumFrameDurationOnPhone
diff --git a/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs b/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs
index 7a05a3da5c..b63c0a8196 100644
--- a/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs
+++ b/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs
@@ -4,6 +4,7 @@
#nullable disable
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -15,6 +16,7 @@ using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Tests.Beatmaps.IO;
using osu.Game.Tests.Visual;
@@ -34,6 +36,12 @@ namespace osu.Game.Tests.Beatmaps
private IBindable starDifficultyBindable;
+ [Resolved]
+ private BeatmapManager beatmapManager { get; set; }
+
+ [Resolved]
+ private BeatmapDifficultyCache actualDifficultyCache { get; set; }
+
[BackgroundDependencyLoader]
private void load(OsuGameBase osu)
{
@@ -55,6 +63,36 @@ namespace osu.Game.Tests.Beatmaps
AddUntilStep($"star difficulty -> {BASE_STARS}", () => starDifficultyBindable.Value.Stars == BASE_STARS);
}
+ [Test]
+ public void TestInvalidationFlow()
+ {
+ BeatmapInfo postEditBeatmapInfo = null;
+ BeatmapInfo preEditBeatmapInfo = null;
+
+ IBindable bindableDifficulty = null;
+
+ AddStep("get bindable stars", () =>
+ {
+ preEditBeatmapInfo = importedSet.Beatmaps.First();
+ bindableDifficulty = actualDifficultyCache.GetBindableDifficulty(preEditBeatmapInfo);
+ });
+
+ AddUntilStep("wait for stars retrieved", () => bindableDifficulty.Value.Stars, () => Is.GreaterThan(0));
+
+ AddStep("remove all hitobjects", () =>
+ {
+ var working = beatmapManager.GetWorkingBeatmap(preEditBeatmapInfo);
+
+ ((IList)working.Beatmap.HitObjects).Clear();
+
+ beatmapManager.Save(working.BeatmapInfo, working.Beatmap);
+ postEditBeatmapInfo = working.BeatmapInfo;
+ });
+
+ AddAssert("stars is now zero", () => actualDifficultyCache.GetDifficultyAsync(postEditBeatmapInfo).GetResultSafely()!.Value.Stars, () => Is.Zero);
+ AddUntilStep("bindable stars is now zero", () => bindableDifficulty.Value.Stars, () => Is.Zero);
+ }
+
[Test]
public void TestStarDifficultyChangesOnModSettings()
{
@@ -122,8 +160,10 @@ namespace osu.Game.Tests.Beatmaps
[Test]
public void TestKeyDoesntEqualWithDifferentModSettings()
{
- var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.1 } } });
- var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.9 } } });
+ var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 },
+ new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.1 } } });
+ var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 },
+ new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.9 } } });
Assert.That(key1, Is.Not.EqualTo(key2));
Assert.That(key1.GetHashCode(), Is.Not.EqualTo(key2.GetHashCode()));
@@ -132,8 +172,10 @@ namespace osu.Game.Tests.Beatmaps
[Test]
public void TestKeyEqualWithMatchingModSettings()
{
- var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
- var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
+ var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 },
+ new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
+ var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 },
+ new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
Assert.That(key1, Is.EqualTo(key2));
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
diff --git a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs
index 4ef484cb67..291239e350 100644
--- a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs
+++ b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs
@@ -75,6 +75,10 @@ namespace osu.Game.Beatmaps
currentMods.BindValueChanged(mods =>
{
+ // A change in bindable here doesn't guarantee that mods have actually changed.
+ if (mods.OldValue.SequenceEqual(mods.NewValue))
+ return;
+
modSettingChangeTracker?.Dispose();
Scheduler.AddOnce(updateTrackedBindables);
@@ -82,15 +86,37 @@ namespace osu.Game.Beatmaps
modSettingChangeTracker = new ModSettingChangeTracker(mods.NewValue);
modSettingChangeTracker.SettingChanged += _ =>
{
- debouncedModSettingsChange?.Cancel();
- debouncedModSettingsChange = Scheduler.AddDelayed(updateTrackedBindables, 100);
+ lock (bindableUpdateLock)
+ {
+ debouncedModSettingsChange?.Cancel();
+ debouncedModSettingsChange = Scheduler.AddDelayed(updateTrackedBindables, 100);
+ }
};
}, true);
}
- public void Invalidate(IBeatmapInfo beatmap)
+ ///
+ /// Notify this cache that a beatmap has been invalidated/updated.
+ ///
+ /// The old beatmap model.
+ /// The updated beatmap model.
+ public void Invalidate(IBeatmapInfo oldBeatmap, IBeatmapInfo newBeatmap)
{
- base.Invalidate(lookup => lookup.BeatmapInfo.Equals(beatmap));
+ base.Invalidate(lookup => lookup.BeatmapInfo.Equals(oldBeatmap));
+
+ lock (bindableUpdateLock)
+ {
+ bool trackedBindablesRefreshRequired = false;
+
+ foreach (var bsd in trackedBindables.Where(bsd => bsd.BeatmapInfo.Equals(oldBeatmap)))
+ {
+ bsd.BeatmapInfo = newBeatmap;
+ trackedBindablesRefreshRequired = true;
+ }
+
+ if (trackedBindablesRefreshRequired)
+ Scheduler.AddOnce(updateTrackedBindables);
+ }
}
///
@@ -195,6 +221,9 @@ namespace osu.Game.Beatmaps
{
lock (bindableUpdateLock)
{
+ debouncedModSettingsChange?.Cancel();
+ debouncedModSettingsChange = null;
+
trackedUpdateCancellationSource.Cancel();
trackedUpdateCancellationSource = new CancellationTokenSource();
@@ -348,7 +377,7 @@ namespace osu.Game.Beatmaps
private class BindableStarDifficulty : Bindable
{
- public readonly IBeatmapInfo BeatmapInfo;
+ public IBeatmapInfo BeatmapInfo;
public readonly CancellationToken CancellationToken;
public BindableStarDifficulty(IBeatmapInfo beatmapInfo, CancellationToken cancellationToken)
diff --git a/osu.Game/Beatmaps/BeatmapUpdater.cs b/osu.Game/Beatmaps/BeatmapUpdater.cs
index ff23bf1242..72c69393df 100644
--- a/osu.Game/Beatmaps/BeatmapUpdater.cs
+++ b/osu.Game/Beatmaps/BeatmapUpdater.cs
@@ -52,11 +52,11 @@ namespace osu.Game.Beatmaps
foreach (BeatmapInfo beatmap in beatmapSet.Beatmaps)
{
- difficultyCache.Invalidate(beatmap);
-
var working = workingBeatmapCache.GetWorkingBeatmap(beatmap);
- var ruleset = working.BeatmapInfo.Ruleset.CreateInstance();
+ difficultyCache.Invalidate(beatmap, working.BeatmapInfo);
+
+ var ruleset = working.BeatmapInfo.Ruleset.CreateInstance();
var calculator = ruleset.CreateDifficultyCalculator(working);
beatmap.StarRating = calculator.Calculate().StarRating;
diff --git a/osu.Game/Beatmaps/WorkingBeatmapCache.cs b/osu.Game/Beatmaps/WorkingBeatmapCache.cs
index 0bb61798dc..75f1bd2a07 100644
--- a/osu.Game/Beatmaps/WorkingBeatmapCache.cs
+++ b/osu.Game/Beatmaps/WorkingBeatmapCache.cs
@@ -4,6 +4,7 @@
#nullable disable
using System;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using JetBrains.Annotations;
@@ -104,6 +105,10 @@ namespace osu.Game.Beatmaps
beatmapInfo = beatmapInfo.Detach();
+ // If this ever gets hit, a request has arrived with an outdated BeatmapInfo.
+ // An outdated BeatmapInfo may contain a reference to a previous version of the beatmap's files on disk.
+ Debug.Assert(confirmFileHashIsUpToDate(beatmapInfo), "working beatmap returned with outdated path");
+
workingCache.Add(working = new BeatmapManagerWorkingBeatmap(beatmapInfo, this));
// best effort; may be higher than expected.
@@ -113,6 +118,12 @@ namespace osu.Game.Beatmaps
}
}
+ private bool confirmFileHashIsUpToDate(BeatmapInfo beatmapInfo)
+ {
+ string refetchPath = realm.Run(r => r.Find(beatmapInfo.ID)?.File?.File.Hash);
+ return refetchPath == null || refetchPath == beatmapInfo.File?.File.Hash;
+ }
+
#region IResourceStorageProvider
TextureStore IBeatmapResourceProvider.LargeTextureStore => largeTextureStore;
diff --git a/osu.Game/Localisation/EditorStrings.cs b/osu.Game/Localisation/EditorStrings.cs
index a9e151d3e5..d06aa4012c 100644
--- a/osu.Game/Localisation/EditorStrings.cs
+++ b/osu.Game/Localisation/EditorStrings.cs
@@ -19,6 +19,11 @@ namespace osu.Game.Localisation
///
public static LocalisableString WaveformOpacity => new TranslatableString(getKey(@"waveform_opacity"), @"Waveform opacity");
+ ///
+ /// "Show storyboard"
+ ///
+ public static LocalisableString ShowStoryboard => new TranslatableString(getKey(@"show_storyboard"), @"Show storyboard");
+
///
/// "Show hit markers"
///
diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs
index 991f10497d..2360febccb 100644
--- a/osu.Game/Screens/Edit/Editor.cs
+++ b/osu.Game/Screens/Edit/Editor.cs
@@ -424,7 +424,7 @@ namespace osu.Game.Screens.Edit
},
new OsuMenuItemSpacer(),
new BackgroundDimMenuItem(editorBackgroundDim),
- new ToggleMenuItem("Show storyboard")
+ new ToggleMenuItem(EditorStrings.ShowStoryboard)
{
State = { BindTarget = editorShowStoryboard },
},
diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/TeamDisplay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/TeamDisplay.cs
index 282430d744..1550cbb8df 100644
--- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/TeamDisplay.cs
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/TeamDisplay.cs
@@ -106,14 +106,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
clickableContent.TooltipText = "Change team";
}
- // reset to ensure samples don't play
- DisplayedTeam = null;
- updateState();
+ updateState(false);
}
- private void onRoomUpdated() => Scheduler.AddOnce(updateState);
+ private void onRoomUpdated() => Scheduler.AddOnce(() => updateState(true));
- private void updateState()
+ private void updateState(bool playSamples)
{
// we don't have a way of knowing when an individual user's state has updated, so just handle on RoomUpdated for now.
@@ -129,7 +127,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
// only play the sample if an already valid team changes to another valid team.
// this avoids playing a sound for each user if the match type is changed to/from a team mode.
- if (newTeam != null && DisplayedTeam != null)
+ if (playSamples && newTeam != null && DisplayedTeam != null)
sampleTeamSwap?.Play();
DisplayedTeam = newTeam;
diff --git a/osu.iOS/AppIcon60x60@2x.png b/osu.iOS/AppIcon60x60@2x.png
new file mode 100644
index 0000000000..ee8f3efcfb
Binary files /dev/null and b/osu.iOS/AppIcon60x60@2x.png differ
diff --git a/osu.iOS/AppIcon76x76@2x~ipad.png b/osu.iOS/AppIcon76x76@2x~ipad.png
new file mode 100644
index 0000000000..bd437f9384
Binary files /dev/null and b/osu.iOS/AppIcon76x76@2x~ipad.png differ
diff --git a/osu.iOS/Assets.car b/osu.iOS/Assets.car
new file mode 100644
index 0000000000..b87f48c6ea
Binary files /dev/null and b/osu.iOS/Assets.car differ
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
deleted file mode 100644
index 7b62835cdc..0000000000
Binary files a/osu.iOS/Assets.xcassets/AppIcon.appiconset/300076680-5cbe0121-ed68-414f-9ddc-dd993ac97e62.png and /dev/null differ
diff --git a/osu.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/osu.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
deleted file mode 100644
index 29df54b400..0000000000
--- a/osu.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "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/Contents.json b/osu.iOS/Assets.xcassets/Contents.json
deleted file mode 100644
index 4caf392f92..0000000000
--- a/osu.iOS/Assets.xcassets/Contents.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
\ No newline at end of file
diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist
index e002949177..8d9985d279 100644
--- a/osu.iOS/Info.plist
+++ b/osu.iOS/Info.plist
@@ -49,8 +49,31 @@
UIInterfaceOrientationLandscapeRight
UIInterfaceOrientationLandscapeLeft
- XSAppIconAssets
- Assets.xcassets/AppIcon.appiconset
+ CFBundleIcons~ipad
+
+ CFBundlePrimaryIcon
+
+ CFBundleIconFiles
+
+ AppIcon60x60
+
+ CFBundleIconName
+ AppIcon
+
+
+ CFBundleIcons
+
+ CFBundlePrimaryIcon
+
+ CFBundleIconFiles
+
+ AppIcon60x60
+ AppIcon76x76
+
+ CFBundleIconName
+ AppIcon
+
+
UTExportedTypeDeclarations
diff --git a/osu.iOS/osu.iOS.csproj b/osu.iOS/osu.iOS.csproj
index 3e8beddaa4..04c00b4c35 100644
--- a/osu.iOS/osu.iOS.csproj
+++ b/osu.iOS/osu.iOS.csproj
@@ -22,6 +22,11 @@
+
+
+
+
+