1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 02:07:34 +08:00

Merge branch 'master' into multi-room-update

This commit is contained in:
Dean Herbert 2019-08-13 21:03:03 +09:00 committed by GitHub
commit 8ce2c876bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 653 additions and 497 deletions

View File

@ -49,9 +49,7 @@
<None Include="$(MSBuildThisFileDirectory)\osu.licenseheader">
<Link>osu.licenseheader</Link>
</None>
<AndroidNativeLibrary Include="$(MSBuildThisFileDirectory)\osu.Android\lib\**\*.so">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</AndroidNativeLibrary>
<AndroidNativeLibrary Include="$(OutputPath)\**\*.so" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
@ -63,6 +61,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.809.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.809.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.813.0" />
</ItemGroup>
</Project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -113,13 +113,14 @@ namespace osu.Desktop.Overlays
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, ChangelogOverlay changelog)
private void load(OsuColour colours, ChangelogOverlay changelog, NotificationOverlay notificationOverlay)
{
Icon = FontAwesome.Solid.CheckSquare;
IconBackgound.Colour = colours.BlueDark;
Activated = delegate
{
notificationOverlay.Hide();
changelog.ShowBuild(OsuGameBase.CLIENT_STREAM_NAME, version);
return true;
};

View File

@ -13,14 +13,6 @@
<ItemGroup>
<None Include="Info.plist" />
<None Include="Entitlements.plist" />
<None Include="..\osu.iOS\libbass.a">
<Link>libbass.a</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\osu.iOS\libbass_fx.a">
<Link>libbass_fx.a</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<LinkDescription Include="..\osu.iOS\Linker.xml">
<Link>Linker.xml</Link>
</LinkDescription>

View File

@ -13,14 +13,6 @@
<ItemGroup>
<None Include="Info.plist" />
<None Include="Entitlements.plist" />
<None Include="..\osu.iOS\libbass.a">
<Link>libbass.a</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\osu.iOS\libbass_fx.a">
<Link>libbass_fx.a</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<LinkDescription Include="..\osu.iOS\Linker.xml">
<Link>Linker.xml</Link>
</LinkDescription>

View File

@ -13,14 +13,6 @@
<ItemGroup>
<None Include="Info.plist" />
<None Include="Entitlements.plist" />
<None Include="..\osu.iOS\libbass.a">
<Link>libbass.a</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\osu.iOS\libbass_fx.a">
<Link>libbass_fx.a</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<LinkDescription Include="..\osu.iOS\Linker.xml">
<Link>Linker.xml</Link>
</LinkDescription>

View File

@ -13,14 +13,6 @@
<ItemGroup>
<None Include="Info.plist" />
<None Include="Entitlements.plist" />
<None Include="..\osu.iOS\libbass.a">
<Link>libbass.a</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\osu.iOS\libbass_fx.a">
<Link>libbass_fx.a</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<LinkDescription Include="..\osu.iOS\Linker.xml">
<Link>Linker.xml</Link>
</LinkDescription>

View File

@ -13,14 +13,6 @@
<ItemGroup>
<None Include="Info.plist" />
<None Include="Entitlements.plist" />
<None Include="..\osu.iOS\libbass.a">
<Link>libbass.a</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\osu.iOS\libbass_fx.a">
<Link>libbass_fx.a</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<LinkDescription Include="..\osu.iOS\Linker.xml">
<Link>Linker.xml</Link>
</LinkDescription>

View File

@ -21,32 +21,38 @@ namespace osu.Game.Tests.Visual.Gameplay
private readonly Container<DrawableStoryboard> storyboardContainer;
private DrawableStoryboard storyboard;
[Cached]
private MusicController musicController = new MusicController();
public TestSceneStoryboard()
{
Clock = new FramedClock();
Add(new Container
AddRange(new Drawable[]
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
musicController,
new Container
{
new Box
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
storyboardContainer = new Container<DrawableStoryboard>
{
RelativeSizeAxes = Axes.Both,
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
storyboardContainer = new Container<DrawableStoryboard>
{
RelativeSizeAxes = Axes.Both,
},
},
},
});
Add(new MusicController
{
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,
State = { Value = Visibility.Visible },
new NowPlayingOverlay
{
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,
State = { Value = Visibility.Visible },
}
});
AddStep("Restart", restart);

View File

@ -3,6 +3,7 @@
using System;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
@ -22,30 +23,36 @@ namespace osu.Game.Tests.Visual.UserInterface
[TestFixture]
public class TestSceneBeatSyncedContainer : OsuTestScene
{
private readonly MusicController mc;
private readonly NowPlayingOverlay np;
[Cached]
private MusicController musicController = new MusicController();
public TestSceneBeatSyncedContainer()
{
Clock = new FramedClock();
Clock.ProcessFrame();
Add(new BeatContainer
AddRange(new Drawable[]
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
});
Add(mc = new MusicController
{
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,
musicController,
new BeatContainer
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
},
np = new NowPlayingOverlay
{
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,
}
});
}
protected override void LoadComplete()
{
base.LoadComplete();
mc.ToggleVisibility();
np.ToggleVisibility();
}
private class BeatContainer : BeatSyncedContainer

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Timing;
using osu.Game.Overlays;
@ -9,22 +10,27 @@ using osu.Game.Overlays;
namespace osu.Game.Tests.Visual.UserInterface
{
[TestFixture]
public class TestSceneMusicController : OsuTestScene
public class TestSceneNowPlayingOverlay : OsuTestScene
{
public TestSceneMusicController()
[Cached]
private MusicController musicController = new MusicController();
public TestSceneNowPlayingOverlay()
{
Clock = new FramedClock();
var mc = new MusicController
var np = new NowPlayingOverlay
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre
};
Add(mc);
AddStep(@"show", () => mc.Show());
Add(musicController);
Add(np);
AddStep(@"show", () => np.Show());
AddToggleStep(@"toggle beatmap lock", state => Beatmap.Disabled = state);
AddStep(@"show", () => mc.Hide());
AddStep(@"show", () => np.Hide());
}
}
}

View File

@ -20,7 +20,7 @@ namespace osu.Game.Input.Bindings
handler = game;
}
public override IEnumerable<KeyBinding> DefaultKeyBindings => GlobalKeyBindings.Concat(InGameKeyBindings);
public override IEnumerable<KeyBinding> DefaultKeyBindings => GlobalKeyBindings.Concat(InGameKeyBindings).Concat(AudioControlKeyBindings);
public IEnumerable<KeyBinding> GlobalKeyBindings => new[]
{
@ -32,11 +32,6 @@ namespace osu.Game.Input.Bindings
new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings),
new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar),
new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings),
new KeyBinding(InputKey.Up, GlobalAction.IncreaseVolume),
new KeyBinding(InputKey.MouseWheelUp, GlobalAction.IncreaseVolume),
new KeyBinding(InputKey.Down, GlobalAction.DecreaseVolume),
new KeyBinding(InputKey.MouseWheelDown, GlobalAction.DecreaseVolume),
new KeyBinding(InputKey.F4, GlobalAction.ToggleMute),
new KeyBinding(InputKey.Escape, GlobalAction.Back),
new KeyBinding(InputKey.ExtraMouseButton1, GlobalAction.Back),
@ -55,6 +50,22 @@ namespace osu.Game.Input.Bindings
new KeyBinding(new[] { InputKey.Control, InputKey.Minus }, GlobalAction.DecreaseScrollSpeed),
};
public IEnumerable<KeyBinding> AudioControlKeyBindings => new[]
{
new KeyBinding(InputKey.Up, GlobalAction.IncreaseVolume),
new KeyBinding(InputKey.MouseWheelUp, GlobalAction.IncreaseVolume),
new KeyBinding(InputKey.Down, GlobalAction.DecreaseVolume),
new KeyBinding(InputKey.MouseWheelDown, GlobalAction.DecreaseVolume),
new KeyBinding(InputKey.F4, GlobalAction.ToggleMute),
new KeyBinding(InputKey.TrackPrevious, GlobalAction.MusicPrev),
new KeyBinding(InputKey.F1, GlobalAction.MusicPrev),
new KeyBinding(InputKey.TrackNext, GlobalAction.MusicNext),
new KeyBinding(InputKey.F5, GlobalAction.MusicNext),
new KeyBinding(InputKey.PlayPause, GlobalAction.MusicPlay),
new KeyBinding(InputKey.F3, GlobalAction.MusicPlay)
};
protected override IEnumerable<Drawable> KeyBindingInputQueue =>
handler == null ? base.KeyBindingInputQueue : base.KeyBindingInputQueue.Prepend(handler);
}
@ -115,5 +126,15 @@ namespace osu.Game.Input.Bindings
[Description("Quick exit (Hold)")]
QuickExit,
// Game-wide beatmap msi ccotolle keybindings
[Description("Next track")]
MusicNext,
[Description("Previous track")]
MusicPrev,
[Description("Play / pause")]
MusicPlay,
}
}

