1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 11:22:54 +08:00

Merge branch 'master' of github.com:ppy/osu into better-song-select

This commit is contained in:
Thomas Müller 2016-11-22 18:55:13 +01:00
commit b22762d0e1
12 changed files with 293 additions and 184 deletions

@ -1 +1 @@
Subproject commit f839a542eed0508c2e7eeb9ba86b5c7ba0620652 Subproject commit 1d43e1ed56421fbbefdf6c23dab8deeeaa0f592a

View File

@ -35,29 +35,31 @@ namespace osu.Game.Tests.Beatmaps.IO
public void TestImportWhenClosed() public void TestImportWhenClosed()
{ {
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
HeadlessGameHost host = new HeadlessGameHost(); using (HeadlessGameHost host = new HeadlessGameHost())
{
var osu = loadOsu(host); var osu = loadOsu(host);
osu.Dependencies.Get<BeatmapDatabase>().Import(osz_path); osu.Dependencies.Get<BeatmapDatabase>().Import(osz_path);
ensureLoaded(osu); ensureLoaded(osu);
}
} }
[Test] [Test]
public void TestImportOverIPC() public void TestImportOverIPC()
{ {
HeadlessGameHost host = new HeadlessGameHost("host", true); using (HeadlessGameHost host = new HeadlessGameHost("host", true))
HeadlessGameHost client = new HeadlessGameHost("client", true); using (HeadlessGameHost client = new HeadlessGameHost("client", true))
{
Assert.IsTrue(host.IsPrimaryInstance);
Assert.IsTrue(!client.IsPrimaryInstance);
Assert.IsTrue(host.IsPrimaryInstance); var osu = loadOsu(host);
Assert.IsTrue(!client.IsPrimaryInstance);
var osu = loadOsu(host); var importer = new BeatmapImporter(client);
if (!importer.Import(osz_path).Wait(1000))
Assert.Fail(@"IPC took too long to send");
var importer = new BeatmapImporter(client); ensureLoaded(osu, 10000);
if (!importer.Import(osz_path).Wait(1000)) }
Assert.Fail(@"IPC took too long to send");
ensureLoaded(osu, 10000);
} }
private OsuGameBase loadOsu(BasicGameHost host) private OsuGameBase loadOsu(BasicGameHost host)

View File

