1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 12:22:56 +08:00

Merge pull request #14776 from peppy/fix-pause-with-audio-offset

Avoid accounting for the pause pitch adjust effect when "fixing" hardware offset adjustments
This commit is contained in:
Dan Balasescu 2021-09-28 18:44:22 +09:00 committed by GitHub
commit 625711e6d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 5 deletions

View File

@ -3,10 +3,12 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Configuration;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Cursor;
using osu.Game.Rulesets;
@ -39,6 +41,45 @@ namespace osu.Game.Tests.Visual.Gameplay
confirmClockRunning(true);
}
[Test]
public void TestPauseWithLargeOffset()
{
double lastTime;
bool alwaysGoingForward = true;
AddStep("force large offset", () =>
{
var offset = (BindableDouble)LocalConfig.GetBindable<double>(OsuSetting.AudioOffset);
// use a large negative offset to avoid triggering a fail from forwards seeking.
offset.MinValue = -5000;
offset.Value = -5000;
});
AddStep("add time forward check hook", () =>
{
lastTime = double.MinValue;
alwaysGoingForward = true;
Player.OnUpdate += _ =>
{
double currentTime = Player.GameplayClockContainer.CurrentTime;
alwaysGoingForward &= currentTime >= lastTime;
lastTime = currentTime;
};
});
AddStep("move cursor outside", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.TopLeft - new Vector2(10)));
pauseAndConfirm();
resumeAndConfirm();
AddAssert("time didn't go backwards", () => alwaysGoingForward);
AddStep("reset offset", () => LocalConfig.SetValue(OsuSetting.AudioOffset, 0.0));
}
[Test]
public void TestPauseResume()
{

View File

@ -158,10 +158,10 @@ namespace osu.Game.Screens.Play
{
// Lazer's audio timings in general doesn't match stable. This is the result of user testing, albeit limited.
// This only seems to be required on windows. We need to eventually figure out why, with a bit of luck.
platformOffsetClock = new HardwareCorrectionOffsetClock(source) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 15 : 0 };
platformOffsetClock = new HardwareCorrectionOffsetClock(source, pauseFreqAdjust) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 15 : 0 };
// the final usable gameplay clock with user-set offsets applied.
userOffsetClock = new HardwareCorrectionOffsetClock(platformOffsetClock);
userOffsetClock = new HardwareCorrectionOffsetClock(platformOffsetClock, pauseFreqAdjust);
return masterGameplayClock = new MasterGameplayClock(userOffsetClock);
}
@ -216,11 +216,25 @@ namespace osu.Game.Screens.Play
{
// we always want to apply the same real-time offset, so it should be adjusted by the difference in playback rate (from realtime) to achieve this.
// base implementation already adds offset at 1.0 rate, so we only add the difference from that here.
public override double CurrentTime => base.CurrentTime + Offset * (Rate - 1);
public override double CurrentTime => base.CurrentTime + offsetAdjust;
public HardwareCorrectionOffsetClock(IClock source, bool processSource = true)
: base(source, processSource)
private readonly BindableDouble pauseRateAdjust;
private double offsetAdjust;
public HardwareCorrectionOffsetClock(IClock source, BindableDouble pauseRateAdjust)
: base(source)
{
this.pauseRateAdjust = pauseRateAdjust;
}
public override void ProcessFrame()
{
base.ProcessFrame();
// changing this during the pause transform effect will cause a potentially large offset to be suddenly applied as we approach zero rate.
if (pauseRateAdjust.Value == 1)
offsetAdjust = Offset * (Rate - 1);
}
}