View File

@ -299,7 +299,7 @@ namespace osu.Game
}, $"watch {databasedScoreInfo}", bypassScreenAllowChecks: true);
}
#region Beatmap jukebox progression
#region Beatmap progression
private void beatmapChanged(ValueChangedEvent<WorkingBeatmap> beatmap)
{
@ -469,6 +469,8 @@ namespace osu.Game
loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add);
loadComponentSingleFile(new OnScreenDisplay(), Add, true);
loadComponentSingleFile(musicController = new MusicController(), Add, true);
loadComponentSingleFile(notifications = new NotificationOverlay
{
GetToolbarHeight = () => ToolbarOffset,
@ -495,7 +497,7 @@ namespace osu.Game
Origin = Anchor.TopRight,
}, rightFloatingOverlayContent.Add, true);
loadComponentSingleFile(musicController = new MusicController
loadComponentSingleFile(new NowPlayingOverlay
{
GetToolbarHeight = () => ToolbarOffset,
Anchor = Anchor.TopRight,

View File

@ -15,6 +15,7 @@ namespace osu.Game.Overlays.KeyBinding
public GlobalKeyBindingsSection(GlobalActionContainer manager)
{
Add(new DefaultBindingsSubsection(manager));
Add(new AudioControlKeyBindingsSubsection(manager));
Add(new InGameKeyBindingsSubsection(manager));
}
@ -39,5 +40,16 @@ namespace osu.Game.Overlays.KeyBinding
Defaults = manager.InGameKeyBindings;
}
}
private class AudioControlKeyBindingsSubsection : KeyBindingsSubsection
{
protected override string Header => "Audio";
public AudioControlKeyBindingsSubsection(GlobalActionContainer manager)
: base(null)
{
Defaults = manager.AudioControlKeyBindings;
}
}
}
}

