From 16eaeeeec207a3471b228bbe72c4415bebd99ce9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 21 Feb 2018 17:26:34 +0900 Subject: [PATCH] Add basic sample skinning support --- .../Audio/DrumSampleMapping.cs | 4 ++-- osu.Game/Audio/SampleInfo.cs | 6 +++--- osu.Game/OsuGameBase.cs | 2 +- .../Objects/Drawables/DrawableHitObject.cs | 18 +++++++++++++----- osu.Game/Skinning/LegacySkin.cs | 18 ++++++++++++------ osu.Game/Skinning/SkinManager.cs | 8 ++++++-- 6 files changed, 37 insertions(+), 19 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs index 5493a5029b..85367b8bf6 100644 --- a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs +++ b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs @@ -29,8 +29,8 @@ namespace osu.Game.Rulesets.Taiko.Audio { mappings[s.Time] = new DrumSample { - Centre = s.GetSampleInfo().GetChannel(audio.Sample, "Taiko"), - Rim = s.GetSampleInfo(SampleInfo.HIT_CLAP).GetChannel(audio.Sample, "Taiko") + Centre = s.GetSampleInfo().GetChannel(audio.Sample.Get, "Taiko"), + Rim = s.GetSampleInfo(SampleInfo.HIT_CLAP).GetChannel(audio.Sample.Get, "Taiko") }; } } diff --git a/osu.Game/Audio/SampleInfo.cs b/osu.Game/Audio/SampleInfo.cs index e6f4a0b8d1..99d2da7ebc 100644 --- a/osu.Game/Audio/SampleInfo.cs +++ b/osu.Game/Audio/SampleInfo.cs @@ -14,16 +14,16 @@ namespace osu.Game.Audio public const string HIT_NORMAL = @"hitnormal"; public const string HIT_CLAP = @"hitclap"; - public SampleChannel GetChannel(SampleManager manager, string resourceNamespace = null) + public SampleChannel GetChannel(Func getChannel, string resourceNamespace = null) { SampleChannel channel = null; if (resourceNamespace != null) - channel = manager.Get($"Gameplay/{resourceNamespace}/{Bank}-{Name}"); + channel = getChannel($"Gameplay/{resourceNamespace}/{Bank}-{Name}"); // try without namespace as a fallback. if (channel == null) - channel = manager.Get($"Gameplay/{Bank}-{Name}"); + channel = getChannel($"Gameplay/{Bank}-{Name}"); if (channel != null) channel.Volume.Value = Volume / 100.0; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 94ed696e49..507c46da5a 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -106,7 +106,7 @@ namespace osu.Game runMigrations(); - dependencies.Cache(SkinManager = new SkinManager(Host.Storage, contextFactory, Host)); + dependencies.Cache(SkinManager = new SkinManager(Host.Storage, contextFactory, Host, Audio)); dependencies.Cache(API = new APIAccess { diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 2db02724ed..e6daf94656 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -17,6 +17,7 @@ using osu.Framework.Configuration; using OpenTK; using osu.Framework.Graphics.Primitives; using osu.Game.Rulesets.Scoring; +using osu.Game.Skinning; namespace osu.Game.Rulesets.Objects.Drawables { @@ -82,8 +83,10 @@ namespace osu.Game.Rulesets.Objects.Drawables HitObject = hitObject; } + private readonly Bindable skin = new Bindable(); + [BackgroundDependencyLoader] - private void load(AudioManager audio) + private void load(AudioManager audio, SkinManager skins) { var samples = GetSamples(); if (samples.Any()) @@ -101,12 +104,17 @@ namespace osu.Game.Rulesets.Objects.Drawables Volume = s.Volume > 0 ? s.Volume : HitObject.SampleControlPoint.SampleVolume }; - SampleChannel channel = localSampleInfo.GetChannel(audio.Sample, SampleNamespace); + void loadSamples(Skin skin) + { + SampleChannel channel = localSampleInfo.GetChannel(skin.GetSample, SampleNamespace) ?? localSampleInfo.GetChannel(audio.Sample.Get, SampleNamespace); - if (channel == null) - continue; + if (channel == null) return; - Samples.Add(channel); + Samples.Add(channel); + } + + skin.ValueChanged += loadSamples; + skin.BindTo(skins.CurrentSkin); } } } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 13821cd771..922f3c5cf2 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -2,7 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.IO; using System.Linq; +using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; @@ -17,20 +19,24 @@ namespace osu.Game.Skinning public SkinInfo SkinInfo; - public LegacySkin(SkinInfo skin, IResourceStore storage) + private readonly SampleManager samples; + + public LegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager) : base(skin.Name) { SkinInfo = skin; + + var audioStore = new ResourceStore(storage); + + samples = audioManager.GetSampleManager(audioStore); textures = new TextureStore(new RawTextureLoaderStore(storage)); } - private string getPathForFile(string filename) => SkinInfo.Files.First(f => string.Equals(f.Filename, filename, StringComparison.InvariantCultureIgnoreCase)).FileInfo.StoragePath; + private string getPathForFile(string filename) => SkinInfo.Files.FirstOrDefault(f => string.Equals(Path.GetFileNameWithoutExtension(f.Filename), filename, StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath; public override Drawable GetDrawableComponent(string componentName) { - var legacyComponentName = componentName.Split('/').Last(); - - var texture = textures.Get(getPathForFile(legacyComponentName)); + var texture = textures.Get(getPathForFile(componentName.Split('/').Last())); if (texture == null) return null; return new Sprite @@ -41,6 +47,6 @@ namespace osu.Game.Skinning }; } - public override SampleChannel GetSample(string sampleName) => null; + public override SampleChannel GetSample(string sampleName) => samples.Get(getPathForFile(sampleName.Split('/').Last())); } } diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index a3a5c84845..1bd6874b8f 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; +using osu.Framework.Audio; using osu.Framework.Configuration; using osu.Framework.Platform; using osu.Game.Database; @@ -12,6 +13,8 @@ namespace osu.Game.Skinning { public class SkinManager : ArchiveModelManager { + private readonly AudioManager audio; + public Bindable CurrentSkin = new Bindable(new DefaultSkin()); public override string[] HandledExtensions => new[] { ".osk" }; @@ -34,14 +37,15 @@ namespace osu.Game.Skinning /// A instance correlating to the provided . public Skin GetSkin(SkinInfo skinInfo) { - return new LegacySkin(skinInfo, Files.Store); + return new LegacySkin(skinInfo, Files.Store, audio); } private SkinStore store; - public SkinManager(Storage storage, DatabaseContextFactory contextFactory, IIpcHost importHost) + public SkinManager(Storage storage, DatabaseContextFactory contextFactory, IIpcHost importHost, AudioManager audio) : base(storage, contextFactory, new SkinStore(contextFactory, storage), importHost) { + this.audio = audio; } } }