diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs new file mode 100644 index 0000000000..945de822a3 --- /dev/null +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -0,0 +1,62 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Timing; + +namespace osu.Game.Graphics.Containers +{ + public class BeatSyncedContainer : Container + { + /// + /// A new beat will not be sent if the time since the beat is larger than this tolerance. + /// + private const int seek_tolerance = 20; + + private readonly Bindable beatmap = new Bindable(); + + private int lastBeat; + private ControlPoint lastControlPoint; + + protected override void Update() + { + if (beatmap.Value?.Track == null) + return; + + double currentTrackTime = beatmap.Value.Track.CurrentTime; + ControlPoint overridePoint; + ControlPoint controlPoint = beatmap.Value.Beatmap.TimingInfo.TimingPointAt(currentTrackTime, out overridePoint); + + bool kiai = (overridePoint ?? controlPoint).KiaiMode; + int beat = controlPoint.BeatLength > 0 ? (int)((currentTrackTime - controlPoint.Time) / controlPoint.BeatLength) : 0; + + // The beats before the start of the first control point are off by 1, this should do the trick + if (currentTrackTime < controlPoint.Time) + beat--; + + if (controlPoint == lastControlPoint && beat == lastBeat) + return; + + if ((currentTrackTime - controlPoint.Time) % controlPoint.BeatLength > seek_tolerance) + return; + + OnNewBeat(beat, controlPoint.BeatLength, controlPoint.TimeSignature, kiai); + + lastBeat = beat; + lastControlPoint = controlPoint; + } + + protected virtual void OnNewBeat(int newBeat, double beatLength, TimeSignatures timeSignature, bool kiai) + { + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase game) + { + beatmap.BindTo(game.Beatmap); + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 1631311ef6..b94c19e1f8 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -292,6 +292,7 @@ +