View File

@ -1,292 +1,112 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 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 System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Framework.Input.Bindings;
using osu.Framework.Threading;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Music;
using osu.Game.Input.Bindings;
using osu.Game.Overlays.OSD;
using osu.Game.Rulesets.Mods;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays
{
public class MusicController : OsuFocusedOverlayContainer
/// <summary>
/// Handles playback of the global music track.
/// </summary>
public class MusicController : Component, IKeyBindingHandler<GlobalAction>
{
private const float player_height = 130;
private const float transition_length = 800;
private const float progress_height = 10;
private const float bottom_black_area_height = 55;
private Drawable background;
private ProgressBar progressBar;
private IconButton prevButton;
private IconButton playButton;
private IconButton nextButton;
private IconButton playlistButton;
private SpriteText title, artist;
private PlaylistOverlay playlist;
private BeatmapManager beatmaps;
[Resolved]
private BeatmapManager beatmaps { get; set; }
private List<BeatmapSetInfo> beatmapSets;
private Container dragContainer;
private Container playerContainer;
public bool IsUserPaused { get; private set; }
/// <summary>
/// Fired when the global <see cref="WorkingBeatmap"/> has changed.
/// Includes direction information for display purposes.
/// </summary>
public event Action<WorkingBeatmap, TrackChangeDirection> TrackChanged;
[Resolved]
private Bindable<WorkingBeatmap> beatmap { get; set; }
private IBindable<WorkingBeatmap> beatmap { get; set; }
[Resolved]
private IBindable<IReadOnlyList<Mod>> mods { get; set; }
/// <summary>
/// Provide a source for the toolbar height.
/// </summary>
public Func<float> GetToolbarHeight;
public MusicController()
{
Width = 400;
Margin = new MarginPadding(10);
}
[Resolved(canBeNull: true)]
private OnScreenDisplay onScreenDisplay { get; set; }
[BackgroundDependencyLoader]
private void load(Bindable<WorkingBeatmap> beatmap, BeatmapManager beatmaps, OsuColour colours)
private void load()
{
this.beatmaps = beatmaps;
Children = new Drawable[]
{
dragContainer = new DragContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
playlist = new PlaylistOverlay
{
RelativeSizeAxes = Axes.X,
Y = player_height + 10,
OrderChanged = playlistOrderChanged
},
playerContainer = new Container
{
RelativeSizeAxes = Axes.X,
Height = player_height,
Masking = true,
CornerRadius = 5,
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Colour = Color4.Black.Opacity(40),
Radius = 5,
},
Children = new[]
{
background = new Background(),
title = new OsuSpriteText
{
Origin = Anchor.BottomCentre,
Anchor = Anchor.TopCentre,
Position = new Vector2(0, 40),
Font = OsuFont.GetFont(size: 25, italics: true),
Colour = Color4.White,
Text = @"Nothing to play",
},
artist = new OsuSpriteText
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Position = new Vector2(0, 45),
Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold, italics: true),
Colour = Color4.White,
Text = @"Nothing to play",
},
new Container
{
Padding = new MarginPadding { Bottom = progress_height },
Height = bottom_black_area_height,
RelativeSizeAxes = Axes.X,
Origin = Anchor.BottomCentre,
Anchor = Anchor.BottomCentre,
Children = new Drawable[]
{
new FillFlowContainer<IconButton>
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5),
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Children = new[]
{
prevButton = new MusicIconButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Action = prev,
Icon = FontAwesome.Solid.StepBackward,
},
playButton = new MusicIconButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(1.4f),
IconScale = new Vector2(1.4f),
Action = togglePause,
Icon = FontAwesome.Regular.PlayCircle,
},
nextButton = new MusicIconButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Action = () => next(),
Icon = FontAwesome.Solid.StepForward,
},
}
},
playlistButton = new MusicIconButton
{
Origin = Anchor.Centre,
Anchor = Anchor.CentreRight,
Position = new Vector2(-bottom_black_area_height / 2, 0),
Icon = FontAwesome.Solid.Bars,
Action = () => playlist.ToggleVisibility(),
},
}
},
progressBar = new ProgressBar
{
Origin = Anchor.BottomCentre,
Anchor = Anchor.BottomCentre,
Height = progress_height,
FillColour = colours.Yellow,
OnSeek = attemptSeek
}
},
},
}
}
};
beatmapSets = beatmaps.GetAllUsableBeatmapSets();
beatmaps.ItemAdded += handleBeatmapAdded;
beatmaps.ItemRemoved += handleBeatmapRemoved;
playlist.State.ValueChanged += s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint);
}
private ScheduledDelegate seekDelegate;
private void attemptSeek(double progress)
protected override void LoadComplete()
{
seekDelegate?.Cancel();
seekDelegate = Schedule(() =>
{
if (!beatmap.Disabled)
current?.Track.Seek(progress);
});
beatmap.BindValueChanged(beatmapChanged, true);
mods.BindValueChanged(_ => updateAudioAdjustments(), true);
base.LoadComplete();
}
private void playlistOrderChanged(BeatmapSetInfo beatmapSetInfo, int index)
/// <summary>
/// Change the position of a <see cref="BeatmapSetInfo"/> in the current playlist.
/// </summary>
/// <param name="beatmapSetInfo">The beatmap to move.</param>
/// <param name="index">The new position.</param>
public void ChangeBeatmapSetPosition(BeatmapSetInfo beatmapSetInfo, int index)
{
beatmapSets.Remove(beatmapSetInfo);
beatmapSets.Insert(index, beatmapSetInfo);
}
private void handleBeatmapAdded(BeatmapSetInfo set) => Schedule(() => beatmapSets.Add(set));
/// <summary>
/// Returns whether the current beatmap track is playing.
/// </summary>
public bool IsPlaying => beatmap.Value.Track.IsRunning;
private void handleBeatmapRemoved(BeatmapSetInfo set) => Schedule(() => beatmapSets.RemoveAll(s => s.ID == set.ID));
private void handleBeatmapAdded(BeatmapSetInfo set) =>
Schedule(() => beatmapSets.Add(set));
protected override void LoadComplete()
private void handleBeatmapRemoved(BeatmapSetInfo set) =>
Schedule(() => beatmapSets.RemoveAll(s => s.ID == set.ID));
private ScheduledDelegate seekDelegate;
public void SeekTo(double position)
{
beatmap.BindValueChanged(beatmapChanged, true);
beatmap.BindDisabledChanged(beatmapDisabledChanged, true);
mods.BindValueChanged(_ => updateAudioAdjustments(), true);
base.LoadComplete();
}
private void beatmapDisabledChanged(bool disabled)
{
if (disabled)
playlist.Hide();
playButton.Enabled.Value = !disabled;
prevButton.Enabled.Value = !disabled;
nextButton.Enabled.Value = !disabled;
playlistButton.Enabled.Value = !disabled;
}
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
Height = dragContainer.Height;
dragContainer.Padding = new MarginPadding { Top = GetToolbarHeight?.Invoke() ?? 0 };
}
protected override void Update()
{
base.Update();
if (pendingBeatmapSwitch != null)
seekDelegate?.Cancel();
seekDelegate = Schedule(() =>
{
pendingBeatmapSwitch();
pendingBeatmapSwitch = null;
}
var track = current?.TrackLoaded ?? false ? current.Track : null;
if (track?.IsDummyDevice == false)
{
progressBar.EndTime = track.Length;
progressBar.CurrentTime = track.CurrentTime;
playButton.Icon = track.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle;
}
else
{
progressBar.CurrentTime = 0;
progressBar.EndTime = 1;
playButton.Icon = FontAwesome.Regular.PlayCircle;
}
if (!beatmap.Disabled)
current?.Track.Seek(position);
});
}
private void togglePause()
/// <summary>
/// Toggle pause / play.
/// </summary>
/// <returns>Whether the operation was successful.</returns>
public bool TogglePause()
{
var track = current?.Track;
if (track == null)
{
if (!beatmap.Disabled)
next(true);
return;
if (beatmap.Disabled)
return false;
next(true);
return true;
}
if (track.IsRunning)
@ -299,48 +119,70 @@ namespace osu.Game.Overlays
track.Start();
IsUserPaused = false;
}
return true;
}
private void prev()
/// <summary>
/// Play the previous track.
/// </summary>
/// <returns>Whether the operation was successful.</returns>
public bool PrevTrack()
{
queuedDirection = TransformDirection.Prev;
queuedDirection = TrackChangeDirection.Prev;
var playable = beatmapSets.TakeWhile(i => i.ID != current.BeatmapSetInfo.ID).LastOrDefault() ?? beatmapSets.LastOrDefault();
if (playable != null)
{
beatmap.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value);
if (beatmap is Bindable<WorkingBeatmap> working)
working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value);
beatmap.Value.Track.Restart();
return true;
}
return false;
}
private void next(bool instant = false)
/// <summary>
/// Play the next random or playlist track.
/// </summary>
/// <returns>Whether the operation was successful.</returns>
public bool NextTrack() => next();
private bool next(bool instant = false)
{
if (!instant)
queuedDirection = TransformDirection.Next;
queuedDirection = TrackChangeDirection.Next;
var playable = beatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? beatmapSets.FirstOrDefault();
if (playable != null)
{
beatmap.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value);
if (beatmap is Bindable<WorkingBeatmap> working)
working.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value);
beatmap.Value.Track.Restart();
return true;
}
return false;
}
private WorkingBeatmap current;
private TransformDirection? queuedDirection;
private TrackChangeDirection? queuedDirection;
private void beatmapChanged(ValueChangedEvent<WorkingBeatmap> beatmap)
{
TransformDirection direction = TransformDirection.None;
TrackChangeDirection direction = TrackChangeDirection.None;
if (current != null)
{
bool audioEquals = beatmap.NewValue?.BeatmapInfo?.AudioEquals(current.BeatmapInfo) ?? false;
if (audioEquals)
direction = TransformDirection.None;
direction = TrackChangeDirection.None;
else if (queuedDirection.HasValue)
{
direction = queuedDirection.Value;
@ -352,13 +194,13 @@ namespace osu.Game.Overlays
var last = beatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count();
var next = beatmap.NewValue == null ? -1 : beatmapSets.TakeWhile(b => b.ID != beatmap.NewValue.BeatmapSetInfo?.ID).Count();
direction = last > next ? TransformDirection.Prev : TransformDirection.Next;
direction = last > next ? TrackChangeDirection.Prev : TrackChangeDirection.Next;
}
}
progressBar.CurrentTime = 0;
current = beatmap.NewValue;
TrackChanged?.Invoke(current, direction);
updateDisplay(current = beatmap.NewValue, direction);
updateAudioAdjustments();
queuedDirection = null;
@ -376,167 +218,57 @@ namespace osu.Game.Overlays
mod.ApplyToClock(track);
}
private Action pendingBeatmapSwitch;
private void updateDisplay(WorkingBeatmap beatmap, TransformDirection direction)
protected override void Dispose(bool isDisposing)
{
// avoid using scheduler as our scheduler may not be run for a long time, holding references to beatmaps.
pendingBeatmapSwitch = delegate
base.Dispose(isDisposing);
if (beatmaps != null)
{
// todo: this can likely be replaced with WorkingBeatmap.GetBeatmapAsync()
Task.Run(() =>
{
if (beatmap?.Beatmap == null) //this is not needed if a placeholder exists
{
title.Text = @"Nothing to play";
artist.Text = @"Nothing to play";
}
else
{
BeatmapMetadata metadata = beatmap.Metadata;
title.Text = new LocalisedString((metadata.TitleUnicode, metadata.Title));
artist.Text = new LocalisedString((metadata.ArtistUnicode, metadata.Artist));
}
});
LoadComponentAsync(new Background(beatmap) { Depth = float.MaxValue }, newBackground =>
{
switch (direction)
{
case TransformDirection.Next:
newBackground.Position = new Vector2(400, 0);
newBackground.MoveToX(0, 500, Easing.OutCubic);
background.MoveToX(-400, 500, Easing.OutCubic);
break;
case TransformDirection.Prev:
newBackground.Position = new Vector2(-400, 0);
newBackground.MoveToX(0, 500, Easing.OutCubic);
background.MoveToX(400, 500, Easing.OutCubic);
break;
}
background.Expire();
background = newBackground;
playerContainer.Add(newBackground);
});
};
}
protected override void PopIn()
{
base.PopIn();
this.FadeIn(transition_length, Easing.OutQuint);
dragContainer.ScaleTo(1, transition_length, Easing.OutElastic);
}
protected override void PopOut()
{
base.PopOut();
this.FadeOut(transition_length, Easing.OutQuint);
dragContainer.ScaleTo(0.9f, transition_length, Easing.OutQuint);
}
private enum TransformDirection
{
None,
Next,
Prev
}
private class MusicIconButton : IconButton
{
public MusicIconButton()
{
AutoSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
HoverColour = colours.YellowDark.Opacity(0.6f);
FlashColour = colours.Yellow;
}
protected override void LoadComplete()
{
base.LoadComplete();
// works with AutoSizeAxes above to make buttons autosize with the scale animation.
Content.AutoSizeAxes = Axes.None;
Content.Size = new Vector2(DEFAULT_BUTTON_SIZE);
beatmaps.ItemAdded -= handleBeatmapAdded;
beatmaps.ItemRemoved -= handleBeatmapRemoved;
}
}
private class Background : BufferedContainer
public bool OnPressed(GlobalAction action)
{
private readonly Sprite sprite;
private readonly WorkingBeatmap beatmap;
public Background(WorkingBeatmap beatmap = null)
switch (action)
{
this.beatmap = beatmap;
CacheDrawnFrameBuffer = true;
Depth = float.MaxValue;
RelativeSizeAxes = Axes.Both;
case GlobalAction.MusicPlay:
if (TogglePause())
onScreenDisplay?.Display(new MusicControllerToast(IsPlaying ? "Play track" : "Pause track"));
return true;
Children = new Drawable[]
{
sprite = new Sprite
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(150),
FillMode = FillMode.Fill,
},
new Box
{
RelativeSizeAxes = Axes.X,
Height = bottom_black_area_height,
Origin = Anchor.BottomCentre,
Anchor = Anchor.BottomCentre,
Colour = Color4.Black.Opacity(0.5f)
}
};
case GlobalAction.MusicNext:
if (NextTrack())
onScreenDisplay?.Display(new MusicControllerToast("Next track"));
return true;
case GlobalAction.MusicPrev:
if (PrevTrack())
onScreenDisplay?.Display(new MusicControllerToast("Previous track"));
return true;
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4");
}
return false;
}
private class DragContainer : Container
public bool OnReleased(GlobalAction action) => false;
public class MusicControllerToast : Toast
{
protected override bool OnDragStart(DragStartEvent e)
public MusicControllerToast(string action)
: base("Music Playback", action, string.Empty)
{
return true;
}
protected override bool OnDrag(DragEvent e)
{
Vector2 change = e.MousePosition - e.MouseDownPosition;
// Diminish the drag distance as we go further to simulate "rubber band" feeling.
change *= change.Length <= 0 ? 0 : (float)Math.Pow(change.Length, 0.7f) / change.Length;
this.MoveTo(change);
return true;
}
protected override bool OnDragEnd(DragEndEvent e)
{
this.MoveTo(Vector2.Zero, 800, Easing.OutElastic);
return base.OnDragEnd(e);
}
}
}
/// <summary>
/// Play the next random or playlist track.
/// </summary>
public void NextTrack() => next();
public enum TrackChangeDirection
{
None,
Next,
Prev
}
}