@ -26,12 +26,12 @@ namespace osu.Game.Beatmaps.Drawable
/// </summary> /// </summary>
public Action<BeatmapGroup, BeatmapInfo> SelectionChanged; public Action<BeatmapGroup, BeatmapInfo> SelectionChanged;
private BeatmapSetInfo beatmapSet;
public BeatmapSetHeader Header; public BeatmapSetHeader Header;
private BeatmapGroupState state; private BeatmapGroupState state;
public List<BeatmapPanel> BeatmapPanels; public List<BeatmapPanel> BeatmapPanels;
private WorkingBeatmap beatmap;
public BeatmapGroupState State public BeatmapGroupState State
{ {
@ -65,11 +65,11 @@ namespace osu.Game.Beatmaps.Drawable
} }
} }
public BeatmapGroup(BeatmapSetInfo beatmapSet, WorkingBeatmap working) public BeatmapGroup(WorkingBeatmap beatmap)
{ {
this.beatmapSet = beatmapSet; this.beatmap = beatmap;
Header = new BeatmapSetHeader(beatmapSet, working) Header = new BeatmapSetHeader(beatmap)
{ {
GainedSelection = headerGainedSelection, GainedSelection = headerGainedSelection,
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
@ -77,7 +77,7 @@ namespace osu.Game.Beatmaps.Drawable
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
}; };
BeatmapPanels = beatmapSet.Beatmaps.Select(b => new BeatmapPanel(b) BeatmapPanels = beatmap.BeatmapSetInfo.Beatmaps.Select(b => new BeatmapPanel(b)
{ {
GainedSelection = panelGainedSelection, GainedSelection = panelGainedSelection,
Anchor = Anchor.TopRight, Anchor = Anchor.TopRight,

View File

@ -14,107 +14,27 @@ using osu.Framework.Allocation;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Colour;
using osu.Framework;
namespace osu.Game.Beatmaps.Drawable namespace osu.Game.Beatmaps.Drawable
{ {
class BeatmapSetHeader : Panel class BeatmapSetHeader : Panel
{ {
public Action<BeatmapSetHeader> GainedSelection; public Action<BeatmapSetHeader> GainedSelection;
private BeatmapSetInfo beatmapSet;
private SpriteText title, artist; private SpriteText title, artist;
private OsuConfigManager config; private OsuConfigManager config;
private Bindable<bool> preferUnicode; private Bindable<bool> preferUnicode;
private WorkingBeatmap beatmap;
protected override void Selected()
{
base.Selected();
GainedSelection?.Invoke(this);
}
protected override void Deselected() public BeatmapSetHeader(WorkingBeatmap beatmap)
{
base.Deselected();
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
this.config = config;
preferUnicode = config.GetBindable<bool>(OsuConfig.ShowUnicode);
preferUnicode.ValueChanged += preferUnicode_changed;
preferUnicode_changed(preferUnicode, null);
}
private void preferUnicode_changed(object sender, EventArgs e)
{ {
title.Text = config.GetUnicodeString(beatmapSet.Metadata.Title, beatmapSet.Metadata.TitleUnicode); this.beatmap = beatmap;
artist.Text = config.GetUnicodeString(beatmapSet.Metadata.Artist, beatmapSet.Metadata.ArtistUnicode);
}
protected override void Dispose(bool isDisposing)
{
if (preferUnicode != null)
preferUnicode.ValueChanged -= preferUnicode_changed;
base.Dispose(isDisposing);
}
public BeatmapSetHeader(BeatmapSetInfo beatmapSet, WorkingBeatmap working)
{
this.beatmapSet = beatmapSet;
Children = new Framework.Graphics.Drawable[] Children = new Framework.Graphics.Drawable[]
{ {
new BufferedContainer new PanelBackground(beatmap)
{ {
CacheDrawnFrameBuffer = true,
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Children = new Framework.Graphics.Drawable[]
{
working.Background == null ? new Box{ RelativeSizeAxes = Axes.Both, Colour = new Color4(200, 200, 200, 255) } : new Sprite
{
Texture = working.Background,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(1366 / working.Background.Width * 0.6f),
},
new FlowContainer
{
Direction = FlowDirection.HorizontalOnly,
RelativeSizeAxes = Axes.Both,
// This makes the gradient not be perfectly horizontal, but diagonal at a ~40° angle
Shear = new Vector2(0.8f, 0),
Alpha = 0.5f,
Children = new[]
{
// The left half with no gradient applied
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Width = 0.4f,
},
// Piecewise-linear gradient with 3 segments to make it appear smoother
new Box
{
RelativeSizeAxes = Axes.Both,
ColourInfo = ColourInfo.GradientHorizontal(Color4.Black, new Color4(0f, 0f, 0f, 0.9f)),
Width = 0.05f,
},
new Box
{
RelativeSizeAxes = Axes.Both,
ColourInfo = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.9f), new Color4(0f, 0f, 0f, 0.1f)),
Width = 0.2f,
},
new Box
{
RelativeSizeAxes = Axes.Both,
ColourInfo = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.1f), new Color4(0, 0, 0, 0)),
Width = 0.05f,
},
}
},
}
}, },
new FlowContainer new FlowContainer
{ {
@ -126,7 +46,7 @@ namespace osu.Game.Beatmaps.Drawable
title = new SpriteText title = new SpriteText
{ {
Font = @"Exo2.0-BoldItalic", Font = @"Exo2.0-BoldItalic",
Text = beatmapSet.Metadata.Title, Text = beatmap.BeatmapSetInfo.Metadata.Title,
TextSize = 22, TextSize = 22,
Shadow = true, Shadow = true,
}, },
@ -134,7 +54,7 @@ namespace osu.Game.Beatmaps.Drawable
{ {
Margin = new MarginPadding { Top = -1 }, Margin = new MarginPadding { Top = -1 },
Font = @"Exo2.0-SemiBoldItalic", Font = @"Exo2.0-SemiBoldItalic",
Text = beatmapSet.Metadata.Artist, Text = beatmap.BeatmapSetInfo.Metadata.Artist,
TextSize = 17, TextSize = 17,
Shadow = true, Shadow = true,
}, },
@ -151,6 +71,125 @@ namespace osu.Game.Beatmaps.Drawable
} }
} }
}; };
}
protected override void Selected()
{
base.Selected();
GainedSelection?.Invoke(this);
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
this.config = config;
preferUnicode = config.GetBindable<bool>(OsuConfig.ShowUnicode);
preferUnicode.ValueChanged += preferUnicode_changed;
preferUnicode_changed(preferUnicode, null);
}
private void preferUnicode_changed(object sender, EventArgs e)
{
title.Text = config.GetUnicodeString(beatmap.BeatmapSetInfo.Metadata.Title, beatmap.BeatmapSetInfo.Metadata.TitleUnicode);
artist.Text = config.GetUnicodeString(beatmap.BeatmapSetInfo.Metadata.Artist, beatmap.BeatmapSetInfo.Metadata.ArtistUnicode);
}
protected override void Dispose(bool isDisposing)
{
if (preferUnicode != null)
preferUnicode.ValueChanged -= preferUnicode_changed;
base.Dispose(isDisposing);
}
class PanelBackground : BufferedContainer
{
private readonly WorkingBeatmap working;
public PanelBackground(WorkingBeatmap working)
{
this.working = working;
CacheDrawnFrameBuffer = true;
Children = new[]
{
new FlowContainer
{
Depth = 1,
Direction = FlowDirection.HorizontalOnly,
RelativeSizeAxes = Axes.Both,
// This makes the gradient not be perfectly horizontal, but diagonal at a ~40° angle
Shear = new Vector2(0.8f, 0),
Alpha = 0.5f,
Children = new[]
{
// The left half with no gradient applied
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
Width = 0.4f,
},
// Piecewise-linear gradient with 3 segments to make it appear smoother
new Box
{
RelativeSizeAxes = Axes.Both,
ColourInfo = ColourInfo.GradientHorizontal(Color4.Black, new Color4(0f, 0f, 0f, 0.9f)),
Width = 0.05f,
},
new Box
{
RelativeSizeAxes = Axes.Both,
ColourInfo = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.9f), new Color4(0f, 0f, 0f, 0.1f)),
Width = 0.2f,
},
new Box
{
RelativeSizeAxes = Axes.Both,
ColourInfo = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.1f), new Color4(0, 0, 0, 0)),
Width = 0.05f,
},
}
},
};
}
[BackgroundDependencyLoader]
private void load(OsuGameBase game)
{
//todo: masking check
new BeatmapBackground(working)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
}.Preload(game, (bg) =>
{
Add(bg);
ForceRedraw();
});
}
class BeatmapBackground : Sprite
{
private readonly WorkingBeatmap working;
public BeatmapBackground(WorkingBeatmap working)
{
this.working = working;
}
[BackgroundDependencyLoader]
private void load(OsuGameBase game)
{
Texture = working.Background;
}
protected override void LoadComplete()
{
base.LoadComplete();
Scale = new Vector2(1366 / (Texture?.Width ?? 1) * 0.6f);
}
}
} }
} }
} }

