Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions osu.Game.Rulesets.Taiko/Mods/TaikoModSimplifiedRhythm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ void processPattern(int patternEndIndex)
}
}
}

taikoBeatmap.HitObjects.Sort((a, b) => a.StartTime.CompareTo(b.StartTime));
}

private int getSnapBetweenNotes(ControlPointInfo controlPointInfo, Hit currentNote, Hit nextNote)
Expand Down
12 changes: 12 additions & 0 deletions osu.Game.Tests/NonVisual/ClosestBeatDivisorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ public void TestApproximateDivisors()
assertClosestDivisors(divisors, closestDivisors, cpi);
}

[Test]
public void TestNegativeTimingPointOffset()
{
var cpi = new ControlPointInfo();
cpi.Add(-300000, new TimingControlPoint { BeatLength = 1000 });

double[] divisors = { 3.03d, 0.97d, 14, 13, 7.94d, 6.08d, 3.93d, 2.96d, 2.02d, 64 };
double[] closestDivisors = { 3, 1, 16, 12, 8, 6, 4, 3, 2, 1 };

assertClosestDivisors(divisors, closestDivisors, cpi);
}

private static void assertClosestDivisors(IReadOnlyList<double> divisors, IReadOnlyList<double> closestDivisors, ControlPointInfo cpi, double step = 1)
{
List<HitObject> hitobjects = new List<HitObject>();
Expand Down
16 changes: 13 additions & 3 deletions osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public void RemoveGroup(ControlPointGroup group)
public double GetClosestSnappedTime(double time, int beatDivisor, double? referenceTime = null)
{
var timingPoint = TimingPointAt(referenceTime ?? time);
double snappedTime = getClosestSnappedTime(timingPoint, time, beatDivisor);
double snappedTime = getClosestPositiveSnappedTime(timingPoint, time, beatDivisor);

if (referenceTime.HasValue)
return snappedTime;
Expand Down Expand Up @@ -197,9 +197,19 @@ public int GetClosestBeatDivisor(double time, double? referenceTime = null)
int closestDivisor = 0;
double closestTime = double.MaxValue;

// `getClosestSnappedTime()` only returns positive time values.
// due to that, if `time` is allowed to be negative, the loop lower below could return bogus results
// as the "snapped time" will not necessarily be "closest" at that point.
// compensate for this by moving `time` by enough beat lengths to go back to the positives.
if (time < 0)
{
int offsetBeats = (int)Math.Ceiling(-time / timingPoint.BeatLength);
time += offsetBeats * timingPoint.BeatLength;
}

foreach (int divisor in BindableBeatDivisor.PREDEFINED_DIVISORS)
{
double distanceFromSnap = Math.Abs(time - getClosestSnappedTime(timingPoint, time, divisor));
double distanceFromSnap = Math.Abs(time - getClosestPositiveSnappedTime(timingPoint, time, divisor));

if (Precision.DefinitelyBigger(closestTime, distanceFromSnap))
{
Expand All @@ -211,7 +221,7 @@ public int GetClosestBeatDivisor(double time, double? referenceTime = null)
return closestDivisor;
}

private static double getClosestSnappedTime(TimingControlPoint timingPoint, double time, int beatDivisor)
private static double getClosestPositiveSnappedTime(TimingControlPoint timingPoint, double time, int beatDivisor)
{
double beatLength = timingPoint.BeatLength / beatDivisor;
double beats = (Math.Max(time, 0) - timingPoint.Time) / beatLength;
Expand Down
Loading