Skip to content

Commit

Permalink
Merge pull request #31368 from frenzibyte/mobile-fix-mania
Browse files Browse the repository at this point in the history
Improve osu!mania playability on mobile devices
  • Loading branch information
peppy authored Feb 1, 2025
2 parents 334b578 + cc3bb59 commit cf3a379
Show file tree
Hide file tree
Showing 28 changed files with 458 additions and 382 deletions.
34 changes: 0 additions & 34 deletions osu.Android/GameplayScreenRotationLocker.cs

This file was deleted.

6 changes: 4 additions & 2 deletions osu.Android/OsuGameActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class OsuGameActivity : AndroidGameActivity
/// <remarks>Adjusted on startup to match expected UX for the current device type (phone/tablet).</remarks>
public ScreenOrientation DefaultOrientation = ScreenOrientation.Unspecified;

public new bool IsTablet { get; private set; }

private readonly OsuGameAndroid game;

private bool gameCreated;
Expand Down Expand Up @@ -89,9 +91,9 @@ protected override void OnCreate(Bundle? savedInstanceState)
WindowManager.DefaultDisplay.GetSize(displaySize);
#pragma warning restore CA1422
float smallestWidthDp = Math.Min(displaySize.X, displaySize.Y) / Resources.DisplayMetrics.Density;
bool isTablet = smallestWidthDp >= 600f;
IsTablet = smallestWidthDp >= 600f;

RequestedOrientation = DefaultOrientation = isTablet ? ScreenOrientation.FullUser : ScreenOrientation.SensorLandscape;
RequestedOrientation = DefaultOrientation = IsTablet ? ScreenOrientation.FullUser : ScreenOrientation.SensorLandscape;

// Currently (SDK 6.0.200), BundleAssemblies is not runnable for net6-android.
// The assembly files are not available as files either after native AOT.
Expand Down
32 changes: 31 additions & 1 deletion osu.Android/OsuGameAndroid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@

using System;
using Android.App;
using Android.Content.PM;
using Microsoft.Maui.Devices;
using osu.Framework.Allocation;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Platform;
using osu.Game;
using osu.Game.Screens;
using osu.Game.Updater;
using osu.Game.Utils;

Expand Down Expand Up @@ -71,7 +73,35 @@ public override Version AssemblyVersion
protected override void LoadComplete()
{
base.LoadComplete();
LoadComponentAsync(new GameplayScreenRotationLocker(), Add);
UserPlayingState.BindValueChanged(_ => updateOrientation());
}

protected override void ScreenChanged(IOsuScreen? current, IOsuScreen? newScreen)
{
base.ScreenChanged(current, newScreen);

if (newScreen != null)
updateOrientation();
}

private void updateOrientation()
{
var orientation = MobileUtils.GetOrientation(this, (IOsuScreen)ScreenStack.CurrentScreen, gameActivity.IsTablet);

switch (orientation)
{
case MobileUtils.Orientation.Locked:
gameActivity.RequestedOrientation = ScreenOrientation.Locked;
break;

case MobileUtils.Orientation.Portrait:
gameActivity.RequestedOrientation = ScreenOrientation.Portrait;
break;

case MobileUtils.Orientation.Default:
gameActivity.RequestedOrientation = gameActivity.DefaultOrientation;
break;
}
}