View File

@ -14,7 +14,7 @@ namespace osu.Game.Beatmaps.IO
public Func<BasicStorage, string, bool> Test { get; set; } public Func<BasicStorage, string, bool> Test { get; set; }
public Type Type { get; set; } public Type Type { get; set; }
} }
private static List<Reader> readers { get; } = new List<Reader>(); private static List<Reader> readers { get; } = new List<Reader>();
public static ArchiveReader GetReader(BasicStorage storage, string path) public static ArchiveReader GetReader(BasicStorage storage, string path)

View File

@ -18,7 +18,7 @@ namespace osu.Game.Beatmaps
public readonly BeatmapSetInfo BeatmapSetInfo; public readonly BeatmapSetInfo BeatmapSetInfo;
private readonly BeatmapDatabase database; private readonly BeatmapDatabase database;
private ArchiveReader reader => database?.GetReader(BeatmapSetInfo); private ArchiveReader GetReader() => database?.GetReader(BeatmapSetInfo);
private Texture background; private Texture background;
private object backgroundLock = new object(); private object backgroundLock = new object();
@ -32,7 +32,8 @@ namespace osu.Game.Beatmaps
try try
{ {
background = new TextureStore(new RawTextureLoaderStore(reader)).Get(BeatmapInfo.Metadata.BackgroundFile); using (var reader = GetReader())
background = new TextureStore(new RawTextureLoaderStore(reader), false).Get(BeatmapInfo.Metadata.BackgroundFile);
} }
catch { } catch { }
@ -54,6 +55,7 @@ namespace osu.Game.Beatmaps
try try
{ {
using (var reader = GetReader())
using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path))) using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path)))
beatmap = BeatmapDecoder.GetDecoder(stream)?.Decode(stream); beatmap = BeatmapDecoder.GetDecoder(stream)?.Decode(stream);
} }
@ -77,9 +79,12 @@ namespace osu.Game.Beatmaps
try try
{ {
var trackData = reader?.GetStream(BeatmapInfo.Metadata.AudioFile); using (var reader = GetReader())
if (trackData != null) {
track = new AudioTrackBass(trackData); var trackData = reader?.GetStream(BeatmapInfo.Metadata.AudioFile);
if (trackData != null)
track = new AudioTrackBass(trackData);
}
} }
catch { } catch { }
@ -89,6 +94,8 @@ namespace osu.Game.Beatmaps
set { lock (trackLock) track = value; } set { lock (trackLock) track = value; }
} }
public bool TrackLoaded => track != null;
public WorkingBeatmap(Beatmap beatmap) public WorkingBeatmap(Beatmap beatmap)
{ {
this.beatmap = beatmap; this.beatmap = beatmap;
@ -108,7 +115,7 @@ namespace osu.Game.Beatmaps
if (!isDisposed) if (!isDisposed)
{ {
track?.Dispose(); track?.Dispose();
reader?.Dispose(); background?.Dispose();
isDisposed = true; isDisposed = true;
} }
} }
@ -116,6 +123,7 @@ namespace osu.Game.Beatmaps
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);
GC.SuppressFinalize(this);
} }
public void TransferTo(WorkingBeatmap working) public void TransferTo(WorkingBeatmap working)

