1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-17 21:53:26 +08:00

Fix metronome BPM text not matching expectations due to custom rounding implementation

This commit is contained in:
Dean Herbert
2025-04-03 15:12:07 +09:00
Unverified
parent ac88220a3d
commit 11368b628b
2 changed files with 22 additions and 18 deletions
@@ -7,7 +7,6 @@ using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
@@ -20,7 +19,6 @@ using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Overlays;
using osu.Game.Utils;
using osuTK;
namespace osu.Game.Screens.Edit.Timing
@@ -217,7 +215,7 @@ namespace osu.Game.Screens.Edit.Timing
bpmText = new OsuTextFlowContainer(st =>
{
st.Font = OsuFont.Default.With(fixedWidth: true);
st.Spacing = new Vector2(-2.2f, 0);
st.Spacing = new Vector2(-1.9f, 0);
})
{
Name = @"BPM display",
@@ -233,8 +231,7 @@ namespace osu.Game.Screens.Edit.Timing
}
private double effectiveBeatLength;
private double effectiveBpm => 60_000 / effectiveBeatLength;
private double effectiveBpm;
private TimingControlPoint timingPoint = null!;
@@ -268,19 +265,25 @@ namespace osu.Game.Screens.Edit.Timing
private void updateBpmText()
{
int intPart = (int)interpolatedBpm.Value;
string text = interpolatedBpm.Value.ToString("N2");
int? breakPoint = null;
bpmText.Text = intPart.ToLocalisableString();
// While interpolating between two integer values, showing the decimal places would look a bit odd
// so rounding is applied until we're close to the final value.
int decimalPlaces = FormatUtils.FindPrecision((decimal)effectiveBpm);
if (decimalPlaces > 0)
for (int i = 0; i < text.Length; i++)
{
bool reachedFinalNumber = intPart == (int)effectiveBpm;
if (!char.IsDigit(text[i]))
breakPoint = i;
}
bpmText.AddText((effectiveBpm % 1).ToLocalisableString("." + new string('0', decimalPlaces)), cp => cp.Alpha = reachedFinalNumber ? 0.5f : 0.1f);
if (breakPoint != null)
{
bool reachedFinalNumber = (int)interpolatedBpm.Value == (int)effectiveBpm;
bpmText.Text = text.Substring(0, breakPoint.Value);
bpmText.AddText(text.Substring(breakPoint.Value), cp => cp.Alpha = reachedFinalNumber ? 0.5f : 0.2f);
}
else
{
bpmText.Text = text;
}
}
@@ -300,6 +303,7 @@ namespace osu.Game.Screens.Edit.Timing
if (effectiveBeatLength != timingPoint.BeatLength / Divisor)
{
effectiveBeatLength = timingPoint.BeatLength / Divisor;
effectiveBpm = TimingSection.BeatLengthToBpm(effectiveBeatLength);
EarlyActivationMilliseconds = timingPoint.BeatLength / 2;
@@ -115,7 +115,7 @@ namespace osu.Game.Screens.Edit.Timing
try
{
if (double.TryParse(Current.Value, out double doubleVal) && doubleVal > 0)
beatLengthBindable.Value = beatLengthToBpm(doubleVal);
beatLengthBindable.Value = BeatLengthToBpm(doubleVal);
}
catch
{
@@ -130,7 +130,7 @@ namespace osu.Game.Screens.Edit.Timing
beatLengthBindable.BindValueChanged(val =>
{
Current.Value = beatLengthToBpm(val.NewValue).ToString("N2");
Current.Value = BeatLengthToBpm(val.NewValue).ToString("N2");
}, true);
}
@@ -146,6 +146,6 @@ namespace osu.Game.Screens.Edit.Timing
}
}
private static double beatLengthToBpm(double beatLength) => 60000 / beatLength;
public static double BeatLengthToBpm(double beatLength) => 60000 / beatLength;
}
}