2019-01-24 16:43:03 +08:00
|
|
|
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
|
|
|
// See the LICENCE file in the repository root for full licence text.
|
2018-04-13 17:19:50 +08:00
|
|
|
|
|
2022-06-17 15:37:17 +08:00
|
|
|
|
#nullable disable
|
|
|
|
|
|
2018-03-11 01:11:25 +08:00
|
|
|
|
using System;
|
|
|
|
|
using NUnit.Framework;
|
|
|
|
|
using osu.Framework.Allocation;
|
2021-04-14 11:36:31 +08:00
|
|
|
|
using osu.Framework.Audio.Sample;
|
|
|
|
|
using osu.Framework.Bindables;
|
2023-04-29 15:06:08 +08:00
|
|
|
|
using osu.Framework.Extensions.ObjectExtensions;
|
2018-03-11 01:11:25 +08:00
|
|
|
|
using osu.Framework.Graphics;
|
2021-04-14 11:36:31 +08:00
|
|
|
|
using osu.Framework.Graphics.Containers;
|
2020-07-10 13:47:26 +08:00
|
|
|
|
using osu.Framework.Graphics.Shapes;
|
2021-04-14 11:36:31 +08:00
|
|
|
|
using osu.Framework.Graphics.Textures;
|
|
|
|
|
using osu.Framework.Input;
|
2021-09-16 21:41:35 +08:00
|
|
|
|
using osu.Framework.Input.Events;
|
2019-09-09 11:48:34 +08:00
|
|
|
|
using osu.Framework.Testing.Input;
|
2020-07-10 13:47:26 +08:00
|
|
|
|
using osu.Framework.Utils;
|
2021-04-14 11:36:31 +08:00
|
|
|
|
using osu.Game.Audio;
|
2020-02-14 11:30:11 +08:00
|
|
|
|
using osu.Game.Configuration;
|
2023-04-29 15:06:08 +08:00
|
|
|
|
using osu.Game.Rulesets.Osu.Configuration;
|
2021-04-14 11:36:31 +08:00
|
|
|
|
using osu.Game.Rulesets.Osu.Skinning;
|
2018-03-11 01:11:25 +08:00
|
|
|
|
using osu.Game.Rulesets.Osu.UI.Cursor;
|
2020-02-14 11:30:11 +08:00
|
|
|
|
using osu.Game.Screens.Play;
|
2021-04-14 11:36:31 +08:00
|
|
|
|
using osu.Game.Skinning;
|
2022-05-28 20:55:57 +08:00
|
|
|
|
using osu.Game.Tests.Gameplay;
|
2019-09-09 11:48:34 +08:00
|
|
|
|
using osuTK;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
|
2018-03-11 01:11:25 +08:00
|
|
|
|
namespace osu.Game.Rulesets.Osu.Tests
|
|
|
|
|
{
|
|
|
|
|
[TestFixture]
|
2020-04-07 14:38:29 +08:00
|
|
|
|
public partial class TestSceneGameplayCursor : OsuSkinnableTestScene
|
2018-03-11 01:11:25 +08:00
|
|
|
|
{
|
2020-02-14 11:30:11 +08:00
|
|
|
|
[Cached]
|
2021-10-02 01:22:23 +08:00
|
|
|
|
private GameplayState gameplayState;
|
2020-02-14 11:30:11 +08:00
|
|
|
|
|
2021-04-14 11:36:31 +08:00
|
|
|
|
private OsuCursorContainer lastContainer;
|
2020-02-14 11:30:11 +08:00
|
|
|
|
|
|
|
|
|
[Resolved]
|
|
|
|
|
private OsuConfigManager config { get; set; }
|
|
|
|
|
|
2020-07-10 13:47:26 +08:00
|
|
|
|
private Drawable background;
|
|
|
|
|
|
2023-04-29 15:06:08 +08:00
|
|
|
|
private readonly Bindable<bool> ripples = new Bindable<bool>();
|
|
|
|
|
|
2020-02-14 11:30:11 +08:00
|
|
|
|
public TestSceneGameplayCursor()
|
|
|
|
|
{
|
2021-10-02 01:22:23 +08:00
|
|
|
|
var ruleset = new OsuRuleset();
|
2022-05-28 20:55:57 +08:00
|
|
|
|
gameplayState = TestGameplayState.Create(ruleset);
|
2020-07-10 13:47:26 +08:00
|
|
|
|
|
|
|
|
|
AddStep("change background colour", () =>
|
|
|
|
|
{
|
|
|
|
|
background?.Expire();
|
|
|
|
|
|
|
|
|
|
Add(background = new Box
|
|
|
|
|
{
|
|
|
|
|
RelativeSizeAxes = Axes.Both,
|
|
|
|
|
Depth = float.MaxValue,
|
|
|
|
|
Colour = new Colour4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1)
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2023-04-29 15:06:08 +08:00
|
|
|
|
AddToggleStep("ripples", v => ripples.Value = v);
|
|
|
|
|
|
2020-07-10 13:47:26 +08:00
|
|
|
|
AddSliderStep("circle size", 0f, 10f, 0f, val =>
|
|
|
|
|
{
|
2021-03-17 15:10:16 +08:00
|
|
|
|
config.SetValue(OsuSetting.AutoCursorSize, true);
|
2021-10-02 11:34:29 +08:00
|
|
|
|
gameplayState.Beatmap.Difficulty.CircleSize = val;
|
2021-10-14 16:52:19 +08:00
|
|
|
|
Scheduler.AddOnce(loadContent);
|
2020-07-10 13:47:26 +08:00
|
|
|
|
});
|
|
|
|
|
|
2021-04-14 11:36:31 +08:00
|
|
|
|
AddStep("test cursor container", () => loadContent(false));
|
2020-02-14 11:30:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-29 15:06:08 +08:00
|
|
|
|
[BackgroundDependencyLoader]
|
|
|
|
|
private void load()
|
|
|
|
|
{
|
|
|
|
|
var rulesetConfig = (OsuRulesetConfigManager)RulesetConfigs.GetConfigFor(Ruleset.Value.CreateInstance()).AsNonNull();
|
|
|
|
|
rulesetConfig.BindWith(OsuRulesetSetting.ShowCursorRipples, ripples);
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-14 11:30:11 +08:00
|
|
|
|
[TestCase(1, 1)]
|
|
|
|
|
[TestCase(5, 1)]
|
|
|
|
|
[TestCase(10, 1)]
|
|
|
|
|
[TestCase(1, 1.5f)]
|
|
|
|
|
[TestCase(5, 1.5f)]
|
|
|
|
|
[TestCase(10, 1.5f)]
|
|
|
|
|
public void TestSizing(int circleSize, float userScale)
|
|
|
|
|
{
|
2021-03-17 15:10:16 +08:00
|
|
|
|
AddStep($"set user scale to {userScale}", () => config.SetValue(OsuSetting.GameplayCursorSize, userScale));
|
2021-10-02 11:34:29 +08:00
|
|
|
|
AddStep($"adjust cs to {circleSize}", () => gameplayState.Beatmap.Difficulty.CircleSize = circleSize);
|
2021-03-17 15:10:16 +08:00
|
|
|
|
AddStep("turn on autosizing", () => config.SetValue(OsuSetting.AutoCursorSize, true));
|
2020-02-14 11:30:11 +08:00
|
|
|
|
|
2021-10-14 16:52:19 +08:00
|
|
|
|
AddStep("load content", loadContent);
|
2020-02-14 11:30:11 +08:00
|
|
|
|
|
2023-11-06 23:35:30 +08:00
|
|
|
|
AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.CursorScale.Value == OsuCursor.GetScaleForCircleSize(circleSize) * userScale);
|
2020-02-14 11:30:11 +08:00
|
|
|
|
|
2021-03-17 15:10:16 +08:00
|
|
|
|
AddStep("set user scale to 1", () => config.SetValue(OsuSetting.GameplayCursorSize, 1f));
|
2023-11-06 23:35:30 +08:00
|
|
|
|
AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.CursorScale.Value == OsuCursor.GetScaleForCircleSize(circleSize));
|
2020-02-14 11:30:11 +08:00
|
|
|
|
|
2021-03-17 15:10:16 +08:00
|
|
|
|
AddStep("turn off autosizing", () => config.SetValue(OsuSetting.AutoCursorSize, false));
|
2023-11-06 23:35:30 +08:00
|
|
|
|
AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.CursorScale.Value == 1);
|
2020-02-14 11:30:11 +08:00
|
|
|
|
|
2021-03-17 15:10:16 +08:00
|
|
|
|
AddStep($"set user scale to {userScale}", () => config.SetValue(OsuSetting.GameplayCursorSize, userScale));
|
2023-11-06 23:35:30 +08:00
|
|
|
|
AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.CursorScale.Value == userScale);
|
2020-02-14 11:30:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-04-14 11:36:31 +08:00
|
|
|
|
[Test]
|
|
|
|
|
public void TestTopLeftOrigin()
|
|
|
|
|
{
|
|
|
|
|
AddStep("load content", () => loadContent(false, () => new SkinProvidingContainer(new TopLeftCursorSkin())));
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-14 16:52:19 +08:00
|
|
|
|
private void loadContent() => loadContent(false);
|
|
|
|
|
|
|
|
|
|
private void loadContent(bool automated, Func<SkinProvidingContainer> skinProvider = null)
|
2021-04-14 11:36:31 +08:00
|
|
|
|
{
|
2021-06-02 15:04:53 +08:00
|
|
|
|
SetContents(_ =>
|
2021-04-14 11:36:31 +08:00
|
|
|
|
{
|
|
|
|
|
var inputManager = automated ? (InputManager)new MovingCursorInputManager() : new OsuInputManager(new OsuRuleset().RulesetInfo);
|
|
|
|
|
var skinContainer = skinProvider?.Invoke() ?? new SkinProvidingContainer(null);
|
|
|
|
|
|
|
|
|
|
lastContainer = automated ? new ClickingCursorContainer() : new OsuCursorContainer();
|
|
|
|
|
|
|
|
|
|
return inputManager.WithChild(skinContainer.WithChild(lastContainer));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class TopLeftCursorSkin : ISkin
|
2018-03-11 01:11:25 +08:00
|
|
|
|
{
|
2022-11-09 15:04:56 +08:00
|
|
|
|
public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => null;
|
2021-04-14 11:36:31 +08:00
|
|
|
|
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => null;
|
|
|
|
|
public ISample GetSample(ISampleInfo sampleInfo) => null;
|
|
|
|
|
|
|
|
|
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup)
|
2019-08-30 12:58:17 +08:00
|
|
|
|
{
|
2021-04-14 11:36:31 +08:00
|
|
|
|
switch (lookup)
|
2019-09-09 11:48:34 +08:00
|
|
|
|
{
|
2021-04-14 11:36:31 +08:00
|
|
|
|
case OsuSkinConfiguration osuLookup:
|
|
|
|
|
if (osuLookup == OsuSkinConfiguration.CursorCentre)
|
2021-07-05 23:52:39 +08:00
|
|
|
|
return SkinUtils.As<TValue>(new BindableBool());
|
2021-04-14 11:36:31 +08:00
|
|
|
|
|
|
|
|
|
break;
|
2019-09-09 11:48:34 +08:00
|
|
|
|
}
|
2021-04-14 11:36:31 +08:00
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2018-03-11 01:11:25 +08:00
|
|
|
|
}
|
2019-09-09 11:48:34 +08:00
|
|
|
|
|
2019-09-09 12:01:40 +08:00
|
|
|
|
private partial class ClickingCursorContainer : OsuCursorContainer
|
|
|
|
|
{
|
2020-07-10 13:47:11 +08:00
|
|
|
|
private bool pressed;
|
|
|
|
|
|
|
|
|
|
public bool Pressed
|
|
|
|
|
{
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (value == pressed)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
pressed = value;
|
|
|
|
|
if (value)
|
2024-05-27 17:23:32 +08:00
|
|
|
|
OnPressed(new KeyBindingPressEvent<OsuAction>(GetContainingInputManager()!.CurrentState, OsuAction.LeftButton));
|
2020-07-10 13:47:11 +08:00
|
|
|
|
else
|
2024-05-27 17:23:32 +08:00
|
|
|
|
OnReleased(new KeyBindingReleaseEvent<OsuAction>(GetContainingInputManager()!.CurrentState, OsuAction.LeftButton));
|
2020-07-10 13:47:11 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-09 12:01:40 +08:00
|
|
|
|
protected override void Update()
|
|
|
|
|
{
|
|
|
|
|
base.Update();
|
2020-07-10 13:47:11 +08:00
|
|
|
|
Pressed = ((int)(Time.Current / 1000)) % 2 == 0;
|
2019-09-09 12:01:40 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-09 11:48:34 +08:00
|
|
|
|
private partial class MovingCursorInputManager : ManualInputManager
|
|
|
|
|
{
|
|
|
|
|
public MovingCursorInputManager()
|
|
|
|
|
{
|
|
|
|
|
UseParentInput = false;
|
2020-07-10 13:46:49 +08:00
|
|
|
|
ShowVisualCursorGuide = false;
|
2019-09-09 11:48:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Update()
|
|
|
|
|
{
|
|
|
|
|
base.Update();
|
|
|
|
|
|
|
|
|
|
const double spin_duration = 5000;
|
|
|
|
|
double currentTime = Time.Current;
|
|
|
|
|
|
|
|
|
|
double angle = (currentTime % spin_duration) / spin_duration * 2 * Math.PI;
|
|
|
|
|
Vector2 rPos = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
|
|
|
|
|
|
|
|
|
|
MoveMouseTo(ToScreenSpace(DrawSize / 2 + DrawSize / 3 * rPos));
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-03-11 01:11:25 +08:00
|
|
|
|
}
|
|
|
|
|
}
|