1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 09:23:06 +08:00

Merge branch 'master' into controlpoint-rework

This commit is contained in:
Dean Herbert 2017-05-24 00:20:15 +09:00 committed by GitHub
commit 0842e00f13
12 changed files with 205 additions and 139 deletions

@ -1 +1 @@
Subproject commit ffccbeb98dc9e8f0965520270b5885e63f244c83 Subproject commit 9f46a456dc3a56dcbff09671a3f588b16a464106

View File

@ -37,5 +37,7 @@ namespace osu.Desktop.Beatmaps.IO
{ {
// no-op // no-op
} }
public override Stream GetUnderlyingStream() => null;
} }
} }

View File

@ -1,10 +1,13 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 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 System;
using OpenTK.Graphics; using OpenTK.Graphics;
using OpenTK.Input; using OpenTK.Input;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
@ -40,14 +43,53 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
} }
} }
protected override void Update() protected override void CheckJudgement(bool userTriggered)
{ {
if (Time.Current > HitObject.StartTime) if (!userTriggered)
Colour = Color4.Green; {
if (Judgement.TimeOffset > HitObject.HitWindows.Bad / 2)
Judgement.Result = HitResult.Miss;
return;
}
double offset = Math.Abs(Judgement.TimeOffset);
if (offset > HitObject.HitWindows.Miss / 2)
return;
ManiaHitResult? tmpResult = HitObject.HitWindows.ResultFor(offset);
if (tmpResult.HasValue)
{
Judgement.Result = HitResult.Hit;
Judgement.ManiaResult = tmpResult.Value;
}
else
Judgement.Result = HitResult.Miss;
} }
protected override void UpdateState(ArmedState state) protected override void UpdateState(ArmedState state)
{ {
switch (State)
{
case ArmedState.Hit:
Colour = Color4.Green;
break;
}
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
if (Judgement.Result != HitResult.None)
return false;
if (args.Key != Key)
return false;
if (args.Repeat)
return false;
return UpdateJudgement(true);
} }
} }
} }

View File

@ -63,5 +63,7 @@ namespace osu.Game.Beatmaps.IO
return buffer; return buffer;
} }
} }
public abstract Stream GetUnderlyingStream();
} }
} }

View File

@ -49,5 +49,7 @@ namespace osu.Game.Beatmaps.IO
archive.Dispose(); archive.Dispose();
archiveStream.Dispose(); archiveStream.Dispose();
} }
public override Stream GetUnderlyingStream() => archiveStream;
} }
} }

View File