View File

@ -136,7 +136,7 @@ namespace osu.Game.Database
public BeatmapSetInfo GetBeatmapSet(int id) public BeatmapSetInfo GetBeatmapSet(int id)
{ {
return Query<BeatmapSetInfo>().Where(s => s.BeatmapSetID == id).FirstOrDefault(); return Query<BeatmapSetInfo>().FirstOrDefault(s => s.BeatmapSetID == id);
} }
public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo, WorkingBeatmap previous = null) public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo, WorkingBeatmap previous = null)
@ -144,7 +144,7 @@ namespace osu.Game.Database
var beatmapSetInfo = Query<BeatmapSetInfo>().FirstOrDefault(s => s.BeatmapSetID == beatmapInfo.BeatmapSetID); var beatmapSetInfo = Query<BeatmapSetInfo>().FirstOrDefault(s => s.BeatmapSetID == beatmapInfo.BeatmapSetID);
//we need metadata //we need metadata
GetChildren(beatmapSetInfo); GetChildren(beatmapSetInfo, false);
if (beatmapSetInfo == null) if (beatmapSetInfo == null)
throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetID} is not in the local database."); throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetID} is not in the local database.");
@ -175,10 +175,10 @@ namespace osu.Game.Database
return connection.GetWithChildren<T>(id); return connection.GetWithChildren<T>(id);
} }
public List<T> GetAllWithChildren<T>(Expression<Func<T, bool>> filter = null, public List<T> GetAllWithChildren<T>(Expression<Func<T, bool>> filter = null, bool recursive = true)
bool recursive = true) where T : class where T : class
{ {
return connection.GetAllWithChildren<T>(filter, recursive); return connection.GetAllWithChildren(filter, recursive);
} }
public T GetChildren<T>(T item, bool recursive = true) public T GetChildren<T>(T item, bool recursive = true)
@ -199,7 +199,7 @@ namespace osu.Game.Database
public void Update<T>(T record, bool cascade = true) where T : class public void Update<T>(T record, bool cascade = true) where T : class
{ {
if (!validTypes.Any(t => t == typeof(T))) if (validTypes.All(t => t != typeof(T)))
throw new ArgumentException(nameof(T), "Must be a type managed by BeatmapDatabase"); throw new ArgumentException(nameof(T), "Must be a type managed by BeatmapDatabase");
if (cascade) if (cascade)
connection.UpdateWithChildren(record); connection.UpdateWithChildren(record);

View File

@ -75,7 +75,7 @@ namespace osu.Game.Graphics.UserInterface.Volume
protected override bool OnWheel(InputState state) protected override bool OnWheel(InputState state)
{ {
Volume += 0.05f * state.Mouse.WheelDiff; Volume += 0.05f * state.Mouse.WheelDelta;
return true; return true;
} }

View File

@ -34,7 +34,6 @@ namespace osu.Game.Overlays
private DragBar progress; private DragBar progress;
private TextAwesome playButton, listButton; private TextAwesome playButton, listButton;
private SpriteText title, artist; private SpriteText title, artist;
private Texture fallbackTexture;
private List<BeatmapSetInfo> playList; private List<BeatmapSetInfo> playList;
private List<BeatmapInfo> playHistory = new List<BeatmapInfo>(); private List<BeatmapInfo> playHistory = new List<BeatmapInfo>();
@ -47,6 +46,7 @@ namespace osu.Game.Overlays
private OsuConfigManager config; private OsuConfigManager config;
private WorkingBeatmap current; private WorkingBeatmap current;
private BeatmapDatabase beatmaps; private BeatmapDatabase beatmaps;
private BaseGame game;
public MusicController() public MusicController()
{ {
@ -208,7 +208,7 @@ namespace osu.Game.Overlays
beatmapSource = osuGame.Beatmap ?? new Bindable<WorkingBeatmap>(); beatmapSource = osuGame.Beatmap ?? new Bindable<WorkingBeatmap>();
playList = beatmaps.GetAllWithChildren<BeatmapSetInfo>(); playList = beatmaps.GetAllWithChildren<BeatmapSetInfo>();
backgroundSprite = new MusicControllerBackground(fallbackTexture = textures.Get(@"Backgrounds/bg4")); backgroundSprite = new MusicControllerBackground();
AddInternal(backgroundSprite); AddInternal(backgroundSprite);
} }
@ -222,12 +222,15 @@ namespace osu.Game.Overlays
protected override void Update() protected override void Update()
{ {
base.Update(); base.Update();
if (current?.Track == null) return;
progress.UpdatePosition((float)(current.Track.CurrentTime / current.Track.Length)); if (current?.TrackLoaded ?? false)
playButton.Icon = current.Track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; {
if (current.Track.HasCompleted && !current.Track.Looping) next(); progress.UpdatePosition((float)(current.Track.CurrentTime / current.Track.Length));
playButton.Icon = current.Track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o;
if (current.Track.HasCompleted && !current.Track.Looping) next();
}
} }
void preferUnicode_changed(object sender, EventArgs e) void preferUnicode_changed(object sender, EventArgs e)
@ -304,36 +307,49 @@ namespace osu.Game.Overlays
updateDisplay(current, isNext ? TransformDirection.Next : TransformDirection.Prev); updateDisplay(current, isNext ? TransformDirection.Next : TransformDirection.Prev);
} }
protected override void PerformLoad(BaseGame game)
{
this.game = game;
base.PerformLoad(game);
}
private void updateDisplay(WorkingBeatmap beatmap, TransformDirection direction) private void updateDisplay(WorkingBeatmap beatmap, TransformDirection direction)
{ {
if (beatmap.Beatmap == null) Task.Run(() =>
//todo: we may need to display some default text here (currently in the constructor).
return;
BeatmapMetadata metadata = beatmap.Beatmap.BeatmapInfo.Metadata;
title.Text = config.GetUnicodeString(metadata.Title, metadata.TitleUnicode);
artist.Text = config.GetUnicodeString(metadata.Artist, metadata.ArtistUnicode);
MusicControllerBackground newBackground = new MusicControllerBackground(beatmap.Background ?? fallbackTexture);
Add(newBackground);
switch (direction)
{ {
case TransformDirection.Next: if (beatmap.Beatmap == null)
newBackground.Position = new Vector2(400, 0); //todo: we may need to display some default text here (currently in the constructor).
newBackground.MoveToX(0, 500, EasingTypes.OutCubic); return;
backgroundSprite.MoveToX(-400, 500, EasingTypes.OutCubic);
break;
case TransformDirection.Prev:
newBackground.Position = new Vector2(-400, 0);
newBackground.MoveToX(0, 500, EasingTypes.OutCubic);
backgroundSprite.MoveToX(400, 500, EasingTypes.OutCubic);
break;
}
backgroundSprite.Expire(); BeatmapMetadata metadata = beatmap.Beatmap.BeatmapInfo.Metadata;
backgroundSprite = newBackground; title.Text = config.GetUnicodeString(metadata.Title, metadata.TitleUnicode);
artist.Text = config.GetUnicodeString(metadata.Artist, metadata.ArtistUnicode);
});
MusicControllerBackground newBackground;
(newBackground = new MusicControllerBackground(beatmap)).Preload(game, delegate
{
Add(newBackground);
switch (direction)
{
case TransformDirection.Next:
newBackground.Position = new Vector2(400, 0);
newBackground.MoveToX(0, 500, EasingTypes.OutCubic);
backgroundSprite.MoveToX(-400, 500, EasingTypes.OutCubic);
break;
case TransformDirection.Prev:
newBackground.Position = new Vector2(-400, 0);
newBackground.MoveToX(0, 500, EasingTypes.OutCubic);
backgroundSprite.MoveToX(400, 500, EasingTypes.OutCubic);
break;
}
backgroundSprite.Expire();
backgroundSprite = newBackground;
});
} }
private void seek(float position) private void seek(float position)
@ -363,9 +379,11 @@ namespace osu.Game.Overlays
private class MusicControllerBackground : BufferedContainer private class MusicControllerBackground : BufferedContainer
{ {
private Sprite sprite; private Sprite sprite;
private WorkingBeatmap beatmap;
public MusicControllerBackground(Texture backgroundTexture) public MusicControllerBackground(WorkingBeatmap beatmap = null)
{ {
this.beatmap = beatmap;
CacheDrawnFrameBuffer = true; CacheDrawnFrameBuffer = true;
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
Depth = float.MinValue; Depth = float.MinValue;
@ -374,7 +392,6 @@ namespace osu.Game.Overlays
{ {
sprite = new Sprite sprite = new Sprite
{ {
Texture = backgroundTexture,
Colour = new Color4(150, 150, 150, 255) Colour = new Color4(150, 150, 150, 255)
}, },
new Box new Box
@ -388,6 +405,12 @@ namespace osu.Game.Overlays
}; };
} }
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4");
}
protected override void LoadComplete() protected override void LoadComplete()
{ {
base.LoadComplete(); base.LoadComplete();

View File

@ -1,9 +1,8 @@
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>. //Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using OpenTK; using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Transformations; using osu.Framework.Graphics.Transformations;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics.Background; using osu.Game.Graphics.Background;
@ -15,6 +14,7 @@ namespace osu.Game.Screens.Backgrounds
private Background background; private Background background;
private WorkingBeatmap beatmap; private WorkingBeatmap beatmap;
private Vector2 blurTarget;
public WorkingBeatmap Beatmap public WorkingBeatmap Beatmap
{ {
@ -30,20 +30,26 @@ namespace osu.Game.Screens.Backgrounds
beatmap = value; beatmap = value;
Background oldBackground = background; Schedule(() =>
addBackground(background = new Background());
background.Sprite.Texture = beatmap.Background;
if (oldBackground != null)
{ {
oldBackground.Depth = 1; Background newBackground = new BeatmapBackground(beatmap);
oldBackground.Flush();
oldBackground.FadeOut(250);
oldBackground.Expire();
background.BlurSigma = oldBackground.BlurSigma; newBackground.Preload(Game, delegate
} {
Background oldBackground = background;
Add(background = newBackground);
background.BlurSigma = blurTarget;
if (oldBackground != null)
{
oldBackground.Depth = 1;
oldBackground.Flush();
oldBackground.FadeOut(250);
oldBackground.Expire();
}
});
});
} }
} }
@ -52,20 +58,33 @@ namespace osu.Game.Screens.Backgrounds
Beatmap = beatmap; Beatmap = beatmap;
} }
private void addBackground(Background background)
{
background.CacheDrawnFrameBuffer = true;
Add(background);
}
public void BlurTo(Vector2 sigma, double duration) public void BlurTo(Vector2 sigma, double duration)
{ {
background?.BlurTo(sigma, duration, EasingTypes.OutExpo); background?.BlurTo(sigma, duration, EasingTypes.OutExpo);
blurTarget = sigma;
} }
public override bool Equals(BackgroundMode other) public override bool Equals(BackgroundMode other)
{ {
return base.Equals(other) && beatmap == ((BackgroundModeBeatmap)other).Beatmap; return base.Equals(other) && beatmap == ((BackgroundModeBeatmap)other).Beatmap;
} }
class BeatmapBackground : Background
{
private WorkingBeatmap beatmap;
public BeatmapBackground(WorkingBeatmap beatmap)
{
this.beatmap = beatmap;
CacheDrawnFrameBuffer = true;
}
[BackgroundDependencyLoader]
private void load()
{
Sprite.Texture = beatmap.Background;
}
}
} }
} }

