Skip to content

Commit

Permalink
Merge branch 'master' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
peppy committed Jun 20, 2023
2 parents 9b3ab2f + c815f8c commit 88e2fa3
Show file tree
Hide file tree
Showing 236 changed files with 2,428 additions and 955 deletions.
2 changes: 1 addition & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
]
},
"codefilesanity": {
"version": "0.0.36",
"version": "0.0.37",
"commands": [
"CodeFileSanity"
]
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ blank_issues_enabled: false
contact_links:
- name: Help
url: https://github.com/ppy/osu/discussions/categories/q-a
about: osu! not working as you'd expect? Not sure it's a bug? Check the Q&A section!
about: osu! not working or performing as you'd expect? Not sure it's a bug? Check the Q&A section!
- name: Suggestions or feature request
url: https://github.com/ppy/osu/discussions/categories/ideas
about: Got something you think should change or be added? Search for or start a new discussion!
Expand Down
2 changes: 1 addition & 1 deletion osu.Android.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<AndroidManifestMerger>manifestmerger.jar</AndroidManifestMerger>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.608.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.620.0" />
</ItemGroup>
<ItemGroup>
<AndroidManifestOverlay Include="$(MSBuildThisFileDirectory)osu.Android\Properties\AndroidManifestOverlay.xml" />
Expand Down
45 changes: 0 additions & 45 deletions osu.Desktop/OsuGameDesktop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using Microsoft.Win32;
using osu.Desktop.Security;
using osu.Framework.Platform;
Expand All @@ -17,7 +15,6 @@
using osu.Framework.Logging;
using osu.Game.Updater;
using osu.Desktop.Windows;
using osu.Framework.Threading;
using osu.Game.IO;
using osu.Game.IPC;
using osu.Game.Utils;
Expand Down Expand Up @@ -138,52 +135,10 @@ public override void SetHost(GameHost host)

desktopWindow.CursorState |= CursorState.Hidden;
desktopWindow.Title = Name;
desktopWindow.DragDrop += f =>
{
// on macOS, URL associations are handled via SDL_DROPFILE events.
if (f.StartsWith(OSU_PROTOCOL, StringComparison.Ordinal))
{
HandleLink(f);
return;
}

fileDrop(new[] { f });
};
}

protected override BatteryInfo CreateBatteryInfo() => new SDL2BatteryInfo();

private readonly List<string> importableFiles = new List<string>();
private ScheduledDelegate? importSchedule;

private void fileDrop(string[] filePaths)
{
lock (importableFiles)
{
importableFiles.AddRange(filePaths);

Logger.Log($"Adding {filePaths.Length} files for import");

// File drag drop operations can potentially trigger hundreds or thousands of these calls on some platforms.
// In order to avoid spawning multiple import tasks for a single drop operation, debounce a touch.
importSchedule?.Cancel();
importSchedule = Scheduler.AddDelayed(handlePendingImports, 100);
}
}

private void handlePendingImports()
{
lock (importableFiles)
{
Logger.Log($"Handling batch import of {importableFiles.Count} files");

string[] paths = importableFiles.ToArray();
importableFiles.Clear();

Task.Factory.StartNew(() => Import(paths), TaskCreationOptions.LongRunning);
}
}

protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
Expand Down
180 changes: 180 additions & 0 deletions osu.Game.Rulesets.Catch/Edit/CatchBeatSnapGrid.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. 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 osu.Framework.Allocation;
using osu.Framework.Caching;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Screens.Edit;
using osuTK.Graphics;