View File

@ -0,0 +1,404 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Music;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays
{
public class NowPlayingOverlay : OsuFocusedOverlayContainer
{
private const float player_height = 130;
private const float transition_length = 800;
private const float progress_height = 10;
private const float bottom_black_area_height = 55;
private Drawable background;
private ProgressBar progressBar;
private IconButton prevButton;
private IconButton playButton;
private IconButton nextButton;
private IconButton playlistButton;
private SpriteText title, artist;
private PlaylistOverlay playlist;
private Container dragContainer;
private Container playerContainer;
/// <summary>
/// Provide a source for the toolbar height.
/// </summary>
public Func<float> GetToolbarHeight;
[Resolved]
private MusicController musicController { get; set; }
[Resolved]
private Bindable<WorkingBeatmap> beatmap { get; set; }
public NowPlayingOverlay()
{
Width = 400;
Margin = new MarginPadding(10);
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Children = new Drawable[]
{
dragContainer = new DragContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
playlist = new PlaylistOverlay
{
RelativeSizeAxes = Axes.X,
Y = player_height + 10,
OrderChanged = musicController.ChangeBeatmapSetPosition
},
playerContainer = new Container
{
RelativeSizeAxes = Axes.X,
Height = player_height,
Masking = true,
CornerRadius = 5,
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Shadow,
Colour = Color4.Black.Opacity(40),
Radius = 5,
},
Children = new[]
{
background = new Background(),
title = new OsuSpriteText
{
Origin = Anchor.BottomCentre,
Anchor = Anchor.TopCentre,
Position = new Vector2(0, 40),
Font = OsuFont.GetFont(size: 25, italics: true),
Colour = Color4.White,
Text = @"Nothing to play",
},
artist = new OsuSpriteText
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Position = new Vector2(0, 45),
Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold, italics: true),
Colour = Color4.White,
Text = @"Nothing to play",
},
new Container
{
Padding = new MarginPadding { Bottom = progress_height },
Height = bottom_black_area_height,
RelativeSizeAxes = Axes.X,
Origin = Anchor.BottomCentre,
Anchor = Anchor.BottomCentre,
Children = new Drawable[]
{
new FillFlowContainer<IconButton>
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5),
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Children = new[]
{
prevButton = new MusicIconButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Action = () => musicController.PrevTrack(),
Icon = FontAwesome.Solid.StepBackward,
},
playButton = new MusicIconButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(1.4f),
IconScale = new Vector2(1.4f),
Action = () => musicController.TogglePause(),
Icon = FontAwesome.Regular.PlayCircle,
},
nextButton = new MusicIconButton
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Action = () => musicController.NextTrack(),
Icon = FontAwesome.Solid.StepForward,
},
}
},
playlistButton = new MusicIconButton
{
Origin = Anchor.Centre,
Anchor = Anchor.CentreRight,
Position = new Vector2(-bottom_black_area_height / 2, 0),
Icon = FontAwesome.Solid.Bars,
Action = () => playlist.ToggleVisibility(),
},
}
},
progressBar = new ProgressBar
{
Origin = Anchor.BottomCentre,
Anchor = Anchor.BottomCentre,
Height = progress_height,
FillColour = colours.Yellow,
OnSeek = musicController.SeekTo
}
},
},
}
}
};
playlist.State.ValueChanged += s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint);
}
protected override void LoadComplete()
{
base.LoadComplete();
beatmap.BindDisabledChanged(beatmapDisabledChanged, true);
musicController.TrackChanged += trackChanged;
trackChanged(beatmap.Value);
}
protected override void PopIn()
{
base.PopIn();
this.FadeIn(transition_length, Easing.OutQuint);
dragContainer.ScaleTo(1, transition_length, Easing.OutElastic);
}
protected override void PopOut()
{
base.PopOut();
this.FadeOut(transition_length, Easing.OutQuint);
dragContainer.ScaleTo(0.9f, transition_length, Easing.OutQuint);
}
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
Height = dragContainer.Height;
dragContainer.Padding = new MarginPadding { Top = GetToolbarHeight?.Invoke() ?? 0 };
}
protected override void Update()
{
base.Update();
if (pendingBeatmapSwitch != null)
{
pendingBeatmapSwitch();
pendingBeatmapSwitch = null;
}
var track = beatmap.Value?.TrackLoaded ?? false ? beatmap.Value.Track : null;
if (track?.IsDummyDevice == false)
{
progressBar.EndTime = track.Length;
progressBar.CurrentTime = track.CurrentTime;
playButton.Icon = track.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle;
}
else
{
progressBar.CurrentTime = 0;
progressBar.EndTime = 1;
playButton.Icon = FontAwesome.Regular.PlayCircle;
}
}
private Action pendingBeatmapSwitch;
private void trackChanged(WorkingBeatmap beatmap, TrackChangeDirection direction = TrackChangeDirection.None)
{
// avoid using scheduler as our scheduler may not be run for a long time, holding references to beatmaps.
pendingBeatmapSwitch = delegate
{
// todo: this can likely be replaced with WorkingBeatmap.GetBeatmapAsync()
Task.Run(() =>
{
if (beatmap?.Beatmap == null) //this is not needed if a placeholder exists
{
title.Text = @"Nothing to play";
artist.Text = @"Nothing to play";
}
else
{
BeatmapMetadata metadata = beatmap.Metadata;
title.Text = new LocalisedString((metadata.TitleUnicode, metadata.Title));
artist.Text = new LocalisedString((metadata.ArtistUnicode, metadata.Artist));
}
});
LoadComponentAsync(new Background(beatmap) { Depth = float.MaxValue }, newBackground =>
{
switch (direction)
{
case TrackChangeDirection.Next:
newBackground.Position = new Vector2(400, 0);
newBackground.MoveToX(0, 500, Easing.OutCubic);
background.MoveToX(-400, 500, Easing.OutCubic);
break;
case TrackChangeDirection.Prev:
newBackground.Position = new Vector2(-400, 0);
newBackground.MoveToX(0, 500, Easing.OutCubic);
background.MoveToX(400, 500, Easing.OutCubic);
break;
}
background.Expire();
background = newBackground;
playerContainer.Add(newBackground);
});
};
}
private void beatmapDisabledChanged(bool disabled)
{
if (disabled)
playlist.Hide();
playButton.Enabled.Value = !disabled;
prevButton.Enabled.Value = !disabled;
nextButton.Enabled.Value = !disabled;
playlistButton.Enabled.Value = !disabled;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (musicController != null)
musicController.TrackChanged -= trackChanged;
}
private class MusicIconButton : IconButton
{
public MusicIconButton()
{
AutoSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
HoverColour = colours.YellowDark.Opacity(0.6f);
FlashColour = colours.Yellow;
}
protected override void LoadComplete()
{
base.LoadComplete();
// works with AutoSizeAxes above to make buttons autosize with the scale animation.
Content.AutoSizeAxes = Axes.None;
Content.Size = new Vector2(DEFAULT_BUTTON_SIZE);
}
}
private class Background : BufferedContainer
{
private readonly Sprite sprite;
private readonly WorkingBeatmap beatmap;
public Background(WorkingBeatmap beatmap = null)
{
this.beatmap = beatmap;
CacheDrawnFrameBuffer = true;
Depth = float.MaxValue;
RelativeSizeAxes = Axes.Both;
Children = new Drawable[]
{
sprite = new Sprite
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(150),
FillMode = FillMode.Fill,
},
new Box
{
RelativeSizeAxes = Axes.X,
Height = bottom_black_area_height,
Origin = Anchor.BottomCentre,
Anchor = Anchor.BottomCentre,
Colour = Color4.Black.Opacity(0.5f)
}
};
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4");
}
}
private class DragContainer : Container
{
protected override bool OnDragStart(DragStartEvent e)
{
return true;
}
protected override bool OnDrag(DragEvent e)
{
Vector2 change = e.MousePosition - e.MouseDownPosition;
// Diminish the drag distance as we go further to simulate "rubber band" feeling.
change *= change.Length <= 0 ? 0 : (float)Math.Pow(change.Length, 0.7f) / change.Length;
this.MoveTo(change);
return true;
}
protected override bool OnDragEnd(DragEndEvent e)
{
this.MoveTo(Vector2.Zero, 800, Easing.OutElastic);
return base.OnDragEnd(e);
}
}
}
}