@ -12,6 +12,7 @@ using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.IO; using osu.Game.Beatmaps.IO;
using osu.Game.IPC; using osu.Game.IPC;
using osu.Game.Screens.Menu;
using SQLite.Net; using SQLite.Net;
using SQLiteNetExtensions.Extensions; using SQLiteNetExtensions.Extensions;
@ -38,6 +39,10 @@ namespace osu.Game.Database
{ {
foreach (var b in GetAllWithChildren<BeatmapSetInfo>(b => b.DeletePending)) foreach (var b in GetAllWithChildren<BeatmapSetInfo>(b => b.DeletePending))
{ {
if (b.Hash == Intro.MENU_MUSIC_BEATMAP_HASH)
// this is a bit hacky, but will do for now.
continue;
try try
{ {
Storage.Delete(b.Path); Storage.Delete(b.Path);
@ -97,50 +102,49 @@ namespace osu.Game.Database
typeof(BeatmapDifficulty), typeof(BeatmapDifficulty),
}; };
public void Import(string path)
{
try
{
Import(ArchiveReader.GetReader(Storage, path));
// We may or may not want to delete the file depending on where it is stored.
// e.g. reconstructing/repairing database with beatmaps from default storage.
// Also, not always a single file, i.e. for LegacyFilesystemReader
// TODO: Add a check to prevent files from storage to be deleted.
try
{
File.Delete(path);
}
catch (Exception e)
{
Logger.Error(e, $@"Could not delete file at {path}");
}
}
catch (Exception e)
{
e = e.InnerException ?? e;
Logger.Error(e, @"Could not import beatmap set");
}
}
public void Import(ArchiveReader archiveReader)
{
BeatmapSetInfo set = getBeatmapSet(archiveReader);
//If we have an ID then we already exist in the database.
if (set.ID == 0)
Import(new[] { set });
}
/// <summary> /// <summary>
/// Import multiple <see cref="BeatmapSetInfo"/> from <paramref name="paths"/>. /// Import multiple <see cref="BeatmapSetInfo"/> from <paramref name="paths"/>.
/// </summary> /// </summary>
/// <param name="paths">Multiple locations on disk</param> /// <param name="paths">Multiple locations on disk</param>
public void Import(IEnumerable<string> paths) public void Import(params string[] paths)
{ {
foreach (string p in paths) foreach (string p in paths)
{ Import(p);
try
{
BeatmapSetInfo set = getBeatmapSet(p);
//If we have an ID then we already exist in the database.
if (set.ID == 0)
Import(new[] { set });
// We may or may not want to delete the file depending on where it is stored.
// e.g. reconstructing/repairing database with beatmaps from default storage.
// Also, not always a single file, i.e. for LegacyFilesystemReader
// TODO: Add a check to prevent files from storage to be deleted.
try
{
File.Delete(p);
}
catch (Exception e)
{
Logger.Error(e, $@"Could not delete file at {p}");
}
}
catch (Exception e)
{
e = e.InnerException ?? e;
Logger.Error(e, @"Could not import beatmap set");
}
}
}
/// <summary>
/// Import <see cref="BeatmapSetInfo"/> from <paramref name="path"/>.
/// </summary>
/// <param name="path">Location on disk</param>
public void Import(string path)
{
Import(new[] { path });
} }
/// <summary> /// <summary>
@ -148,29 +152,26 @@ namespace osu.Game.Database
/// </summary> /// </summary>
/// <param name="path">Content location</param> /// <param name="path">Content location</param>
/// <returns><see cref="BeatmapSetInfo"/></returns> /// <returns><see cref="BeatmapSetInfo"/></returns>
private BeatmapSetInfo getBeatmapSet(string path) private BeatmapSetInfo getBeatmapSet(string path) => getBeatmapSet(ArchiveReader.GetReader(Storage, path));
{
string hash = null;
private BeatmapSetInfo getBeatmapSet(ArchiveReader archiveReader)
{
BeatmapMetadata metadata; BeatmapMetadata metadata;
using (var reader = ArchiveReader.GetReader(Storage, path)) using (var stream = new StreamReader(archiveReader.GetStream(archiveReader.BeatmapFilenames[0])))
{ metadata = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata;
using (var stream = new StreamReader(reader.GetStream(reader.BeatmapFilenames[0])))
metadata = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata;
}
if (File.Exists(path)) // Not always the case, i.e. for LegacyFilesystemReader string hash;
string path;
using (var input = archiveReader.GetUnderlyingStream())
{ {
using (var input = Storage.GetStream(path)) hash = input.GetMd5Hash();
{ input.Seek(0, SeekOrigin.Begin);
hash = input.GetMd5Hash(); path = Path.Combine(@"beatmaps", hash.Remove(1), hash.Remove(2), hash);
input.Seek(0, SeekOrigin.Begin); if (!Storage.Exists(path))
path = Path.Combine(@"beatmaps", hash.Remove(1), hash.Remove(2), hash); using (var output = Storage.GetStream(path, FileAccess.Write))
if (!Storage.Exists(path)) input.CopyTo(output);
using (var output = Storage.GetStream(path, FileAccess.Write))
input.CopyTo(output);
}
} }
var existing = Connection.Table<BeatmapSetInfo>().FirstOrDefault(b => b.Hash == hash); var existing = Connection.Table<BeatmapSetInfo>().FirstOrDefault(b => b.Hash == hash);

View File

@ -82,7 +82,7 @@ namespace osu.Game
if (args?.Length > 0) if (args?.Length > 0)
{ {
var paths = args.Where(a => !a.StartsWith(@"-")); var paths = args.Where(a => !a.StartsWith(@"-"));
Task.Run(() => BeatmapDatabase.Import(paths)); Task.Run(() => BeatmapDatabase.Import(paths.ToArray()));
} }
Dependencies.Cache(this); Dependencies.Cache(this);

View File

@ -4,6 +4,7 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
namespace osu.Game.Overlays.Settings.Sections.Graphics namespace osu.Game.Overlays.Settings.Sections.Graphics
{ {
@ -11,11 +12,12 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
{ {
protected override string Header => "Layout"; protected override string Header => "Layout";
private SettingsSlider<double> letterboxPositionX; private FillFlowContainer letterboxSettings;
private SettingsSlider<double> letterboxPositionY;
private Bindable<bool> letterboxing; private Bindable<bool> letterboxing;
private const int transition_duration = 400;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(FrameworkConfigManager config) private void load(FrameworkConfigManager config)
{ {
@ -33,34 +35,40 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
LabelText = "Letterboxing", LabelText = "Letterboxing",
Bindable = letterboxing, Bindable = letterboxing,
}, },
letterboxPositionX = new SettingsSlider<double> letterboxSettings = new FillFlowContainer
{ {
LabelText = "Horizontal position", Direction = FillDirection.Vertical,
Bindable = config.GetBindable<double>(FrameworkSetting.LetterboxPositionX) RelativeSizeAxes = Axes.X,
}, AutoSizeAxes = Axes.Y,
letterboxPositionY = new SettingsSlider<double> AutoSizeDuration = transition_duration,
{ AutoSizeEasing = EasingTypes.OutQuint,
LabelText = "Vertical position", Masking = true,
Bindable = config.GetBindable<double>(FrameworkSetting.LetterboxPositionY)
Children = new Drawable[]
{
new SettingsSlider<double>
{
LabelText = "Horizontal position",
Bindable = config.GetBindable<double>(FrameworkSetting.LetterboxPositionX)
},
new SettingsSlider<double>
{
LabelText = "Vertical position",
Bindable = config.GetBindable<double>(FrameworkSetting.LetterboxPositionY)
},
}
}, },
}; };
letterboxing.ValueChanged += visibilityChanged; letterboxing.ValueChanged += isVisible =>
letterboxing.TriggerChange(); {
} letterboxSettings.ClearTransforms();
letterboxSettings.AutoSizeAxes = isVisible ? Axes.Y : Axes.None;
private void visibilityChanged(bool newVisibility) if(!isVisible)
{ letterboxSettings.ResizeHeightTo(0, transition_duration, EasingTypes.OutQuint);
if (newVisibility) };
{ letterboxing.TriggerChange();
letterboxPositionX.Show();
letterboxPositionY.Show();
}
else
{
letterboxPositionX.Hide();
letterboxPositionY.Hide();
}
} }
} }
} }

View File

@ -8,7 +8,10 @@ using osu.Framework.Audio.Track;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps.IO;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Backgrounds;
using OpenTK.Graphics; using OpenTK.Graphics;
@ -19,6 +22,8 @@ namespace osu.Game.Screens.Menu
{ {
private readonly OsuLogo logo; private readonly OsuLogo logo;
public const string MENU_MUSIC_BEATMAP_HASH = "21c1271b91234385978b5418881fdd88";
/// <summary> /// <summary>
/// Whether we have loaded the menu previously. /// Whether we have loaded the menu previously.
/// </summary> /// </summary>
@ -27,7 +32,6 @@ namespace osu.Game.Screens.Menu
private MainMenu mainMenu; private MainMenu mainMenu;
private SampleChannel welcome; private SampleChannel welcome;
private SampleChannel seeya; private SampleChannel seeya;
private Track bgm;
internal override bool HasLocalCursorDisplayed => true; internal override bool HasLocalCursorDisplayed => true;
@ -60,15 +64,49 @@ namespace osu.Game.Screens.Menu
private Bindable<bool> menuVoice; private Bindable<bool> menuVoice;
private Bindable<bool> menuMusic; private Bindable<bool> menuMusic;
private Track track;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(AudioManager audio, OsuConfigManager config) private void load(AudioManager audio, OsuConfigManager config, BeatmapDatabase beatmaps, Framework.Game game)
{ {
menuVoice = config.GetBindable<bool>(OsuSetting.MenuVoice); menuVoice = config.GetBindable<bool>(OsuSetting.MenuVoice);
menuMusic = config.GetBindable<bool>(OsuSetting.MenuMusic); menuMusic = config.GetBindable<bool>(OsuSetting.MenuMusic);
bgm = audio.Track.Get(@"circles"); var trackManager = audio.Track;
bgm.Looping = true;
BeatmapSetInfo setInfo = null;
if (!menuMusic)
{
var query = beatmaps.Query<BeatmapSetInfo>().Where(b => !b.DeletePending);
int count = query.Count();
if (count > 0)
setInfo = query.ElementAt(RNG.Next(0, count - 1));
}
if (setInfo == null)
{
var query = beatmaps.Query<BeatmapSetInfo>().Where(b => b.Hash == MENU_MUSIC_BEATMAP_HASH);
setInfo = query.FirstOrDefault();
if (setInfo == null)
{
// we need to import the default menu background beatmap
beatmaps.Import(new OszArchiveReader(game.Resources.GetStream(@"Tracks/circles.osz")));
setInfo = query.First();
setInfo.DeletePending = true;
beatmaps.Update(setInfo, false);
}
}
beatmaps.GetChildren(setInfo);
Beatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]);
track = Beatmap.Track;
trackManager.SetExclusive(track);
welcome = audio.Sample.Get(@"welcome"); welcome = audio.Sample.Get(@"welcome");
seeya = audio.Sample.Get(@"seeya"); seeya = audio.Sample.Get(@"seeya");
@ -83,8 +121,7 @@ namespace osu.Game.Screens.Menu
Scheduler.AddDelayed(delegate Scheduler.AddDelayed(delegate
{ {
if (menuMusic) track.Start();
bgm.Start();
LoadComponentAsync(mainMenu = new MainMenu()); LoadComponentAsync(mainMenu = new MainMenu());

View File

@ -1,18 +1,12 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 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 System.Threading.Tasks;
using OpenTK; using OpenTK;
using OpenTK.Input; using OpenTK.Input;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Framework.MathUtils;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Backgrounds;
using osu.Game.Screens.Charts; using osu.Game.Screens.Charts;
@ -60,30 +54,11 @@ namespace osu.Game.Screens.Menu
}; };
} }
private Bindable<bool> menuMusic;
private TrackManager trackManager;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuGame game, OsuConfigManager config, BeatmapDatabase beatmaps) private void load(OsuGame game)
{ {
menuMusic = config.GetBindable<bool>(OsuSetting.MenuMusic);
LoadComponentAsync(background); LoadComponentAsync(background);
if (!menuMusic)
{
trackManager = game.Audio.Track;
var query = beatmaps.Query<BeatmapSetInfo>().Where(b => !b.DeletePending);
int count = query.Count();
if (count > 0)
{
var beatmap = query.ElementAt(RNG.Next(0, count - 1));
beatmaps.GetChildren(beatmap);
Beatmap = beatmaps.GetWorkingBeatmap(beatmap.Beatmaps[0]);
}
}
buttons.OnSettings = game.ToggleSettings; buttons.OnSettings = game.ToggleSettings;
preloadSongSelect(); preloadSongSelect();
@ -108,14 +83,13 @@ namespace osu.Game.Screens.Menu
buttons.FadeInFromZero(500); buttons.FadeInFromZero(500);
if (last is Intro && Beatmap != null) if (last is Intro && Beatmap != null)
{ {
Task.Run(() => if (!Beatmap.Track.IsRunning)
{ {
trackManager.SetExclusive(Beatmap.Track);
Beatmap.Track.Seek(Beatmap.Metadata.PreviewTime); Beatmap.Track.Seek(Beatmap.Metadata.PreviewTime);
if (Beatmap.Metadata.PreviewTime == -1) if (Beatmap.Metadata.PreviewTime == -1)
Beatmap.Track.Seek(Beatmap.Track.Length * 0.4f); Beatmap.Track.Seek(Beatmap.Track.Length * 0.4f);
Beatmap.Track.Start(); Beatmap.Track.Start();
}); }
} }
} }

View File

@ -30,7 +30,6 @@ namespace osu.Game.Screens.Play
public readonly SongProgress Progress; public readonly SongProgress Progress;
public readonly ModDisplay ModDisplay; public readonly ModDisplay ModDisplay;
private Bindable<bool> showKeyCounter;
private Bindable<bool> showHud; private Bindable<bool> showHud;
private static bool hasShownNotificationOnce; private static bool hasShownNotificationOnce;
@ -67,24 +66,8 @@ namespace osu.Game.Screens.Play
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(OsuConfigManager config, NotificationManager notificationManager) private void load(OsuConfigManager config, NotificationManager notificationManager)
{ {
showKeyCounter = config.GetBindable<bool>(OsuSetting.KeyOverlay);
showKeyCounter.ValueChanged += keyCounterVisibility =>
{
if (keyCounterVisibility)
KeyCounter.FadeIn(duration);
else
KeyCounter.FadeOut(duration);
};
showKeyCounter.TriggerChange();
showHud = config.GetBindable<bool>(OsuSetting.ShowInterface); showHud = config.GetBindable<bool>(OsuSetting.ShowInterface);
showHud.ValueChanged += hudVisibility => showHud.ValueChanged += hudVisibility => content.FadeTo(hudVisibility ? 1 : 0, duration);
{
if (hudVisibility)
content.FadeIn(duration);
else
content.FadeOut(duration);
};
showHud.TriggerChange(); showHud.TriggerChange();
if (!showHud && !hasShownNotificationOnce) if (!showHud && !hasShownNotificationOnce)

View File

@ -6,11 +6,18 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Framework.Configuration;
using osu.Framework.Allocation;
using osu.Game.Configuration;
namespace osu.Game.Screens.Play namespace osu.Game.Screens.Play
{ {
public class KeyCounterCollection : FillFlowContainer<KeyCounter> public class KeyCounterCollection : FillFlowContainer<KeyCounter>
{ {
private const int duration = 100;
private Bindable<bool> showKeyCounter;
public KeyCounterCollection() public KeyCounterCollection()
{ {
AlwaysReceiveInput = true; AlwaysReceiveInput = true;
@ -34,6 +41,14 @@ namespace osu.Game.Screens.Play
counter.ResetCount(); counter.ResetCount();
} }
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
showKeyCounter = config.GetBindable<bool>(OsuSetting.KeyOverlay);
showKeyCounter.ValueChanged += keyCounterVisibility => FadeTo(keyCounterVisibility ? 1 : 0, duration);
showKeyCounter.TriggerChange();
}
//further: change default values here and in KeyCounter if needed, instead of passing them in every constructor //further: change default values here and in KeyCounter if needed, instead of passing them in every constructor
private bool isCounting; private bool isCounting;
public bool IsCounting public bool IsCounting