Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Beatmaps decodable as Skins #2253

Merged
merged 8 commits into from Mar 22, 2018
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 0 additions & 6 deletions osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs
Expand Up @@ -16,11 +16,7 @@ public class CatchBeatmapProcessor : BeatmapProcessor<CatchHitObject>
{
public override void PostProcess(Beatmap<CatchHitObject> beatmap)
{
if (beatmap.ComboColours.Count == 0)
return;

int index = 0;
int colourIndex = 0;

CatchHitObject lastObj = null;

Expand All @@ -31,11 +27,9 @@ public override void PostProcess(Beatmap<CatchHitObject> beatmap)
if (obj.NewCombo)
{
if (lastObj != null) lastObj.LastInCombo = true;
colourIndex = (colourIndex + 1) % beatmap.ComboColours.Count;
}

obj.IndexInBeatmap = index++;
obj.ComboColour = beatmap.ComboColours[colourIndex];

lastObj = obj;
}
Expand Down
6 changes: 0 additions & 6 deletions osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs
Expand Up @@ -14,22 +14,16 @@ public override void PostProcess(Beatmap<OsuHitObject> beatmap)
{
applyStacking(beatmap);

if (beatmap.ComboColours.Count == 0)
return;

int comboIndex = 0;
int colourIndex = 0;

foreach (var obj in beatmap.HitObjects)
{
if (obj.NewCombo)
{
comboIndex = 0;
colourIndex = (colourIndex + 1) % beatmap.ComboColours.Count;
}

obj.IndexInCurrentCombo = comboIndex++;
obj.ComboColour = beatmap.ComboColours[colourIndex];
}
}

Expand Down
3 changes: 2 additions & 1 deletion osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
Expand Up @@ -11,6 +11,7 @@
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.Timing;
using osu.Game.Skinning;

namespace osu.Game.Tests.Beatmaps.Formats
{
Expand Down Expand Up @@ -163,7 +164,7 @@ public void TestDecodeBeatmapTimingPoints()
[Test]
public void TestDecodeBeatmapColors()
{
var decoder = new LegacyBeatmapDecoder();
var decoder = new LegacySkinDecoder();
using (var resStream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
using (var stream = new StreamReader(resStream))
{
Expand Down
19 changes: 0 additions & 19 deletions osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs
Expand Up @@ -12,7 +12,6 @@
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Tests.Resources;
using OpenTK;
using OpenTK.Graphics;

namespace osu.Game.Tests.Beatmaps.Formats
{
Expand Down Expand Up @@ -89,24 +88,6 @@ public void TestDecodeDifficulty()
Assert.AreEqual(2, difficulty.SliderTickRate);
}

[Test]
public void TestDecodeColors()
{
var beatmap = decodeAsJson(normal);
Color4[] expected =
{
new Color4(142, 199, 255, 255),
new Color4(255, 128, 128, 255),
new Color4(128, 255, 255, 255),
new Color4(128, 255, 128, 255),
new Color4(255, 187, 255, 255),
new Color4(255, 177, 140, 255),
};
Assert.AreEqual(expected.Length, beatmap.ComboColours.Count);
for (int i = 0; i < expected.Length; i++)
Assert.AreEqual(expected[i], beatmap.ComboColours[i]);
}

[Test]
public void TestDecodeHitObjects()
{
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Tests/Visual/TestCasePlaySongSelect.cs
Expand Up @@ -68,7 +68,7 @@ private void load(OsuGameBase game)
IDatabaseContextFactory factory = new SingletonContextFactory(new OsuDbContext());

dependencies.Cache(rulesets = new RulesetStore(factory));
dependencies.Cache(manager = new BeatmapManager(storage, factory, rulesets, null)
dependencies.Cache(manager = new BeatmapManager(storage, factory, rulesets, null, null)
{
DefaultBeatmap = defaultBeatmap = game.Beatmap.Default
});
Expand Down
13 changes: 1 addition & 12 deletions osu.Game/Beatmaps/Beatmap.cs
@@ -1,37 +1,27 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

using OpenTK.Graphics;
using osu.Game.Beatmaps.Timing;
using osu.Game.Rulesets.Objects;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.IO.Serialization;
using Newtonsoft.Json;
using osu.Game.Beatmaps.Formats;
using osu.Game.IO.Serialization.Converters;

namespace osu.Game.Beatmaps
{
/// <summary>
/// A Beatmap containing converted HitObjects.
/// </summary>
public class Beatmap<T> : IJsonSerializable, IHasComboColours
public class Beatmap<T> : IJsonSerializable
where T : HitObject
{
public BeatmapInfo BeatmapInfo = new BeatmapInfo();
public ControlPointInfo ControlPointInfo = new ControlPointInfo();
public List<BreakPeriod> Breaks = new List<BreakPeriod>();

public List<Color4> ComboColours { get; set; } = new List<Color4>
{
new Color4(17, 136, 170, 255),
new Color4(102, 136, 0, 255),
new Color4(204, 102, 0, 255),
new Color4(121, 9, 13, 255)
};

[JsonIgnore]
public BeatmapMetadata Metadata => BeatmapInfo?.Metadata ?? BeatmapInfo?.BeatmapSet?.Metadata;

Expand All @@ -56,7 +46,6 @@ public Beatmap(Beatmap<T> original = null)
BeatmapInfo = original?.BeatmapInfo.DeepClone() ?? BeatmapInfo;
ControlPointInfo = original?.ControlPointInfo ?? ControlPointInfo;
Breaks = original?.Breaks ?? Breaks;
ComboColours = original?.ComboColours ?? ComboColours;
HitObjects = original?.HitObjects ?? HitObjects;

if (original == null && Metadata == null)
Expand Down
1 change: 0 additions & 1 deletion osu.Game/Beatmaps/BeatmapConverter.cs
Expand Up @@ -57,7 +57,6 @@ protected virtual Beatmap<T> ConvertBeatmap(Beatmap original)
beatmap.ControlPointInfo = original.ControlPointInfo;
beatmap.HitObjects = original.HitObjects.SelectMany(h => convert(h, original)).ToList();
beatmap.Breaks = original.Breaks;
beatmap.ComboColours = original.ComboColours;

return beatmap;
}
Expand Down
8 changes: 6 additions & 2 deletions osu.Game/Beatmaps/BeatmapManager.cs
Expand Up @@ -8,6 +8,7 @@
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Logging;
using osu.Framework.Platform;
Expand Down Expand Up @@ -55,14 +56,16 @@ public partial class BeatmapManager : ArchiveModelManager<BeatmapSetInfo, Beatma

private readonly APIAccess api;

private readonly AudioManager audioManager;

private readonly List<DownloadBeatmapSetRequest> currentDownloads = new List<DownloadBeatmapSetRequest>();

/// <summary>
/// Set a storage with access to an osu-stable install for import purposes.
/// </summary>
public Func<Storage> GetStableStorage { private get; set; }

public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, APIAccess api, IIpcHost importHost = null)
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, APIAccess api, AudioManager audioManager, IIpcHost importHost = null)
: base(storage, contextFactory, new BeatmapStore(contextFactory), importHost)
{
beatmaps = (BeatmapStore)ModelStore;
Expand All @@ -71,6 +74,7 @@ public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, R

this.rulesets = rulesets;
this.api = api;
this.audioManager = audioManager;
}

protected override void Populate(BeatmapSetInfo model, ArchiveReader archive)
Expand Down Expand Up @@ -217,7 +221,7 @@ public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo, WorkingBeatmap
if (beatmapInfo.Metadata == null)
beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata;

WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(Files.Store, beatmapInfo);
WorkingBeatmap working = new BeatmapManagerWorkingBeatmap(Files.Store, beatmapInfo, audioManager);

previous?.TransferTo(working);

Expand Down
22 changes: 21 additions & 1 deletion osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs
Expand Up @@ -4,12 +4,14 @@
using System;
using System.IO;
using System.Linq;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores;
using osu.Framework.Logging;
using osu.Game.Beatmaps.Formats;
using osu.Game.Graphics.Textures;
using osu.Game.Skinning;
using osu.Game.Storyboards;

namespace osu.Game.Beatmaps
Expand All @@ -19,11 +21,13 @@ public partial class BeatmapManager
protected class BeatmapManagerWorkingBeatmap : WorkingBeatmap
{
private readonly IResourceStore<byte[]> store;
private readonly AudioManager audioManager;

public BeatmapManagerWorkingBeatmap(IResourceStore<byte[]> store, BeatmapInfo beatmapInfo)
public BeatmapManagerWorkingBeatmap(IResourceStore<byte[]> store, BeatmapInfo beatmapInfo, AudioManager audioManager)
: base(beatmapInfo)
{
this.store = store;
this.audioManager = audioManager;
}

protected override Beatmap GetBeatmap()
Expand Down Expand Up @@ -100,6 +104,22 @@ protected override Storyboard GetStoryboard()

return storyboard;
}

protected override Skin GetSkin()
{
Skin skin;
try
{
skin = new LegacyBeatmapSkin(BeatmapInfo, store, audioManager);
}
catch (Exception e)
{
Logger.Error(e, "Skin failed to load");

This comment was marked as off-topic.

skin = new DefaultSkin();
}

return skin;
}
}
}
}
11 changes: 11 additions & 0 deletions osu.Game/Beatmaps/WorkingBeatmap.cs
Expand Up @@ -14,6 +14,7 @@
using System.IO;
using osu.Game.IO.Serialization;
using System.Diagnostics;
using osu.Game.Skinning;

namespace osu.Game.Beatmaps
{
Expand All @@ -40,6 +41,7 @@ protected WorkingBeatmap(BeatmapInfo beatmapInfo)
track = new AsyncLazy<Track>(populateTrack);
waveform = new AsyncLazy<Waveform>(populateWaveform);
storyboard = new AsyncLazy<Storyboard>(populateStoryboard);
skin = new AsyncLazy<Skin>(populateSkin);
}

/// <summary>
Expand All @@ -56,6 +58,7 @@ public void Save()
protected abstract Beatmap GetBeatmap();
protected abstract Texture GetBackground();
protected abstract Track GetTrack();
protected virtual Skin GetSkin() => new DefaultSkin();
protected virtual Waveform GetWaveform() => new Waveform();
protected virtual Storyboard GetStoryboard() => new Storyboard { BeatmapInfo = BeatmapInfo };

Expand Down Expand Up @@ -109,6 +112,13 @@ private Track populateTrack()

private Storyboard populateStoryboard() => GetStoryboard();

public bool SkinLoaded => skin.IsResultAvailable;
public Skin Skin => skin.Value.Result;
public async Task<Skin> GetSkinAsync() => await skin.Value;
private readonly AsyncLazy<Skin> skin;

private Skin populateSkin() => GetSkin();

public void TransferTo(WorkingBeatmap other)
{
if (track.IsResultAvailable && Track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo))
Expand All @@ -123,6 +133,7 @@ public virtual void Dispose()
if (BackgroundLoaded) Background?.Dispose();
if (WaveformLoaded) Waveform?.Dispose();
if (StoryboardLoaded) Storyboard?.Dispose();
if (SkinLoaded) Skin?.Dispose();
}

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions osu.Game/Database/IHasFiles.cs
Expand Up @@ -10,6 +10,8 @@ namespace osu.Game.Database
/// </summary>
/// <typeparam name="TFile">The model representing a file.</typeparam>
public interface IHasFiles<TFile>
where TFile : INamedFileInfo

{
List<TFile> Files { get; set; }
}
Expand Down
2 changes: 1 addition & 1 deletion osu.Game/OsuGameBase.cs
Expand Up @@ -113,7 +113,7 @@ private void load()

dependencies.Cache(RulesetStore = new RulesetStore(contextFactory));
dependencies.Cache(FileStore = new FileStore(contextFactory, Host.Storage));
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory, RulesetStore, api, Host));
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory, RulesetStore, api, Audio, Host));
dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, contextFactory, Host, BeatmapManager, RulesetStore));
dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory, RulesetStore));
dependencies.Cache(SettingsStore = new SettingsStore(contextFactory));
Expand Down
20 changes: 20 additions & 0 deletions osu.Game/Skinning/LegacyBeatmapSkin.cs
@@ -0,0 +1,20 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

using osu.Framework.Audio;
using osu.Framework.IO.Stores;
using osu.Game.Beatmaps;

namespace osu.Game.Skinning
{
public class LegacyBeatmapSkin : LegacySkin
{
public LegacyBeatmapSkin(BeatmapInfo beatmap, IResourceStore<byte[]> storage, AudioManager audioManager)
: base(createSkinInfo(beatmap), new LegacySkinResourceStore<BeatmapSetFileInfo>(beatmap.BeatmapSet, storage), audioManager, beatmap.Path)
{
}

private static SkinInfo createSkinInfo(BeatmapInfo beatmap) =>
new SkinInfo { Name = beatmap.ToString(), Creator = beatmap.Metadata.Author.ToString() };
}
}