public override void SetHost(GameHost host)
Expand Down
10 changes: 5 additions & 5 deletions osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFadeIn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void TestMinCoverageFullWidth()
{
CreateModTest(new ModTestData
{
Mod = new ManiaModHidden(),
Mod = new ManiaModFadeIn(),
PassCondition = () => checkCoverage(ManiaModHidden.MIN_COVERAGE)
});
}
Expand All @@ -36,7 +36,7 @@ public void TestMinCoverageHalfWidth()
{
CreateModTest(new ModTestData
{
Mod = new ManiaModHidden(),
Mod = new ManiaModFadeIn(),
PassCondition = () => checkCoverage(ManiaModHidden.MIN_COVERAGE)
});

Expand All @@ -48,7 +48,7 @@ public void TestMaxCoverageFullWidth()
{
CreateModTest(new ModTestData
{
Mod = new ManiaModHidden(),
Mod = new ManiaModFadeIn(),
PassCondition = () => checkCoverage(ManiaModHidden.MAX_COVERAGE)
});

Expand All @@ -60,7 +60,7 @@ public void TestMaxCoverageHalfWidth()
{
CreateModTest(new ModTestData
{
Mod = new ManiaModHidden(),
Mod = new ManiaModFadeIn(),
PassCondition = () => checkCoverage(ManiaModHidden.MAX_COVERAGE)
});

Expand All @@ -73,7 +73,7 @@ public void TestNoCoverageDuringBreak()
{
CreateModTest(new ModTestData
{
Mod = new ManiaModHidden(),
Mod = new ManiaModFadeIn(),
CreateBeatmap = () => new Beatmap
{
HitObjects = Enumerable.Range(1, 100).Select(i => (HitObject)new Note { StartTime = 1000 + 200 * i }).ToList(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,20 @@ private void load()
{
RelativeSizeAxes = Axes.Both,
Width = 0.5f,
Child = new ColumnHitObjectArea(new HitObjectContainer())
Child = new ColumnHitObjectArea
{
RelativeSizeAxes = Axes.Both
RelativeSizeAxes = Axes.Both,
Child = new HitObjectContainer(),
}
},
new ColumnTestContainer(1, ManiaAction.Key2)
{
RelativeSizeAxes = Axes.Both,
Width = 0.5f,
Child = new ColumnHitObjectArea(new HitObjectContainer())
Child = new ColumnHitObjectArea
{
RelativeSizeAxes = Axes.Both
RelativeSizeAxes = Axes.Both,
Child = new HitObjectContainer(),
}
}
}
Expand Down
68 changes: 68 additions & 0 deletions osu.Game.Rulesets.Mania.Tests/TestSceneManiaTouchInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// 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.

using System.Linq;
using NUnit.Framework;
using osu.Framework.Input;
using osu.Framework.Testing;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Tests.Visual;

namespace osu.Game.Rulesets.Mania.Tests
{
public partial class TestSceneManiaTouchInput : PlayerTestScene
{
protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset();

[Test]
public void TestTouchInput()
{
for (int i = 0; i < 4; i++)
{
int index = i;

AddStep($"touch column {index}", () => InputManager.BeginTouch(new Touch(TouchSource.Touch1, getColumn(index).ScreenSpaceDrawQuad.Centre)));

AddAssert("action sent",
() => this.ChildrenOfType<ManiaInputManager>().SelectMany(m => m.KeyBindingContainer.PressedActions),
() => Does.Contain(getColumn(index).Action.Value));

AddStep($"release column {index}", () => InputManager.EndTouch(new Touch(TouchSource.Touch1, getColumn(index).ScreenSpaceDrawQuad.Centre)));

AddAssert("action released",
() => this.ChildrenOfType<ManiaInputManager>().SelectMany(m => m.KeyBindingContainer.PressedActions),
() => Does.Not.Contain(getColumn(index).Action.Value));
}
}

[Test]
public void TestOneColumnMultipleTouches()
{
AddStep("touch column 0", () => InputManager.BeginTouch(new Touch(TouchSource.Touch1, getColumn(0).ScreenSpaceDrawQuad.Centre)));

AddAssert("action sent",
() => this.ChildrenOfType<ManiaInputManager>().SelectMany(m => m.KeyBindingContainer.PressedActions),
() => Does.Contain(getColumn(0).Action.Value));

AddStep("touch another finger", () => InputManager.BeginTouch(new Touch(TouchSource.Touch2, getColumn(0).ScreenSpaceDrawQuad.Centre)));

AddAssert("action still pressed",
() => this.ChildrenOfType<ManiaInputManager>().SelectMany(m => m.KeyBindingContainer.PressedActions),
() => Does.Contain(getColumn(0).Action.Value));

AddStep("release first finger", () => InputManager.EndTouch(new Touch(TouchSource.Touch1, getColumn(0).ScreenSpaceDrawQuad.Centre)));

AddAssert("action still pressed",
() => this.ChildrenOfType<ManiaInputManager>().SelectMany(m => m.KeyBindingContainer.PressedActions),
() => Does.Contain(getColumn(0).Action.Value));

AddStep("release second finger", () => InputManager.EndTouch(new Touch(TouchSource.Touch2, getColumn(0).ScreenSpaceDrawQuad.Centre)));

AddAssert("action released",
() => this.ChildrenOfType<ManiaInputManager>().SelectMany(m => m.KeyBindingContainer.PressedActions),
() => Does.Not.Contain(getColumn(0).Action.Value));
}

private Column getColumn(int index) => this.ChildrenOfType<Column>().ElementAt(index);
}
}
49 changes: 0 additions & 49 deletions osu.Game.Rulesets.Mania.Tests/TestSceneManiaTouchInputArea.cs

This file was deleted.

2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Mania/ManiaInputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace osu.Game.Rulesets.Mania
{
[Cached] // Used for touch input, see ColumnTouchInputArea.
[Cached] // Used for touch input, see Column.OnTouchDown/OnTouchUp.
public partial class ManiaInputManager : RulesetInputManager<ManiaAction>
{
public ManiaInputManager(RulesetInfo ruleset, int variant)
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Mania/Mods/ManiaModWithPlayfieldCover.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public virtual void ApplyToDrawableRuleset(DrawableRuleset<ManiaHitObject> drawa

foreach (Column column in maniaPlayfield.Stages.SelectMany(stage => stage.Columns))
{
HitObjectContainer hoc = column.HitObjectArea.HitObjectContainer;
HitObjectContainer hoc = column.HitObjectContainer;
Container hocParent = (Container)hoc.Parent!;

hocParent.Remove(hoc, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
{
public partial class ArgonJudgementPiece : TextJudgementPiece, IAnimatableJudgement
{
private const float judgement_y_position = 160;
private const float judgement_y_position = -180f;

private RingExplosion? ringExplosion;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using osu.Framework.Graphics.Containers;
using osu.Framework.Utils;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning;

Expand All @@ -23,7 +22,7 @@ public LegacyManiaJudgementPiece(HitResult result, Drawable animation)
this.result = result;
this.animation = animation;

Anchor = Anchor.Centre;
Anchor = Anchor.BottomCentre;
Origin = Anchor.Centre;

AutoSizeAxes = Axes.Both;
Expand All @@ -32,12 +31,11 @@ public LegacyManiaJudgementPiece(HitResult result, Drawable animation)
[BackgroundDependencyLoader]
private void load(ISkinSource skin)
{
float? scorePosition = skin.GetManiaSkinConfig<float>(LegacyManiaSkinConfigurationLookups.ScorePosition)?.Value;
float hitPosition = skin.GetManiaSkinConfig<float>(LegacyManiaSkinConfigurationLookups.HitPosition)?.Value ?? 0;
float scorePosition = skin.GetManiaSkinConfig<float>(LegacyManiaSkinConfigurationLookups.ScorePosition)?.Value ?? 0;

if (scorePosition != null)
scorePosition -= Stage.HIT_TARGET_POSITION + 150;

Y = scorePosition ?? 0;
float absoluteHitPosition = 480f * LegacyManiaSkinConfiguration.POSITION_SCALE_FACTOR - hitPosition;
Y = scorePosition - absoluteHitPosition;

InternalChild = animation.With(d =>
{
Expand Down
Loading

0 comments on commit cf3a379

Please # to comment.