View File

@ -125,9 +125,9 @@ namespace osu.Game.Screens.Play
{ {
} }
protected override void UpdateMouseState(InputState state) protected override void TransformState(InputState state)
{ {
base.UpdateMouseState(state); base.TransformState(state);
MouseState mouse = (MouseState)state.Mouse; MouseState mouse = (MouseState)state.Mouse;

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
@ -44,6 +45,7 @@ namespace osu.Game.Screens.Select
private Container wedgedBeatmapInfo; private Container wedgedBeatmapInfo;
private static readonly Vector2 BACKGROUND_BLUR = new Vector2(20); private static readonly Vector2 BACKGROUND_BLUR = new Vector2(20);
private CancellationTokenSource initialAddSetsTask;
/// <param name="database">Optionally provide a database to use instead of the OsuGame one.</param> /// <param name="database">Optionally provide a database to use instead of the OsuGame one.</param>
public PlaySongSelect(BeatmapDatabase database = null) public PlaySongSelect(BeatmapDatabase database = null)
@ -153,11 +155,18 @@ namespace osu.Game.Screens.Select
if (database == null) if (database == null)
database = beatmaps; database = beatmaps;
database.BeatmapSetAdded += s => Schedule(() => addBeatmapSet(s, game)); database.BeatmapSetAdded += onDatabaseOnBeatmapSetAdded;
trackManager = audio.Track; trackManager = audio.Track;
Task.Factory.StartNew(() => addBeatmapSets(game)); initialAddSetsTask = new CancellationTokenSource();
Task.Factory.StartNew(() => addBeatmapSets(game, initialAddSetsTask.Token), initialAddSetsTask.Token);
}
private void onDatabaseOnBeatmapSetAdded(BeatmapSetInfo s)
{
Schedule(() => addBeatmapSet(s, Game));
} }
protected override void OnEntering(GameMode last) protected override void OnEntering(GameMode last)
@ -196,6 +205,10 @@ namespace osu.Game.Screens.Select
base.Dispose(isDisposing); base.Dispose(isDisposing);
if (playMode != null) if (playMode != null)
playMode.ValueChanged -= playMode_ValueChanged; playMode.ValueChanged -= playMode_ValueChanged;
database.BeatmapSetAdded -= onDatabaseOnBeatmapSetAdded;
initialAddSetsTask.Cancel();
} }
private void playMode_ValueChanged(object sender, EventArgs e) private void playMode_ValueChanged(object sender, EventArgs e)
@ -215,6 +228,7 @@ namespace osu.Game.Screens.Select
(Background as BackgroundModeBeatmap)?.BlurTo(BACKGROUND_BLUR, 1000); (Background as BackgroundModeBeatmap)?.BlurTo(BACKGROUND_BLUR, 1000);
} }
//todo: move to own class and fix async logic (move every call on WorkingBeatmap.* to load() and use Preload to create it.
refreshWedgedBeatmapInfo(beatmap); refreshWedgedBeatmapInfo(beatmap);
} }
@ -329,6 +343,7 @@ namespace osu.Game.Screens.Select
{ {
base.OnBeatmapChanged(beatmap); base.OnBeatmapChanged(beatmap);
//todo: change background in selectionChanged instead; support per-difficulty backgrounds.
changeBackground(beatmap); changeBackground(beatmap);
selectBeatmap(beatmap.BeatmapInfo); selectBeatmap(beatmap.BeatmapInfo);
@ -372,9 +387,9 @@ namespace osu.Game.Screens.Select
beatmapSet.Beatmaps.ForEach(b => database.GetChildren(b)); beatmapSet.Beatmaps.ForEach(b => database.GetChildren(b));
beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList(); beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList();
var working = database.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()); var beatmap = database.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault());
var group = new BeatmapGroup(beatmapSet, working) { SelectionChanged = selectionChanged }; var group = new BeatmapGroup(beatmap) { SelectionChanged = selectionChanged };
//for the time being, let's completely load the difficulty panels in the background. //for the time being, let's completely load the difficulty panels in the background.
//this likely won't scale so well, but allows us to completely async the loading flow. //this likely won't scale so well, but allows us to completely async the loading flow.
@ -393,10 +408,13 @@ namespace osu.Game.Screens.Select
})); }));
} }
private void addBeatmapSets(BaseGame game) private void addBeatmapSets(BaseGame game, CancellationToken token)
{ {
foreach (var beatmapSet in database.Query<BeatmapSetInfo>()) foreach (var beatmapSet in database.Query<BeatmapSetInfo>())
{
if (token.IsCancellationRequested) return;
addBeatmapSet(beatmapSet, game); addBeatmapSet(beatmapSet, game);
}
} }
} }
} }