View File

@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Toolbar
}
[BackgroundDependencyLoader(true)]
private void load(MusicController music)
private void load(NowPlayingOverlay music)
{
StateContainer = music;
}

View File

@ -15,7 +15,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.809.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.809.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.813.0" />
<PackageReference Include="SharpCompress" Version="0.23.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" />

View File

@ -3,7 +3,8 @@
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<DefaultMtouchExtraArgs>--nolinkaway -gcc_flags "-lstdc++ -framework AudioToolbox -framework SystemConfiguration -framework CFNetwork -framework Accelerate</DefaultMtouchExtraArgs>
<DefaultMtouchExtraArgs>--nolinkaway</DefaultMtouchExtraArgs>
<DefaultMtouchGccFlags>-lstdc++ -lbz2 -framework AudioToolbox -framework AVFoundation -framework CoreMedia -framework VideoToolbox -framework SystemConfiguration -framework CFNetwork -framework Accelerate</DefaultMtouchGccFlags>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols>
@ -24,7 +25,7 @@
<DeviceSpecificBuild>false</DeviceSpecificBuild>
<MtouchVerbosity></MtouchVerbosity>
<LangVersion>Default</LangVersion>
<MtouchExtraArgs>$(DefaultMtouchExtraArgs) -force_load $(OutputPath)\libbass.a -force_load $(OutputPath)\libbass_fx.a"</MtouchExtraArgs>
<MtouchExtraArgs>$(DefaultMtouchExtraArgs) -gcc_flags "$(DefaultMtouchGccFlags)"</MtouchExtraArgs>
<OptimizePNGs>false</OptimizePNGs>
<MtouchI18n>cjk,mideast,other,rare,west</MtouchI18n>
</PropertyGroup>
@ -44,7 +45,7 @@
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<MtouchVerbosity></MtouchVerbosity>
<LangVersion>Default</LangVersion>
<MtouchExtraArgs>$(DefaultMtouchExtraArgs) -force_load $(OutputPath)\libbass.a -force_load $(OutputPath)\libbass_fx.a"</MtouchExtraArgs>
<MtouchExtraArgs>$(DefaultMtouchExtraArgs) -gcc_flags "$(DefaultMtouchGccFlags)"</MtouchExtraArgs>
<OptimizePNGs>false</OptimizePNGs>
<MtouchI18n>cjk,mideast,other,rare,west</MtouchI18n>
</PropertyGroup>
@ -62,7 +63,7 @@
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<MtouchVerbosity></MtouchVerbosity>
<LangVersion>Default</LangVersion>
<MtouchExtraArgs>$(DefaultMtouchExtraArgs) -force_load $(OutputPath)\libbass.a -force_load $(OutputPath)\libbass_fx.a"</MtouchExtraArgs>
<MtouchExtraArgs>$(DefaultMtouchExtraArgs) -gcc_flags "$(DefaultMtouchGccFlags)"</MtouchExtraArgs>
<OptimizePNGs>false</OptimizePNGs>
<MtouchI18n>cjk,mideast,other,rare,west</MtouchI18n>
</PropertyGroup>
@ -86,10 +87,22 @@
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<MtouchVerbosity></MtouchVerbosity>
<LangVersion>Default</LangVersion>
<MtouchExtraArgs>$(DefaultMtouchExtraArgs) -force_load $(OutputPath)\libbass.a -force_load $(OutputPath)\libbass_fx.a"</MtouchExtraArgs>
<MtouchExtraArgs>$(DefaultMtouchExtraArgs) -gcc_flags "$(DefaultMtouchGccFlags)"</MtouchExtraArgs>
<OptimizePNGs>false</OptimizePNGs>
<MtouchI18n>cjk,mideast,other,rare,west</MtouchI18n>
</PropertyGroup>
<ItemGroup>
<NativeReference Include="$(OutputPath)\libbass.a;$(OutputPath)\libbass_fx.a">
<Kind>Static</Kind>
<SmartLink>False</SmartLink>
<ForceLoad>True</ForceLoad>
</NativeReference>
<NativeReference Include="$(OutputPath)\libavcodec.a;$(OutputPath)\libavdevice.a;$(OutputPath)\libavfilter.a;$(OutputPath)\libavformat.a;$(OutputPath)\libavutil.a;$(OutputPath)\libswresample.a;$(OutputPath)\libswscale.a">
<Kind>Static</Kind>
<SmartLink>False</SmartLink>
<ForceLoad>True</ForceLoad>
</NativeReference>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
@ -105,12 +118,12 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.809.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.809.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.809.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.813.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.813.0" />
<PackageReference Include="SharpCompress" Version="0.22.0" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
<PackageReference Include="ppy.osu.Framework.NativeLibs" Version="2019.307.0" ExcludeAssets="all" />
<PackageReference Include="ppy.osu.Framework.NativeLibs" Version="2019.813.0" ExcludeAssets="all" />
</ItemGroup>
</Project>

Binary file not shown.

Binary file not shown.

View File

@ -19,12 +19,6 @@
<ItemGroup>
<None Include="Info.plist" />
<None Include="Entitlements.plist" />
<None Include="libbass_fx.a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="libbass.a">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Compile Include="Application.cs" />