mirror of
https://github.com/ppy/osu.git
synced 2025-02-24 12:42:54 +08:00
Merge branch 'master' into collection-counts
This commit is contained in:
commit
01e489e9c3
20
.github/workflows/ci.yml
vendored
20
.github/workflows/ci.yml
vendored
@ -13,17 +13,17 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# FIXME: Tools won't run in .NET 6.0 unless you install 3.1.x LTS side by side.
|
||||
# https://itnext.io/how-to-support-multiple-net-sdks-in-github-actions-workflows-b988daa884e
|
||||
- name: Install .NET 3.1.x LTS
|
||||
uses: actions/setup-dotnet@v1
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: "3.1.x"
|
||||
|
||||
- name: Install .NET 6.0.x
|
||||
uses: actions/setup-dotnet@v1
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: "6.0.x"
|
||||
|
||||
@ -77,10 +77,10 @@ jobs:
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install .NET 6.0.x
|
||||
uses: actions/setup-dotnet@v1
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: "6.0.x"
|
||||
|
||||
@ -94,7 +94,7 @@ jobs:
|
||||
# Attempt to upload results even if test fails.
|
||||
# https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#always
|
||||
- name: Upload Test Results
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}}
|
||||
@ -106,10 +106,10 @@ jobs:
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install .NET 6.0.x
|
||||
uses: actions/setup-dotnet@v1
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: "6.0.x"
|
||||
|
||||
@ -125,10 +125,10 @@ jobs:
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install .NET 6.0.x
|
||||
uses: actions/setup-dotnet@v1
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: "6.0.x"
|
||||
|
||||
|
18
.github/workflows/diffcalc.yml
vendored
18
.github/workflows/diffcalc.yml
vendored
@ -48,8 +48,8 @@ jobs:
|
||||
CONTINUE="no"
|
||||
fi
|
||||
|
||||
echo "::set-output name=continue::${CONTINUE}"
|
||||
echo "::set-output name=matrix::${MATRIX_JSON}"
|
||||
echo "continue=${CONTINUE}" >> $GITHUB_OUTPUT
|
||||
echo "matrix=${MATRIX_JSON}" >> $GITHUB_OUTPUT
|
||||
diffcalc:
|
||||
name: Run
|
||||
runs-on: self-hosted
|
||||
@ -80,34 +80,34 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
echo "::set-output name=branchname::$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.ref' | sed 's/\"//g')"
|
||||
echo "::set-output name=repo::$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.repo.full_name' | sed 's/\"//g')"
|
||||
echo "branchname=$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.ref' | sed 's/\"//g')" >> $GITHUB_OUTPUT
|
||||
echo "repo=$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.repo.full_name' | sed 's/\"//g')" >> $GITHUB_OUTPUT
|
||||
|
||||
# Checkout osu
|
||||
- name: Checkout osu (master)
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: 'master/osu'
|
||||
- name: Checkout osu (pr)
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: 'pr/osu'
|
||||
repository: ${{ steps.upstreambranch.outputs.repo }}
|
||||
ref: ${{ steps.upstreambranch.outputs.branchname }}
|
||||
|
||||
- name: Checkout osu-difficulty-calculator (master)
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: ppy/osu-difficulty-calculator
|
||||
path: 'master/osu-difficulty-calculator'
|
||||
- name: Checkout osu-difficulty-calculator (pr)
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: ppy/osu-difficulty-calculator
|
||||
path: 'pr/osu-difficulty-calculator'
|
||||
|
||||
- name: Install .NET 5.0.x
|
||||
uses: actions/setup-dotnet@v1
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: "5.0.x"
|
||||
|
||||
|
2
.github/workflows/sentry-release.yml
vendored
2
.github/workflows/sentry-release.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
@ -105,7 +105,7 @@ When it comes to contributing to the project, the two main things you can do to
|
||||
|
||||
If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web).
|
||||
|
||||
For those interested, we love to reward quality contributions via [bounties](https://docs.google.com/spreadsheets/d/1jNXfj_S3Pb5PErA-czDdC9DUu4IgUbe1Lt8E7CYUJuE/view?&rm=minimal#gid=523803337), paid out via PayPal or osu!supporter tags. Don't hesitate to [request a bounty](https://docs.google.com/forms/d/e/1FAIpQLSet_8iFAgPMG526pBZ2Kic6HSh7XPM3fE8xPcnWNkMzINDdYg/viewform) for your work on this project.
|
||||
We love to reward quality contributions. If you have made a large contribution, or are a regular contributor, you are welcome to [submit an expense via opencollective](https://opencollective.com/ppy/expenses/new). If you have any questions, feel free to [reach out to peppy](mailto:pe@ppy.sh) before doing so.
|
||||
|
||||
## Licence
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
<AndroidManifestMerger>manifestmerger.jar</AndroidManifestMerger>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.314.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.403.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidManifestOverlay Include="$(MSBuildThisFileDirectory)osu.Android\Properties\AndroidManifestOverlay.xml" />
|
||||
|
@ -1,17 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using Foundation;
|
||||
using osu.Framework.iOS;
|
||||
using osu.Game.Tests;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Tests.iOS
|
||||
{
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : GameAppDelegate
|
||||
{
|
||||
protected override Framework.Game CreateGame() => new OsuTestBrowser();
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using UIKit;
|
||||
using osu.Framework.iOS;
|
||||
using osu.Game.Tests;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Tests.iOS
|
||||
{
|
||||
@ -11,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
GameApplication.Main(new OsuTestBrowser());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,6 +136,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
Origin = Anchor.TopCentre;
|
||||
|
||||
Size = new Vector2(BASE_SIZE);
|
||||
|
||||
if (difficulty != null)
|
||||
Scale = calculateScale(difficulty);
|
||||
|
||||
@ -333,8 +334,11 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
base.Update();
|
||||
|
||||
var scaleFromDirection = new Vector2((int)VisualDirection, 1);
|
||||
|
||||
body.Scale = scaleFromDirection;
|
||||
caughtObjectContainer.Scale = hitExplosionContainer.Scale = flipCatcherPlate ? scaleFromDirection : Vector2.One;
|
||||
// Inverse of catcher scale is applied here, as catcher gets scaled by circle size and so do the incoming fruit.
|
||||
caughtObjectContainer.Scale = (1 / Scale.X) * (flipCatcherPlate ? scaleFromDirection : Vector2.One);
|
||||
hitExplosionContainer.Scale = flipCatcherPlate ? scaleFromDirection : Vector2.One;
|
||||
|
||||
// Correct overshooting.
|
||||
if ((hyperDashDirection > 0 && hyperDashTargetPosition < X) ||
|
||||
|
@ -1,17 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using Foundation;
|
||||
using osu.Framework.iOS;
|
||||
using osu.Game.Tests;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests.iOS
|
||||
{
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : GameAppDelegate
|
||||
{
|
||||
protected override Framework.Game CreateGame() => new OsuTestBrowser();
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using UIKit;
|
||||
using osu.Framework.iOS;
|
||||
using osu.Game.Tests;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests.iOS
|
||||
{
|
||||
@ -11,7 +10,7 @@ namespace osu.Game.Rulesets.Mania.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
GameApplication.Main(new OsuTestBrowser());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,9 @@
|
||||
|
||||
#nullable disable
|
||||
|
||||
using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Game.Rulesets.Mania.Configuration;
|
||||
using osu.Game.Rulesets.Mania.UI;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests
|
||||
@ -10,5 +13,19 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
public partial class TestSceneManiaPlayer : PlayerTestScene
|
||||
{
|
||||
protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset();
|
||||
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddStep("change direction to down", () => changeDirectionTo(ManiaScrollingDirection.Down));
|
||||
AddStep("change direction to up", () => changeDirectionTo(ManiaScrollingDirection.Up));
|
||||
}
|
||||
|
||||
private void changeDirectionTo(ManiaScrollingDirection direction)
|
||||
{
|
||||
var rulesetConfig = (ManiaRulesetConfigManager)RulesetConfigs.GetConfigFor(new ManiaRuleset()).AsNonNull();
|
||||
rulesetConfig.SetValue(ManiaRulesetSetting.ScrollDirection, direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,8 +43,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
{
|
||||
largeFaint = new Container
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Height = ArgonNotePiece.NOTE_ACCENT_RATIO,
|
||||
Masking = true,
|
||||
@ -81,11 +79,15 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
if (direction.NewValue == ScrollingDirection.Up)
|
||||
{
|
||||
Anchor = Anchor.TopCentre;
|
||||
largeFaint.Anchor = Anchor.TopCentre;
|
||||
largeFaint.Origin = Anchor.TopCentre;
|
||||
Y = ArgonNotePiece.NOTE_HEIGHT / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Anchor = Anchor.BottomCentre;
|
||||
largeFaint.Anchor = Anchor.BottomCentre;
|
||||
largeFaint.Origin = Anchor.BottomCentre;
|
||||
Y = -ArgonNotePiece.NOTE_HEIGHT / 2;
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using Foundation;
|
||||
using osu.Framework.iOS;
|
||||
using osu.Game.Tests;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests.iOS
|
||||
{
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : GameAppDelegate
|
||||
{
|
||||
protected override Framework.Game CreateGame() => new OsuTestBrowser();
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using UIKit;
|
||||
using osu.Framework.iOS;
|
||||
using osu.Game.Tests;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests.iOS
|
||||
{
|
||||
@ -11,7 +10,7 @@ namespace osu.Game.Rulesets.Osu.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
GameApplication.Main(new OsuTestBrowser());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints
|
||||
protected override bool AlwaysShowWhenSelected => true;
|
||||
|
||||
protected override bool ShouldBeAlive => base.ShouldBeAlive
|
||||
|| (ShowHitMarkers.Value && editorClock.CurrentTime >= Item.StartTime && editorClock.CurrentTime - Item.GetEndTime() < HitCircleOverlapMarker.FADE_OUT_EXTENSION);
|
||||
|| (DrawableObject is not DrawableSpinner && ShowHitMarkers.Value && editorClock.CurrentTime >= Item.StartTime && editorClock.CurrentTime - Item.GetEndTime() < HitCircleOverlapMarker.FADE_OUT_EXTENSION);
|
||||
|
||||
protected OsuSelectionBlueprint(T hitObject)
|
||||
: base(hitObject)
|
||||
|
@ -252,13 +252,14 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
renderer.SetBlend(BlendingParameters.Additive);
|
||||
renderer.PushLocalMatrix(DrawInfo.Matrix);
|
||||
|
||||
TextureShader.Bind();
|
||||
BindTextureShader(renderer);
|
||||
|
||||
texture.Bind();
|
||||
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
drawPointQuad(points[i], textureRect, i + firstVisiblePointIndex);
|
||||
|
||||
TextureShader.Unbind();
|
||||
UnbindTextureShader(renderer);
|
||||
renderer.PopLocalMatrix();
|
||||
}
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using Foundation;
|
||||
using osu.Framework.iOS;
|
||||
using osu.Game.Tests;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Tests.iOS
|
||||
{
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : GameAppDelegate
|
||||
{
|
||||
protected override Framework.Game CreateGame() => new OsuTestBrowser();
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using UIKit;
|
||||
using osu.Framework.iOS;
|
||||
using osu.Game.Tests;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Tests.iOS
|
||||
{
|
||||
@ -11,7 +10,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
GameApplication.Main(new OsuTestBrowser());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using Foundation;
|
||||
using osu.Framework.iOS;
|
||||
|
||||
namespace osu.Game.Tests.iOS
|
||||
{
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : GameAppDelegate
|
||||
{
|
||||
protected override Framework.Game CreateGame() => new OsuTestBrowser();
|
||||
}
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using UIKit;
|
||||
using osu.Framework.iOS;
|
||||
|
||||
namespace osu.Game.Tests.iOS
|
||||
{
|
||||
@ -11,7 +9,7 @@ namespace osu.Game.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
GameApplication.Main(new OsuTestBrowser());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
@ -51,9 +49,11 @@ namespace osu.Game.Tests.Testing
|
||||
[Test]
|
||||
public void TestRetrieveShader()
|
||||
{
|
||||
AddAssert("ruleset shaders retrieved", () =>
|
||||
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestVertex.vs") != null &&
|
||||
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestFragment.fs") != null);
|
||||
AddStep("ruleset shaders retrieved without error", () =>
|
||||
{
|
||||
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestVertex.vs");
|
||||
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestFragment.fs");
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -76,12 +76,12 @@ namespace osu.Game.Tests.Testing
|
||||
}
|
||||
|
||||
public override IResourceStore<byte[]> CreateResourceStore() => new NamespacedResourceStore<byte[]>(TestResources.GetStore(), @"Resources");
|
||||
public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new TestRulesetConfigManager();
|
||||
public override IRulesetConfigManager CreateConfig(SettingsStore? settings) => new TestRulesetConfigManager();
|
||||
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type) => Array.Empty<Mod>();
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => null;
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => null;
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => null;
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod>? mods = null) => null!;
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => null!;
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => null!;
|
||||
}
|
||||
|
||||
private class TestRulesetConfigManager : IRulesetConfigManager
|
||||
|
@ -100,8 +100,10 @@ namespace osu.Game.Tests.Visual.Background
|
||||
|
||||
private IUniformBuffer<TriangleBorderData>? borderDataBuffer;
|
||||
|
||||
public override void Draw(IRenderer renderer)
|
||||
protected override void BindUniformResources(IShader shader, IRenderer renderer)
|
||||
{
|
||||
base.BindUniformResources(shader, renderer);
|
||||
|
||||
borderDataBuffer ??= renderer.CreateUniformBuffer<TriangleBorderData>();
|
||||
borderDataBuffer.Data = borderDataBuffer.Data with
|
||||
{
|
||||
@ -109,9 +111,7 @@ namespace osu.Game.Tests.Visual.Background
|
||||
TexelSize = texelSize
|
||||
};
|
||||
|
||||
TextureShader.BindUniformBlock("m_BorderData", borderDataBuffer);
|
||||
|
||||
base.Draw(renderer);
|
||||
shader.BindUniformBlock("m_BorderData", borderDataBuffer);
|
||||
}
|
||||
|
||||
protected override bool CanDrawOpaqueInterior => false;
|
||||
|
@ -13,6 +13,7 @@ using osu.Framework.Screens;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
@ -106,6 +107,26 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddUntilStep("wait for fail overlay", () => Player.FailOverlay.State.Value == Visibility.Visible);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSaveFailedReplayWithStoryboardEndedDoesNotProgress()
|
||||
{
|
||||
CreateTest(() =>
|
||||
{
|
||||
AddStep("fail on first judgement", () => currentFailConditions = (_, _) => true);
|
||||
AddStep("set storyboard duration to 0s", () => currentStoryboardDuration = 0);
|
||||
});
|
||||
AddUntilStep("storyboard ends", () => Player.GameplayClockContainer.CurrentTime >= currentStoryboardDuration);
|
||||
AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed);
|
||||
|
||||
AddUntilStep("wait for fail overlay", () => Player.FailOverlay.State.Value == Visibility.Visible);
|
||||
AddUntilStep("wait for button clickable", () => Player.ChildrenOfType<SaveFailedScoreButton>().First().ChildrenOfType<OsuClickableContainer>().First().Enabled.Value);
|
||||
AddStep("click save button", () => Player.ChildrenOfType<SaveFailedScoreButton>().First().ChildrenOfType<OsuClickableContainer>().First().TriggerClick());
|
||||
|
||||
// Test a regression where importing the fail replay would cause progression to results screen in a failed state.
|
||||
AddWaitStep("wait some", 10);
|
||||
AddAssert("player is still current screen", () => Player.IsCurrentScreen());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestShowResultsFalse()
|
||||
{
|
||||
|
@ -126,6 +126,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
Id = 13926,
|
||||
TournamentId = 35,
|
||||
ImageLowRes = "https://assets.ppy.sh/tournament-banners/official/owc2022/profile/winner_US.jpg",
|
||||
Image = "https://assets.ppy.sh/tournament-banners/official/owc2022/profile/winner_US@2x.jpg",
|
||||
},
|
||||
Badges = new[]
|
||||
{
|
||||
|
@ -332,13 +332,6 @@ namespace osu.Game.Tournament
|
||||
|
||||
private void saveChanges()
|
||||
{
|
||||
foreach (var r in ladder.Rounds)
|
||||
r.Matches = ladder.Matches.Where(p => p.Round.Value == r).Select(p => p.ID).ToList();
|
||||
|
||||
ladder.Progressions = ladder.Matches.Where(p => p.Progression.Value != null).Select(p => new TournamentProgression(p.ID, p.Progression.Value.ID)).Concat(
|
||||
ladder.Matches.Where(p => p.LosersProgression.Value != null).Select(p => new TournamentProgression(p.ID, p.LosersProgression.Value.ID, true)))
|
||||
.ToList();
|
||||
|
||||
// Serialise before opening stream for writing, so if there's a failure it will leave the file in the previous state.
|
||||
string serialisedLadder = GetSerialisedLadder();
|
||||
|
||||
@ -349,6 +342,13 @@ namespace osu.Game.Tournament
|
||||
|
||||
public string GetSerialisedLadder()
|
||||
{
|
||||
foreach (var r in ladder.Rounds)
|
||||
r.Matches = ladder.Matches.Where(p => p.Round.Value == r).Select(p => p.ID).ToList();
|
||||
|
||||
ladder.Progressions = ladder.Matches.Where(p => p.Progression.Value != null).Select(p => new TournamentProgression(p.ID, p.Progression.Value.ID)).Concat(
|
||||
ladder.Matches.Where(p => p.LosersProgression.Value != null).Select(p => new TournamentProgression(p.ID, p.LosersProgression.Value.ID, true)))
|
||||
.ToList();
|
||||
|
||||
return JsonConvert.SerializeObject(ladder,
|
||||
new JsonSerializerSettings
|
||||
{
|
||||
|
@ -306,7 +306,7 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
};
|
||||
|
||||
shader.Bind();
|
||||
shader.BindUniformBlock("m_BorderData", borderDataBuffer);
|
||||
shader.BindUniformBlock(@"m_BorderData", borderDataBuffer);
|
||||
|
||||
foreach (TriangleParticle particle in parts)
|
||||
{
|
||||
|
@ -249,7 +249,7 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
};
|
||||
|
||||
shader.Bind();
|
||||
shader.BindUniformBlock("m_BorderData", borderDataBuffer);
|
||||
shader.BindUniformBlock(@"m_BorderData", borderDataBuffer);
|
||||
|
||||
Vector2 relativeSize = Vector2.Divide(triangleSize, size);
|
||||
|
||||
|
@ -76,17 +76,24 @@ namespace osu.Game.Graphics.Sprites
|
||||
private IUniformBuffer<AnimationData> animationDataBuffer;
|
||||
private IVertexBatch<LogoAnimationVertex> animationVertexBatch;
|
||||
|
||||
protected override void Blit(IRenderer renderer)
|
||||
protected override void BindUniformResources(IShader shader, IRenderer renderer)
|
||||
{
|
||||
if (DrawRectangle.Width == 0 || DrawRectangle.Height == 0)
|
||||
return;
|
||||
base.BindUniformResources(shader, renderer);
|
||||
|
||||
animationDataBuffer ??= renderer.CreateUniformBuffer<AnimationData>();
|
||||
animationVertexBatch ??= renderer.CreateQuadBatch<LogoAnimationVertex>(1, 2);
|
||||
|
||||
animationDataBuffer.Data = animationDataBuffer.Data with { Progress = progress };
|
||||
|
||||
TextureShader.BindUniformBlock("m_AnimationData", animationDataBuffer);
|
||||
shader.BindUniformBlock(@"m_AnimationData", animationDataBuffer);
|
||||
}
|
||||
|
||||
protected override void Blit(IRenderer renderer)
|
||||
{
|
||||
if (DrawRectangle.Width == 0 || DrawRectangle.Height == 0)
|
||||
return;
|
||||
|
||||
base.Blit(renderer);
|
||||
|
||||
renderer.DrawQuad(
|
||||
Texture,
|
||||
|
@ -19,6 +19,11 @@ namespace osu.Game.Localisation
|
||||
/// </summary>
|
||||
public static LocalisableString RendererHeader => new TranslatableString(getKey(@"renderer_header"), @"Renderer");
|
||||
|
||||
/// <summary>
|
||||
/// "Renderer"
|
||||
/// </summary>
|
||||
public static LocalisableString Renderer => new TranslatableString(getKey(@"renderer"), @"Renderer");
|
||||
|
||||
/// <summary>
|
||||
/// "Frame limiter"
|
||||
/// </summary>
|
||||
@ -144,6 +149,12 @@ namespace osu.Game.Localisation
|
||||
/// </summary>
|
||||
public static LocalisableString Png => new TranslatableString(getKey(@"png_lossless"), @"PNG (lossless)");
|
||||
|
||||
/// <summary>
|
||||
/// "In order to change the renderer, the game will close. Please open it again."
|
||||
/// </summary>
|
||||
public static LocalisableString ChangeRendererConfirmation =>
|
||||
new TranslatableString(getKey(@"change_renderer_configuration"), @"In order to change the renderer, the game will close. Please open it again.");
|
||||
|
||||
private static string getKey(string key) => $"{prefix}:{key}";
|
||||
}
|
||||
}
|
||||
|
@ -50,16 +50,18 @@ namespace osu.Game.Localisation
|
||||
public static LocalisableString NoAutoplayMod => new TranslatableString(getKey(@"no_autoplay_mod"), @"The current ruleset doesn't have an autoplay mod available!");
|
||||
|
||||
/// <summary>
|
||||
/// "osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting."
|
||||
/// "osu! doesn't seem to be able to play audio correctly.
|
||||
///
|
||||
/// Please try changing your audio device to a working setting."
|
||||
/// </summary>
|
||||
public static LocalisableString AudioPlaybackIssue => new TranslatableString(getKey(@"audio_playback_issue"),
|
||||
@"osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting.");
|
||||
public static LocalisableString AudioPlaybackIssue => new TranslatableString(getKey(@"audio_playback_issue"), @"osu! doesn't seem to be able to play audio correctly.
|
||||
|
||||
Please try changing your audio device to a working setting.");
|
||||
|
||||
/// <summary>
|
||||
/// "The score overlay is currently disabled. You can toggle this by pressing {0}."
|
||||
/// </summary>
|
||||
public static LocalisableString ScoreOverlayDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"score_overlay_disabled"),
|
||||
@"The score overlay is currently disabled. You can toggle this by pressing {0}.", arg0);
|
||||
public static LocalisableString ScoreOverlayDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"score_overlay_disabled"), @"The score overlay is currently disabled. You can toggle this by pressing {0}.", arg0);
|
||||
|
||||
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||
}
|
||||
|
@ -65,6 +65,11 @@ namespace osu.Game.Localisation
|
||||
if (manager == null)
|
||||
return null;
|
||||
|
||||
// When using the English culture, prefer the fallbacks rather than osu-resources baked strings.
|
||||
// They are guaranteed to be up-to-date, and is also what a developer expects to see when making changes to `xxxStrings.cs` files.
|
||||
if (EffectiveCulture.Name == @"en")
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
return manager.GetString(key, EffectiveCulture);
|
||||
|
@ -209,7 +209,7 @@ namespace osu.Game.Overlays.AccountCreation
|
||||
if (!string.IsNullOrEmpty(errors.Message))
|
||||
passwordDescription.AddErrors(new[] { errors.Message });
|
||||
|
||||
game.OpenUrlExternally($"{errors.Redirect}?username={usernameTextBox.Text}&email={emailTextBox.Text}");
|
||||
game.OpenUrlExternally($"{errors.Redirect}?username={usernameTextBox.Text}&email={emailTextBox.Text}", true);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -132,11 +132,10 @@ namespace osu.Game.Overlays.Comments
|
||||
},
|
||||
sideNumber = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreRight,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
Text = "+1",
|
||||
Font = OsuFont.GetFont(size: 14),
|
||||
Margin = new MarginPadding { Right = 3 },
|
||||
Alpha = 0,
|
||||
},
|
||||
votesCounter = new OsuSpriteText
|
||||
@ -189,7 +188,7 @@ namespace osu.Game.Overlays.Comments
|
||||
else
|
||||
sideNumber.FadeTo(IsHovered ? 1 : 0);
|
||||
|
||||
borderContainer.BorderThickness = IsHovered ? 3 : 0;
|
||||
borderContainer.BorderThickness = IsHovered ? 2 : 0;
|
||||
}
|
||||
|
||||
private void onHoverAction()
|
||||
|
@ -55,7 +55,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu
|
||||
set => valueText.Text = value.ToLocalisableString("N0");
|
||||
}
|
||||
|
||||
public CountSection(LocalisableString header)
|
||||
protected CountSection(LocalisableString header)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
@ -32,7 +32,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||
private FillFlowContainer<SettingsSlider<float>> scalingSettings = null!;
|
||||
|
||||
private readonly Bindable<Display> currentDisplay = new Bindable<Display>();
|
||||
private readonly IBindableList<WindowMode> windowModes = new BindableList<WindowMode>();
|
||||
|
||||
private Bindable<ScalingMode> scalingMode = null!;
|
||||
private Bindable<Size> sizeFullscreen = null!;
|
||||
@ -75,7 +74,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||
if (window != null)
|
||||
{
|
||||
currentDisplay.BindTo(window.CurrentDisplayBindable);
|
||||
windowModes.BindTo(window.SupportedWindowModes);
|
||||
window.DisplaysChanged += onDisplaysChanged;
|
||||
}
|
||||
|
||||
@ -87,7 +85,8 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||
windowModeDropdown = new SettingsDropdown<WindowMode>
|
||||
{
|
||||
LabelText = GraphicsSettingsStrings.ScreenMode,
|
||||
ItemSource = windowModes,
|
||||
Items = window?.SupportedWindowModes,
|
||||
CanBeShown = { Value = window?.SupportedWindowModes.Count() > 1 },
|
||||
Current = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode),
|
||||
},
|
||||
displayDropdown = new DisplaySettingsDropdown
|
||||
@ -181,8 +180,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||
updateScreenModeWarning();
|
||||
}, true);
|
||||
|
||||
windowModes.BindCollectionChanged((_, _) => updateDisplaySettingsVisibility());
|
||||
|
||||
currentDisplay.BindValueChanged(display => Schedule(() =>
|
||||
{
|
||||
resolutions.RemoveRange(1, resolutions.Count - 1);
|
||||
@ -236,7 +233,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||
|
||||
private void updateDisplaySettingsVisibility()
|
||||
{
|
||||
windowModeDropdown.CanBeShown.Value = windowModes.Count > 1;
|
||||
resolutionDropdown.CanBeShown.Value = resolutions.Count > 1 && windowModeDropdown.Current.Value == WindowMode.Fullscreen;
|
||||
displayDropdown.CanBeShown.Value = displayDropdown.Items.Count() > 1;
|
||||
safeAreaConsiderationsCheckbox.CanBeShown.Value = host.Window?.SafeAreaPadding.Value.Total != Vector2.Zero;
|
||||
|
@ -1,15 +1,18 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Overlays.Dialog;
|
||||
|
||||
namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||
{
|
||||
@ -17,12 +20,25 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||
{
|
||||
protected override LocalisableString Header => GraphicsSettingsStrings.RendererHeader;
|
||||
|
||||
private bool automaticRendererInUse;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(FrameworkConfigManager config, OsuConfigManager osuConfig)
|
||||
private void load(FrameworkConfigManager config, OsuConfigManager osuConfig, IDialogOverlay? dialogOverlay, OsuGame? game, GameHost host)
|
||||
{
|
||||
// NOTE: Compatability mode omitted
|
||||
var renderer = config.GetBindable<RendererType>(FrameworkSetting.Renderer);
|
||||
automaticRendererInUse = renderer.Value == RendererType.Automatic;
|
||||
|
||||
SettingsEnumDropdown<RendererType> rendererDropdown;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
rendererDropdown = new RendererSettingsDropdown
|
||||
{
|
||||
LabelText = GraphicsSettingsStrings.Renderer,
|
||||
Current = renderer,
|
||||
Items = host.GetPreferredRenderersForCurrentPlatform().OrderBy(t => t).Where(t => t != RendererType.Vulkan),
|
||||
Keywords = new[] { @"compatibility", @"directx" },
|
||||
},
|
||||
// TODO: this needs to be a custom dropdown at some point
|
||||
new SettingsEnumDropdown<FrameSync>
|
||||
{
|
||||
@ -41,6 +57,55 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
||||
Current = osuConfig.GetBindable<bool>(OsuSetting.ShowFpsDisplay)
|
||||
},
|
||||
};
|
||||
|
||||
renderer.BindValueChanged(r =>
|
||||
{
|
||||
if (r.NewValue == host.ResolvedRenderer)
|
||||
return;
|
||||
|
||||
// Need to check startup renderer for the "automatic" case, as ResolvedRenderer above will track the final resolved renderer instead.
|
||||
if (r.NewValue == RendererType.Automatic && automaticRendererInUse)
|
||||
return;
|
||||
|
||||
dialogOverlay?.Push(new ConfirmDialog(GraphicsSettingsStrings.ChangeRendererConfirmation, () => game?.AttemptExit(), () =>
|
||||
{
|
||||
renderer.Value = automaticRendererInUse ? RendererType.Automatic : host.ResolvedRenderer;
|
||||
}));
|
||||
});
|
||||
|
||||
// TODO: remove this once we support SDL+android.
|
||||
if (RuntimeInfo.OS == RuntimeInfo.Platform.Android)
|
||||
{
|
||||
rendererDropdown.Items = new[] { RendererType.Automatic, RendererType.OpenGLLegacy };
|
||||
rendererDropdown.SetNoticeText("New renderer support for android is coming soon!", true);
|
||||
}
|
||||
}
|
||||
|
||||
private partial class RendererSettingsDropdown : SettingsEnumDropdown<RendererType>
|
||||
{
|
||||
protected override OsuDropdown<RendererType> CreateDropdown() => new RendererDropdown();
|
||||
|
||||
protected partial class RendererDropdown : DropdownControl
|
||||
{
|
||||
private RendererType hostResolvedRenderer;
|
||||
private bool automaticRendererInUse;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(FrameworkConfigManager config, GameHost host)
|
||||
{
|
||||
var renderer = config.GetBindable<RendererType>(FrameworkSetting.Renderer);
|
||||
automaticRendererInUse = renderer.Value == RendererType.Automatic;
|
||||
hostResolvedRenderer = host.ResolvedRenderer;
|
||||
}
|
||||
|
||||
protected override LocalisableString GenerateItemText(RendererType item)
|
||||
{
|
||||
if (item == RendererType.Automatic && automaticRendererInUse)
|
||||
return LocalisableString.Interpolate($"{base.GenerateItemText(item)} ({hostResolvedRenderer.GetDescription()})");
|
||||
|
||||
return base.GenerateItemText(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ namespace osu.Game.Rulesets.Mods
|
||||
};
|
||||
|
||||
shader.Bind();
|
||||
shader.BindUniformBlock("m_FlashlightParameters", flashlightParametersBuffer);
|
||||
shader.BindUniformBlock(@"m_FlashlightParameters", flashlightParametersBuffer);
|
||||
|
||||
renderer.DrawQuad(renderer.WhitePixel, screenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: addAction);
|
||||
|
||||
|
@ -25,21 +25,28 @@ namespace osu.Game.Rulesets.UI
|
||||
/// <summary>
|
||||
/// The texture store to be used for the ruleset.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Reads textures from the "Textures" folder in ruleset resources.
|
||||
/// If not available locally, lookups will fallback to the global texture store.
|
||||
/// </remarks>
|
||||
public TextureStore TextureStore { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The sample store to be used for the ruleset.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the local sample store pointing to the ruleset sample resources,
|
||||
/// the cached sample store (<see cref="FallbackSampleStore"/>) retrieves from
|
||||
/// this store and falls back to the parent store if this store doesn't have the requested sample.
|
||||
/// Reads samples from the "Samples" folder in ruleset resources.
|
||||
/// If not available locally, lookups will fallback to the global sample store.
|
||||
/// </remarks>
|
||||
public ISampleStore SampleStore { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The shader manager to be used for the ruleset.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Reads shaders from the "Shaders" folder in ruleset resources.
|
||||
/// If not available locally, lookups will fallback to the global shader manager.
|
||||
/// </remarks>
|
||||
public ShaderManager ShaderManager { get; }
|
||||
|
||||
/// <summary>
|
||||
@ -61,8 +68,7 @@ namespace osu.Game.Rulesets.UI
|
||||
SampleStore.PlaybackConcurrency = OsuGameBase.SAMPLE_CONCURRENCY;
|
||||
CacheAs(SampleStore = new FallbackSampleStore(SampleStore, parent.Get<ISampleStore>()));
|
||||
|
||||
ShaderManager = new ShaderManager(host.Renderer, new NamespacedResourceStore<byte[]>(resources, @"Shaders"));
|
||||
CacheAs(ShaderManager = new FallbackShaderManager(host.Renderer, ShaderManager, parent.Get<ShaderManager>()));
|
||||
CacheAs(ShaderManager = new RulesetShaderManager(host.Renderer, new NamespacedResourceStore<byte[]>(resources, @"Shaders"), parent.Get<ShaderManager>()));
|
||||
|
||||
RulesetConfigManager = parent.Get<IRulesetConfigCache>().GetConfigFor(ruleset);
|
||||
if (RulesetConfigManager != null)
|
||||
@ -190,24 +196,27 @@ namespace osu.Game.Rulesets.UI
|
||||
}
|
||||
}
|
||||
|
||||
private class FallbackShaderManager : ShaderManager
|
||||
private class RulesetShaderManager : ShaderManager
|
||||
{
|
||||
private readonly ShaderManager primary;
|
||||
private readonly ShaderManager fallback;
|
||||
private readonly ShaderManager parent;
|
||||
|
||||
public FallbackShaderManager(IRenderer renderer, ShaderManager primary, ShaderManager fallback)
|
||||
: base(renderer, new ResourceStore<byte[]>())
|
||||
public RulesetShaderManager(IRenderer renderer, NamespacedResourceStore<byte[]> rulesetResources, ShaderManager parent)
|
||||
: base(renderer, rulesetResources)
|
||||
{
|
||||
this.primary = primary;
|
||||
this.fallback = fallback;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public override byte[]? LoadRaw(string name) => primary.LoadRaw(name) ?? fallback.LoadRaw(name);
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
public override IShader Load(string vertex, string fragment)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (primary.IsNotNull()) primary.Dispose();
|
||||
try
|
||||
{
|
||||
return base.Load(vertex, fragment);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Shader lookup is very non-standard. Rather than returning null on missing shaders, exceptions are thrown.
|
||||
return parent.Load(vertex, fragment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,6 +130,8 @@ namespace osu.Game.Screens
|
||||
|
||||
loadTargets.Add(manager.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE));
|
||||
|
||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, "TriangleBorder"));
|
||||
|
||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE));
|
||||
}
|
||||
|
||||
|
@ -73,11 +73,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
||||
private OsuSpriteText typeLabel = null!;
|
||||
private LoadingLayer loadingLayer = null!;
|
||||
|
||||
public void SelectBeatmap()
|
||||
{
|
||||
if (matchSubScreen.IsCurrentScreen())
|
||||
matchSubScreen.Push(new MultiplayerMatchSongSelect(matchSubScreen.Room));
|
||||
}
|
||||
public void SelectBeatmap() => selectBeatmapButton.TriggerClick();
|
||||
|
||||
[Resolved]
|
||||
private MultiplayerMatchSubScreen matchSubScreen { get; set; } = null!;
|
||||
@ -97,6 +93,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
||||
private IDisposable? applyingSettingsOperation;
|
||||
private Drawable playlistContainer = null!;
|
||||
private DrawableRoomPlaylist drawablePlaylist = null!;
|
||||
private RoundedButton selectBeatmapButton = null!;
|
||||
|
||||
public MatchSettings(Room room)
|
||||
{
|
||||
@ -275,12 +272,16 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = DrawableRoomPlaylistItem.HEIGHT
|
||||
},
|
||||
new RoundedButton
|
||||
selectBeatmapButton = new RoundedButton
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 40,
|
||||
Text = "Select beatmap",
|
||||
Action = SelectBeatmap
|
||||
Action = () =>
|
||||
{
|
||||
if (matchSubScreen.IsCurrentScreen())
|
||||
matchSubScreen.Push(new MultiplayerMatchSongSelect(matchSubScreen.Room));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -358,14 +358,10 @@ namespace osu.Game.Screens.Play
|
||||
ScoreProcessor.RevertResult(r);
|
||||
};
|
||||
|
||||
DimmableStoryboard.HasStoryboardEnded.ValueChanged += storyboardEnded =>
|
||||
{
|
||||
if (storyboardEnded.NewValue)
|
||||
progressToResults(true);
|
||||
};
|
||||
DimmableStoryboard.HasStoryboardEnded.ValueChanged += _ => checkScoreCompleted();
|
||||
|
||||
// Bind the judgement processors to ourselves
|
||||
ScoreProcessor.HasCompleted.BindValueChanged(scoreCompletionChanged);
|
||||
ScoreProcessor.HasCompleted.BindValueChanged(_ => checkScoreCompleted());
|
||||
HealthProcessor.Failed += onFail;
|
||||
|
||||
// Provide judgement processors to mods after they're loaded so that they're on the gameplay clock,
|
||||
@ -706,19 +702,20 @@ namespace osu.Game.Screens.Play
|
||||
/// <summary>
|
||||
/// Handles changes in player state which may progress the completion of gameplay / this screen's lifetime.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">Thrown if this method is called more than once without changing state.</exception>
|
||||
private void scoreCompletionChanged(ValueChangedEvent<bool> completed)
|
||||
private void checkScoreCompleted()
|
||||
{
|
||||
// If this player instance is in the middle of an exit, don't attempt any kind of state update.
|
||||
if (!this.IsCurrentScreen())
|
||||
return;
|
||||
|
||||
// Special case to handle rewinding post-completion. This is the only way already queued forward progress can be cancelled.
|
||||
// TODO: Investigate whether this can be moved to a RewindablePlayer subclass or similar.
|
||||
// Currently, even if this scenario is hit, prepareScoreForDisplay has already been queued (and potentially run).
|
||||
// In scenarios where rewinding is possible (replay, spectating) this is a non-issue as no submission/import work is done,
|
||||
// but it still doesn't feel right that this exists here.
|
||||
if (!completed.NewValue)
|
||||
// Handle cases of arriving at this method when not in a completed state.
|
||||
// - When a storyboard completion triggered this call earlier than gameplay finishes.
|
||||
// - When a replay has been rewound before a queued resultsDisplayDelegate has run.
|
||||
//
|
||||
// Currently, even if this scenario is hit, prepareAndImportScoreAsync has already been queued (and potentially run).
|
||||
// In the scenarios above, this is a non-issue, but it still feels a bit convoluted to have to cancel in this method.
|
||||
// Maybe this can be improved with further refactoring.
|
||||
if (!ScoreProcessor.HasCompleted.Value)
|
||||
{
|
||||
resultsDisplayDelegate?.Cancel();
|
||||
resultsDisplayDelegate = null;
|
||||
@ -742,12 +739,12 @@ namespace osu.Game.Screens.Play
|
||||
if (!Configuration.ShowResults)
|
||||
return;
|
||||
|
||||
bool storyboardHasOutro = DimmableStoryboard.ContentDisplayed && !DimmableStoryboard.HasStoryboardEnded.Value;
|
||||
bool storyboardStillRunning = DimmableStoryboard.ContentDisplayed && !DimmableStoryboard.HasStoryboardEnded.Value;
|
||||
|
||||
if (storyboardHasOutro)
|
||||
// If the current beatmap has a storyboard, this method will be called again on storyboard completion.
|
||||
// Alternatively, the user may press the outro skip button, forcing immediate display of the results screen.
|
||||
if (storyboardStillRunning)
|
||||
{
|
||||
// if the current beatmap has a storyboard, the progression to results will be handled by the storyboard ending
|
||||
// or the user pressing the skip outro button.
|
||||
skipOutroOverlay.Show();
|
||||
return;
|
||||
}
|
||||
@ -793,6 +790,8 @@ namespace osu.Game.Screens.Play
|
||||
// This player instance may already be in the process of exiting.
|
||||
return;
|
||||
|
||||
Debug.Assert(ScoreProcessor.Rank.Value != ScoreRank.F);
|
||||
|
||||
this.Push(CreateResults(prepareScoreForDisplayTask.GetResultSafely()));
|
||||
}, Time.Current + delay, 50);
|
||||
|
||||
|
@ -257,6 +257,7 @@ namespace osu.Game.Screens.Select
|
||||
public FilterControlTextBox()
|
||||
{
|
||||
Height += filter_text_size;
|
||||
TextContainer.Height *= (Height - filter_text_size) / Height;
|
||||
TextContainer.Margin = new MarginPadding { Bottom = filter_text_size };
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
// 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.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Users
|
||||
@ -17,7 +16,7 @@ namespace osu.Game.Users
|
||||
[JsonProperty("image")]
|
||||
public string ImageLowRes = null!;
|
||||
|
||||
// TODO: remove when api returns @2x image link: https://github.com/ppy/osu-web/issues/9816
|
||||
public string Image => $@"{Path.ChangeExtension(ImageLowRes, null)}@2x{Path.GetExtension(ImageLowRes)}";
|
||||
[JsonProperty("image@2x")]
|
||||
public string Image = null!;
|
||||
}
|
||||
}
|
||||
|
@ -36,8 +36,8 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Realm" Version="10.20.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2023.314.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2023.320.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2023.403.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2023.402.0" />
|
||||
<PackageReference Include="Sentry" Version="3.28.1" />
|
||||
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||
|
@ -16,6 +16,6 @@
|
||||
<RuntimeIdentifier>iossimulator-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2023.314.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2023.403.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1,29 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Foundation;
|
||||
using osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.iOS
|
||||
{
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : GameAppDelegate
|
||||
{
|
||||
private OsuGameIOS game;
|
||||
|
||||
protected override Framework.Game CreateGame() => game = new OsuGameIOS();
|
||||
|
||||
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
|
||||
{
|
||||
if (url.IsFileUrl)
|
||||
Task.Run(() => game.Import(url.Path));
|
||||
else
|
||||
Task.Run(() => game.HandleLink(url.AbsoluteString));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using UIKit;
|
||||
using osu.Framework.iOS;
|
||||
|
||||
namespace osu.iOS
|
||||
{
|
||||
@ -11,7 +9,7 @@ namespace osu.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
GameApplication.Main(new OsuGameIOS());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +0,0 @@
|
||||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Overlays.Settings;
|
||||
|
||||
namespace osu.iOS
|
||||
{
|
||||
public partial class IOSMouseSettings : SettingsSubsection
|
||||
{
|
||||
protected override LocalisableString Header => MouseSettingsStrings.Mouse;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuConfigManager osuConfig)
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SettingsCheckbox
|
||||
{
|
||||
LabelText = MouseSettingsStrings.DisableMouseWheelVolumeAdjust,
|
||||
TooltipText = MouseSettingsStrings.DisableMouseWheelVolumeAdjustTooltip,
|
||||
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableWheel),
|
||||
},
|
||||
new SettingsCheckbox
|
||||
{
|
||||
LabelText = MouseSettingsStrings.DisableMouseButtons,
|
||||
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -7,10 +7,7 @@ using System;
|
||||
using Foundation;
|
||||
using Microsoft.Maui.Devices;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input.Handlers;
|
||||
using osu.Framework.iOS.Input;
|
||||
using osu.Game;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Game.Updater;
|
||||
using osu.Game.Utils;
|
||||
|
||||
@ -29,18 +26,6 @@ namespace osu.iOS
|
||||
// Because we have the home indicator (mostly) hidden we don't really care about drawing in this region.
|
||||
Edges.Bottom;
|
||||
|
||||
public override SettingsSubsection CreateSettingsSubsectionFor(InputHandler handler)
|
||||
{
|
||||
switch (handler)
|
||||
{
|
||||
case IOSMouseHandler:
|
||||
return new IOSMouseSettings();
|
||||
|
||||
default:
|
||||
return base.CreateSettingsSubsectionFor(handler);
|
||||
}
|
||||
}
|
||||
|
||||
private class IOSBatteryInfo : BatteryInfo
|
||||
{
|
||||
public override double? ChargeLevel => Battery.ChargeLevel;
|
||||
|
Loading…
Reference in New Issue
Block a user