namespace osu.Game.Rulesets.Catch.Edit
{
/// <summary>
/// A grid which displays coloured beat divisor lines in proximity to the selection or placement cursor.
/// </summary>
/// <remarks>
/// This class heavily borrows from osu!mania's implementation (ManiaBeatSnapGrid).
/// If further changes are to be made, they should also be applied there.
/// If the scale of the changes are large enough, abstracting may be a good path.
/// </remarks>
public partial class CatchBeatSnapGrid : Component
{
private const double visible_range = 750;

/// <summary>
/// The range of time values of the current selection.
/// </summary>
public (double start, double end)? SelectionTimeRange
{
set
{
if (value == selectionTimeRange)
return;

selectionTimeRange = value;
lineCache.Invalidate();
}
}

[Resolved]
private EditorBeatmap beatmap { get; set; } = null!;

[Resolved]
private OsuColour colours { get; set; } = null!;

[Resolved]
private BindableBeatDivisor beatDivisor { get; set; } = null!;

private readonly Cached lineCache = new Cached();

private (double start, double end)? selectionTimeRange;

private ScrollingHitObjectContainer lineContainer = null!;

[BackgroundDependencyLoader]
private void load(HitObjectComposer composer)
{
lineContainer = new ScrollingHitObjectContainer();

((CatchPlayfield)composer.Playfield).UnderlayElements.Add(lineContainer);

beatDivisor.BindValueChanged(_ => createLines(), true);
}

protected override void Update()
{
base.Update();

if (!lineCache.IsValid)
{
lineCache.Validate();
createLines();
}
}

private readonly Stack<DrawableGridLine> availableLines = new Stack<DrawableGridLine>();

private void createLines()
{
foreach (var line in lineContainer.Objects.OfType<DrawableGridLine>())
availableLines.Push(line);

lineContainer.Clear();

if (selectionTimeRange == null)
return;

var range = selectionTimeRange.Value;

var timingPoint = beatmap.ControlPointInfo.TimingPointAt(range.start - visible_range);

double time = timingPoint.Time;
int beat = 0;

// progress time until in the visible range.
while (time < range.start - visible_range)
{
time += timingPoint.BeatLength / beatDivisor.Value;
beat++;
}

while (time < range.end + visible_range)
{
var nextTimingPoint = beatmap.ControlPointInfo.TimingPointAt(time);

// switch to the next timing point if we have reached it.
if (nextTimingPoint.Time > timingPoint.Time)
{
beat = 0;
time = nextTimingPoint.Time;
timingPoint = nextTimingPoint;
}

Color4 colour = BindableBeatDivisor.GetColourFor(
BindableBeatDivisor.GetDivisorForBeatIndex(beat, beatDivisor.Value), colours);

if (!availableLines.TryPop(out var line))
line = new DrawableGridLine();

line.HitObject.StartTime = time;
line.Colour = colour;

lineContainer.Add(line);

beat++;
time += timingPoint.BeatLength / beatDivisor.Value;
}

// required to update ScrollingHitObjectContainer's cache.
lineContainer.UpdateSubTree();

foreach (var line in lineContainer.Objects.OfType<DrawableGridLine>())
{
time = line.HitObject.StartTime;

if (time >= range.start && time <= range.end)
line.Alpha = 1;
else
{
double timeSeparation = time < range.start ? range.start - time : time - range.end;
line.Alpha = (float)Math.Max(0, 1 - timeSeparation / visible_range);
}
}
}

private partial class DrawableGridLine : DrawableHitObject
{
public DrawableGridLine()
: base(new HitObject())
{
RelativeSizeAxes = Axes.X;
Height = 2;

AddInternal(new Box { RelativeSizeAxes = Axes.Both });
}

[BackgroundDependencyLoader]
private void load()
{
Origin = Anchor.BottomLeft;
Anchor = Anchor.BottomLeft;
}

protected override void UpdateInitialTransforms()
{
// don't perform any fading – we are handling that ourselves.
LifetimeEnd = HitObject.StartTime + visible_range;
}
}
}
}
27 changes: 27 additions & 0 deletions osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public partial class CatchHitObjectComposer : DistancedHitObjectComposer<CatchHi

private InputManager inputManager = null!;

private CatchBeatSnapGrid beatSnapGrid = null!;

private readonly BindableDouble timeRangeMultiplier = new BindableDouble(1)
{
MinValue = 1,
Expand Down Expand Up @@ -65,6 +67,8 @@ private void load()
Catcher.BASE_DASH_SPEED, -Catcher.BASE_DASH_SPEED,
Catcher.BASE_WALK_SPEED, -Catcher.BASE_WALK_SPEED,
}));

AddInternal(beatSnapGrid = new CatchBeatSnapGrid());
}

protected override void LoadComplete()
Expand All @@ -74,6 +78,29 @@ protected override void LoadComplete()
inputManager = GetContainingInputManager();
}

protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();

if (BlueprintContainer.CurrentTool is SelectTool)
{
if (EditorBeatmap.SelectedHitObjects.Any())
{
beatSnapGrid.SelectionTimeRange = (EditorBeatmap.SelectedHitObjects.Min(h => h.StartTime), EditorBeatmap.SelectedHitObjects.Max(h => h.GetEndTime()));
}
else
beatSnapGrid.SelectionTimeRange = null;
}
else
{
var result = FindSnappedPositionAndTime(inputManager.CurrentState.Mouse.Position);
if (result.Time is double time)
beatSnapGrid.SelectionTimeRange = (time, time);
else
beatSnapGrid.SelectionTimeRange = null;
}
}

protected override double ReadCurrentDistanceSnap(HitObject before, HitObject after)
{
// osu!catch's distance snap implementation is limited, in that a custom spacing cannot be specified.
Expand Down
7 changes: 7 additions & 0 deletions osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawables;
Expand Down Expand Up @@ -41,6 +42,8 @@ public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) =>

internal CatcherArea CatcherArea { get; private set; } = null!;

public Container UnderlayElements { get; private set; } = null!;

private readonly IBeatmapDifficultyInfo difficulty;

public CatchPlayfield(IBeatmapDifficultyInfo difficulty)
Expand All @@ -62,6 +65,10 @@ private void load()

AddRangeInternal(new[]
{
UnderlayElements = new Container
{
RelativeSizeAxes = Axes.Both,
},
droppedObjectContainer,
Catcher.CreateProxiedContent(),
HitObjectContainer.CreateProxy(),
Expand Down
Loading

0 comments on commit 88e2fa3

Please sign in to comment.