1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 14:47:25 +08:00

Temporary rollback of framework / SDL3

This commit is contained in:
Dean Herbert 2024-05-21 14:34:53 +08:00
parent e740b8bcc3
commit d7d569cf4e
No known key found for this signature in database
44 changed files with 304 additions and 226 deletions

View File

@ -10,7 +10,7 @@
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.Android" Version="2024.509.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2024.329.0" />
</ItemGroup>
<PropertyGroup>
<!-- Fody does not handle Android build well, and warns when unchanged.

View File

@ -0,0 +1,76 @@
// 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.Android.Input;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Localisation;
using osu.Game.Overlays.Settings;
namespace osu.Android
{
public partial class AndroidJoystickSettings : SettingsSubsection
{
protected override LocalisableString Header => JoystickSettingsStrings.JoystickGamepad;
private readonly AndroidJoystickHandler joystickHandler;
private readonly Bindable<bool> enabled = new BindableBool(true);
private SettingsSlider<float> deadzoneSlider = null!;
private Bindable<float> handlerDeadzone = null!;
private Bindable<float> localDeadzone = null!;
public AndroidJoystickSettings(AndroidJoystickHandler joystickHandler)
{
this.joystickHandler = joystickHandler;
}
[BackgroundDependencyLoader]
private void load()
{
// use local bindable to avoid changing enabled state of game host's bindable.
handlerDeadzone = joystickHandler.DeadzoneThreshold.GetBoundCopy();
localDeadzone = handlerDeadzone.GetUnboundCopy();
Children = new Drawable[]
{
new SettingsCheckbox
{
LabelText = CommonStrings.Enabled,
Current = enabled
},
deadzoneSlider = new SettingsSlider<float>
{
LabelText = JoystickSettingsStrings.DeadzoneThreshold,
KeyboardStep = 0.01f,
DisplayAsPercentage = true,
Current = localDeadzone,
},
};
}
protected override void LoadComplete()
{
base.LoadComplete();
enabled.BindTo(joystickHandler.Enabled);
enabled.BindValueChanged(e => deadzoneSlider.Current.Disabled = !e.NewValue, true);
handlerDeadzone.BindValueChanged(val =>
{
bool disabled = localDeadzone.Disabled;
localDeadzone.Disabled = false;
localDeadzone.Value = val.NewValue;
localDeadzone.Disabled = disabled;
}, true);
localDeadzone.BindValueChanged(val => handlerDeadzone.Value = val.NewValue);
}
}
}

View File

@ -0,0 +1,97 @@
// 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 Android.OS;
using osu.Framework.Allocation;
using osu.Framework.Android.Input;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Localisation;
using osu.Game.Overlays.Settings;
using osu.Game.Overlays.Settings.Sections.Input;
namespace osu.Android
{
public partial class AndroidMouseSettings : SettingsSubsection
{
private readonly AndroidMouseHandler mouseHandler;
protected override LocalisableString Header => MouseSettingsStrings.Mouse;
private Bindable<double> handlerSensitivity = null!;
private Bindable<double> localSensitivity = null!;
private Bindable<bool> relativeMode = null!;
public AndroidMouseSettings(AndroidMouseHandler mouseHandler)
{
this.mouseHandler = mouseHandler;
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager osuConfig)
{
// use local bindable to avoid changing enabled state of game host's bindable.
handlerSensitivity = mouseHandler.Sensitivity.GetBoundCopy();
localSensitivity = handlerSensitivity.GetUnboundCopy();
relativeMode = mouseHandler.UseRelativeMode.GetBoundCopy();
// High precision/pointer capture is only available on Android 8.0 and up
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
AddRange(new Drawable[]
{
new SettingsCheckbox
{
LabelText = MouseSettingsStrings.HighPrecisionMouse,
TooltipText = MouseSettingsStrings.HighPrecisionMouseTooltip,
Current = relativeMode,
Keywords = new[] { @"raw", @"input", @"relative", @"cursor", @"captured", @"pointer" },
},
new MouseSettings.SensitivitySetting
{
LabelText = MouseSettingsStrings.CursorSensitivity,
Current = localSensitivity,
},
});
}
AddRange(new Drawable[]
{
new SettingsCheckbox
{
LabelText = MouseSettingsStrings.DisableMouseWheelVolumeAdjust,
TooltipText = MouseSettingsStrings.DisableMouseWheelVolumeAdjustTooltip,
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableWheel),
},
new SettingsCheckbox
{
LabelText = MouseSettingsStrings.DisableClicksDuringGameplay,
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons),
},
});
}
protected override void LoadComplete()
{
base.LoadComplete();
relativeMode.BindValueChanged(relative => localSensitivity.Disabled = !relative.NewValue, true);
handlerSensitivity.BindValueChanged(val =>
{
bool disabled = localSensitivity.Disabled;
localSensitivity.Disabled = false;
localSensitivity.Value = val.NewValue;
localSensitivity.Disabled = disabled;
}, true);
localSensitivity.BindValueChanged(val => handlerSensitivity.Value = val.NewValue);
}
}
}

View File

@ -5,9 +5,13 @@ using System;
using Android.App;
using Microsoft.Maui.Devices;
using osu.Framework.Allocation;
using osu.Framework.Android.Input;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Input.Handlers;
using osu.Framework.Platform;
using osu.Game;
using osu.Game.Overlays.Settings;
using osu.Game.Overlays.Settings.Sections.Input;
using osu.Game.Updater;
using osu.Game.Utils;
@ -84,6 +88,24 @@ namespace osu.Android
protected override BatteryInfo CreateBatteryInfo() => new AndroidBatteryInfo();
public override SettingsSubsection CreateSettingsSubsectionFor(InputHandler handler)
{
switch (handler)
{
case AndroidMouseHandler mh:
return new AndroidMouseSettings(mh);
case AndroidJoystickHandler jh:
return new AndroidJoystickSettings(jh);
case AndroidTouchHandler th:
return new TouchSettings(th);
default:
return base.CreateSettingsSubsectionFor(handler);
}
}
private class AndroidBatteryInfo : BatteryInfo
{
public override double? ChargeLevel => Battery.ChargeLevel;

View File

@ -22,7 +22,7 @@ using osu.Game.IPC;
using osu.Game.Online.Multiplayer;
using osu.Game.Performance;
using osu.Game.Utils;
using SDL;
using SDL2;
namespace osu.Desktop
{
@ -161,7 +161,7 @@ namespace osu.Desktop
host.Window.Title = Name;
}
protected override BatteryInfo CreateBatteryInfo() => new SDL3BatteryInfo();
protected override BatteryInfo CreateBatteryInfo() => new SDL2BatteryInfo();
protected override void Dispose(bool isDisposing)
{
@ -170,14 +170,13 @@ namespace osu.Desktop
archiveImportIPCChannel?.Dispose();
}
private unsafe class SDL3BatteryInfo : BatteryInfo
private class SDL2BatteryInfo : BatteryInfo
{
public override double? ChargeLevel
{
get
{
int percentage;
SDL3.SDL_GetPowerInfo(null, &percentage);
SDL.SDL_GetPowerInfo(out _, out int percentage);
if (percentage == -1)
return null;
@ -186,7 +185,7 @@ namespace osu.Desktop
}
}
public override bool OnBattery => SDL3.SDL_GetPowerInfo(null, null) == SDL_PowerState.SDL_POWERSTATE_ON_BATTERY;
public override bool OnBattery => SDL.SDL_GetPowerInfo(out _, out _) == SDL.SDL_PowerState.SDL_POWERSTATE_ON_BATTERY;
}
}
}

View File

@ -13,7 +13,7 @@ using osu.Framework.Platform;
using osu.Game;
using osu.Game.IPC;
using osu.Game.Tournament;
using SDL;
using SDL2;
using Squirrel;
namespace osu.Desktop
@ -52,19 +52,16 @@ namespace osu.Desktop
// See https://www.mongodb.com/docs/realm/sdk/dotnet/compatibility/
if (windowsVersion.Major < 6 || (windowsVersion.Major == 6 && windowsVersion.Minor <= 2))
{
unsafe
{
// If users running in compatibility mode becomes more of a common thing, we may want to provide better guidance or even consider
// disabling it ourselves.
// We could also better detect compatibility mode if required:
// https://stackoverflow.com/questions/10744651/how-i-can-detect-if-my-application-is-running-under-compatibility-mode#comment58183249_10744730
SDL3.SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR,
"Your operating system is too old to run osu!"u8,
"This version of osu! requires at least Windows 8.1 to run.\n"u8
+ "Please upgrade your operating system or consider using an older version of osu!.\n\n"u8
+ "If you are running a newer version of windows, please check you don't have \"Compatibility mode\" turned on for osu!"u8, null);
return;
}
// If users running in compatibility mode becomes more of a common thing, we may want to provide better guidance or even consider
// disabling it ourselves.
// We could also better detect compatibility mode if required:
// https://stackoverflow.com/questions/10744651/how-i-can-detect-if-my-application-is-running-under-compatibility-mode#comment58183249_10744730
SDL.SDL_ShowSimpleMessageBox(SDL.SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR,
"Your operating system is too old to run osu!",
"This version of osu! requires at least Windows 8.1 to run.\n"
+ "Please upgrade your operating system or consider using an older version of osu!.\n\n"
+ "If you are running a newer version of windows, please check you don't have \"Compatibility mode\" turned on for osu!", IntPtr.Zero);
return;
}
setupSquirrel();
@ -107,13 +104,7 @@ namespace osu.Desktop
}
}
var hostOptions = new HostOptions
{
IPCPort = !tournamentClient ? OsuGame.IPC_PORT : null,
FriendlyGameName = OsuGameBase.GAME_NAME,
};
using (DesktopGameHost host = Host.GetSuitableDesktopHost(gameName, hostOptions))
using (DesktopGameHost host = Host.GetSuitableDesktopHost(gameName, new HostOptions { IPCPort = !tournamentClient ? OsuGame.IPC_PORT : null }))
{
if (!host.IsPrimaryInstance)
{

View File

@ -78,7 +78,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
}
// Generally all the control points are within the visible area all the time.
public override bool UpdateSubTreeMasking() => true;
public override bool UpdateSubTreeMasking(Drawable source, RectangleF maskingBounds) => true;
/// <summary>
/// Handles correction of invalid path types.

View File

@ -8,6 +8,7 @@ using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
@ -36,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.UI
// For osu! gameplay, everything is always on screen.
// Skipping masking calculations improves performance in intense beatmaps (ie. https://osu.ppy.sh/beatmapsets/150945#osu/372245)
public override bool UpdateSubTreeMasking() => false;
public override bool UpdateSubTreeMasking(Drawable source, RectangleF maskingBounds) => false;
public SmokeContainer Smoke { get; }
public FollowPointRenderer FollowPoints { get; }

View File

@ -7,6 +7,7 @@ using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Judgements;
@ -344,7 +345,7 @@ namespace osu.Game.Rulesets.Taiko.UI
{
public void Add(Drawable proxy) => AddInternal(proxy);
public override bool UpdateSubTreeMasking()
public override bool UpdateSubTreeMasking(Drawable source, RectangleF maskingBounds)
{
// DrawableHitObject disables masking.
// Hitobject content is proxied and unproxied based on hit status and the IsMaskedAway value could get stuck because of this.

View File

@ -22,7 +22,7 @@ namespace osu.Game.Tournament.Screens.Ladder
protected override bool ComputeIsMaskedAway(RectangleF maskingBounds) => false;
public override bool UpdateSubTreeMasking() => false;
public override bool UpdateSubTreeMasking(Drawable source, RectangleF maskingBounds) => false;
protected override void OnDrag(DragEvent e)
{

View File

@ -6,7 +6,6 @@ using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using JetBrains.Annotations;
using Realms;
using Realms.Schema;
@ -16,12 +15,8 @@ namespace osu.Game.Database
{
private IList<T> emptySet => Array.Empty<T>();
[MustDisposeResource]
public IEnumerator<T> GetEnumerator() => emptySet.GetEnumerator();
[MustDisposeResource]
IEnumerator IEnumerable.GetEnumerator() => emptySet.GetEnumerator();
public int Count => emptySet.Count;
public T this[int index] => emptySet[index];
public int IndexOf(object? item) => item == null ? -1 : emptySet.IndexOf((T)item);

View File

@ -1,7 +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.
using System.Numerics;
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@ -10,7 +10,7 @@ using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using Vector2 = osuTK.Vector2;
using osuTK;
namespace osu.Game.Graphics.UserInterface
{
@ -18,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface
/// An <see cref="IExpandable"/> implementation for the UI slider bar control.
/// </summary>
public partial class ExpandableSlider<T, TSlider> : CompositeDrawable, IExpandable, IHasCurrentValue<T>
where T : struct, INumber<T>, IMinMaxValue<T>
where T : struct, IEquatable<T>, IComparable<T>, IConvertible
where TSlider : RoundedSliderBar<T>, new()
{
private readonly OsuSpriteText label;
@ -129,7 +129,7 @@ namespace osu.Game.Graphics.UserInterface
/// An <see cref="IExpandable"/> implementation for the UI slider bar control.
/// </summary>
public partial class ExpandableSlider<T> : ExpandableSlider<T, RoundedSliderBar<T>>
where T : struct, INumber<T>, IMinMaxValue<T>
where T : struct, IEquatable<T>, IComparable<T>, IConvertible
{
}
}

View File

@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Numerics;
using System.Globalization;
using osu.Framework.Allocation;
using osu.Framework.Audio;
@ -16,7 +15,7 @@ using osu.Game.Utils;
namespace osu.Game.Graphics.UserInterface
{
public abstract partial class OsuSliderBar<T> : SliderBar<T>, IHasTooltip
where T : struct, INumber<T>, IMinMaxValue<T>
where T : struct, IEquatable<T>, IComparable<T>, IConvertible
{
public bool PlaySamplesOnAdjust { get; set; } = true;
@ -86,11 +85,11 @@ namespace osu.Game.Graphics.UserInterface
private LocalisableString getTooltipText(T value)
{
if (CurrentNumber.IsInteger)
return int.CreateTruncating(value).ToString("N0");
return value.ToInt32(NumberFormatInfo.InvariantInfo).ToString("N0");
double floatValue = double.CreateTruncating(value);
double floatValue = value.ToDouble(NumberFormatInfo.InvariantInfo);
decimal decimalPrecision = normalise(decimal.CreateTruncating(CurrentNumber.Precision), max_decimal_digits);
decimal decimalPrecision = normalise(CurrentNumber.Precision.ToDecimal(NumberFormatInfo.InvariantInfo), max_decimal_digits);
// Find the number of significant digits (we could have less than 5 after normalize())
int significantDigits = FormatUtils.FindPrecision(decimalPrecision);

View File

@ -8,8 +8,6 @@ using System.Linq;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Extensions.Color4Extensions;
@ -145,6 +143,13 @@ namespace osu.Game.Graphics.UserInterface
FadeUnhovered();
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
if (accentColour == default)
AccentColour = colours.Blue;
}
public OsuTabItem(T value)
: base(value)
{
@ -191,21 +196,10 @@ namespace osu.Game.Graphics.UserInterface
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
},
new HoverSounds(HoverSampleSet.TabSelect)
new HoverClickSounds(HoverSampleSet.TabSelect)
};
}
private Sample selectSample;
[BackgroundDependencyLoader]
private void load(OsuColour colours, AudioManager audio)
{
if (accentColour == default)
AccentColour = colours.Blue;
selectSample = audio.Samples.Get(@"UI/tabselect-select");
}
protected override void OnActivated()
{
Text.Font = Text.Font.With(weight: FontWeight.Bold);
@ -217,8 +211,6 @@ namespace osu.Game.Graphics.UserInterface
Text.Font = Text.Font.With(weight: FontWeight.Medium);
FadeUnhovered();
}
protected override void OnActivatedByUser() => selectSample.Play();
}
}
}

View File

@ -7,8 +7,6 @@ using System;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
@ -55,8 +53,6 @@ namespace osu.Game.Graphics.UserInterface
}
}
private Sample selectSample = null!;
public PageTabItem(T value)
: base(value)
{
@ -82,18 +78,12 @@ namespace osu.Game.Graphics.UserInterface
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
},
new HoverSounds(HoverSampleSet.TabSelect)
new HoverClickSounds(HoverSampleSet.TabSelect)
};
Active.BindValueChanged(active => Text.Font = Text.Font.With(Typeface.Torus, weight: active.NewValue ? FontWeight.Bold : FontWeight.Medium), true);
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
selectSample = audio.Samples.Get(@"UI/tabselect-select");
}
protected virtual LocalisableString CreateText() => (Value as Enum)?.GetLocalisableDescription() ?? Value.ToString();
protected override bool OnHover(HoverEvent e)
@ -122,8 +112,6 @@ namespace osu.Game.Graphics.UserInterface
protected override void OnActivated() => slideActive();
protected override void OnDeactivated() => slideInactive();
protected override void OnActivatedByUser() => selectSample.Play();
}
}
}

View File

@ -2,7 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Numerics;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
@ -11,12 +11,11 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Game.Overlays;
using Vector2 = osuTK.Vector2;
namespace osu.Game.Graphics.UserInterface
{
public partial class RoundedSliderBar<T> : OsuSliderBar<T>
where T : struct, INumber<T>, IMinMaxValue<T>
where T : struct, IEquatable<T>, IComparable<T>, IConvertible
{
protected readonly Nub Nub;
protected readonly Box LeftBox;

View File

@ -2,7 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Numerics;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
@ -12,12 +12,11 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Game.Overlays;
using static osu.Game.Graphics.UserInterface.ShearedNub;
using Vector2 = osuTK.Vector2;
namespace osu.Game.Graphics.UserInterface
{
public partial class ShearedSliderBar<T> : OsuSliderBar<T>
where T : struct, INumber<T>, IMinMaxValue<T>
where T : struct, IEquatable<T>, IComparable<T>, IConvertible
{
protected readonly ShearedNub Nub;
protected readonly Box LeftBox;

View File

@ -1,14 +1,14 @@
// 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.Numerics;
using System;
using osu.Framework.Graphics;
using osu.Game.Overlays.Settings;
namespace osu.Game.Graphics.UserInterfaceV2
{
public partial class LabelledSliderBar<TNumber> : LabelledComponent<SettingsSlider<TNumber>, TNumber>
where TNumber : struct, INumber<TNumber>, IMinMaxValue<TNumber>
where TNumber : struct, IEquatable<TNumber>, IComparable<TNumber>, IConvertible
{
public LabelledSliderBar()
: base(true)

View File

@ -1,7 +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.
using System.Numerics;
using System;
using System.Globalization;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@ -10,12 +10,12 @@ using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Overlays.Settings;
using osu.Game.Utils;
using Vector2 = osuTK.Vector2;
using osuTK;
namespace osu.Game.Graphics.UserInterfaceV2
{
public partial class SliderWithTextBoxInput<T> : CompositeDrawable, IHasCurrentValue<T>
where T : struct, INumber<T>, IMinMaxValue<T>
where T : struct, IEquatable<T>, IComparable<T>, IConvertible
{
/// <summary>
/// A custom step value for each key press which actuates a change on this control.
@ -138,7 +138,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
{
if (updatingFromTextBox) return;
decimal decimalValue = decimal.CreateTruncating(slider.Current.Value);
decimal decimalValue = slider.Current.Value.ToDecimal(NumberFormatInfo.InvariantInfo);
textBox.Text = decimalValue.ToString($@"N{FormatUtils.FindPrecision(decimalValue)}");
}
}

View File

@ -75,12 +75,6 @@ namespace osu.Game
{
public static readonly string[] VIDEO_EXTENSIONS = { ".mp4", ".mov", ".avi", ".flv", ".mpg", ".wmv", ".m4v" };
#if DEBUG
public const string GAME_NAME = "osu! (development)";
#else
public const string GAME_NAME = "osu!";
#endif
public const string OSU_PROTOCOL = "osu://";
public const string CLIENT_STREAM_NAME = @"lazer";
@ -247,7 +241,11 @@ namespace osu.Game
public OsuGameBase()
{
Name = GAME_NAME;
Name = @"osu!";
#if DEBUG
Name += " (development)";
#endif
allowableExceptions = UnhandledExceptionsBeforeCrash;
}

View File

@ -5,8 +5,6 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -49,15 +47,13 @@ namespace osu.Game.Overlays.BeatmapListing
[Resolved]
private OverlayColourProvider colourProvider { get; set; }
private Sample selectSample = null!;
public TabItem(BeatmapCardSize value)
: base(value)
{
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
private void load()
{
AutoSizeAxes = Axes.Both;
Masking = true;
@ -83,10 +79,8 @@ namespace osu.Game.Overlays.BeatmapListing
Icon = getIconForCardSize(Value)
}
},
new HoverSounds(HoverSampleSet.TabSelect)
new HoverClickSounds(HoverSampleSet.TabSelect)
};
selectSample = audio.Samples.Get(@"UI/tabselect-select");
}
private static IconUsage getIconForCardSize(BeatmapCardSize cardSize)
@ -117,8 +111,6 @@ namespace osu.Game.Overlays.BeatmapListing
updateState();
}
protected override void OnActivatedByUser() => selectSample.Play();
protected override void OnDeactivated()
{
if (IsLoaded)

View File

@ -128,11 +128,7 @@ namespace osu.Game.Overlays.BeatmapListing
protected override bool OnClick(ClickEvent e)
{
base.OnClick(e);
// this tab item implementation is not managed by a TabControl,
// therefore we have to manually update Active state and play select sound when this tab item is clicked.
Active.Toggle();
SelectSample.Play();
return true;
}
}

View File

@ -5,8 +5,6 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
@ -26,15 +24,13 @@ namespace osu.Game.Overlays.BeatmapListing
private OsuSpriteText text;
protected Sample SelectSample { get; private set; } = null!;
public FilterTabItem(T value)
: base(value)
{
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
private void load()
{
AutoSizeAxes = Axes.Both;
AddRangeInternal(new Drawable[]
@ -44,12 +40,10 @@ namespace osu.Game.Overlays.BeatmapListing
Font = OsuFont.GetFont(size: 13, weight: FontWeight.Regular),
Text = LabelFor(Value)
},
new HoverSounds(HoverSampleSet.TabSelect)
new HoverClickSounds(HoverSampleSet.TabSelect)
});
Enabled.Value = true;
SelectSample = audio.Samples.Get(@"UI/tabselect-select");
}
protected override void LoadComplete()
@ -77,8 +71,6 @@ namespace osu.Game.Overlays.BeatmapListing
protected override void OnDeactivated() => UpdateState();
protected override void OnActivatedByUser() => SelectSample.Play();
/// <summary>
/// Returns the label text to be used for the supplied <paramref name="value"/>.
/// </summary>

View File

@ -21,7 +21,7 @@ namespace osu.Game.Overlays.BeatmapSet
// propagate value to tab items first to enable only available rulesets.
beatmapSet.Value = value;
Current.Value = TabContainer.TabItems.FirstOrDefault(t => t.Enabled.Value)?.Value;
SelectTab(TabContainer.TabItems.FirstOrDefault(t => t.Enabled.Value));
}
}

View File

@ -11,8 +11,6 @@ using osuTK;
using osu.Framework.Input.Events;
using osu.Game.Graphics.UserInterface;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osuTK.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Localisation;
@ -67,8 +65,6 @@ namespace osu.Game.Overlays
private readonly SpriteIcon icon;
private Sample selectSample = null!;
public PanelDisplayTabItem(OverlayPanelDisplayStyle value)
: base(value)
{
@ -82,22 +78,14 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit
},
new HoverSounds(HoverSampleSet.TabSelect)
new HoverClickSounds()
});
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
selectSample = audio.Samples.Get(@"UI/tabselect-select");
}
protected override void OnActivated() => updateState();
protected override void OnDeactivated() => updateState();
protected override void OnActivatedByUser() => selectSample.Play();
protected override bool OnHover(HoverEvent e)
{
updateState();

View File

@ -10,8 +10,6 @@ using osu.Game.Rulesets;
using osuTK.Graphics;
using osuTK;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Localisation;
using osu.Game.Graphics.Containers;
@ -41,8 +39,6 @@ namespace osu.Game.Overlays
public LocalisableString TooltipText => Value.Name;
private Sample selectSample = null!;
public OverlayRulesetTabItem(RulesetInfo value)
: base(value)
{
@ -63,18 +59,12 @@ namespace osu.Game.Overlays
Icon = value.CreateInstance().CreateIcon(),
},
},
new HoverSounds(HoverSampleSet.TabSelect)
new HoverClickSounds()
});
Enabled.Value = true;
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
selectSample = audio.Samples.Get(@"UI/tabselect-select");
}
protected override void LoadComplete()
{
base.LoadComplete();
@ -100,8 +90,6 @@ namespace osu.Game.Overlays
protected override void OnDeactivated() => updateState();
protected override void OnActivatedByUser() => selectSample.Play();
private void updateState()
{
AccentColour = Enabled.Value ? getActiveColour() : colourProvider.Foreground1;

View File

@ -11,8 +11,6 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics;
using osuTK.Graphics;
@ -51,10 +49,8 @@ namespace osu.Game.Overlays
Margin = new MarginPadding(PADDING);
}
private Sample selectSample;
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider, OsuColour colours, AudioManager audio)
private void load(OverlayColourProvider colourProvider, OsuColour colours)
{
AddRange(new Drawable[]
{
@ -91,11 +87,9 @@ namespace osu.Game.Overlays
CollapsedSize = 2,
Expanded = true
},
new HoverSounds(HoverSampleSet.TabSelect)
new HoverClickSounds()
});
selectSample = audio.Samples.Get(@"UI/tabselect-select");
SelectedItem.BindValueChanged(_ => updateState(), true);
}
@ -111,8 +105,6 @@ namespace osu.Game.Overlays
protected override void OnDeactivated() => updateState();
protected override void OnActivatedByUser() => selectSample.Play();
protected override bool OnHover(HoverEvent e)
{
updateState();

View File

@ -4,8 +4,6 @@
#nullable disable
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
@ -82,8 +80,6 @@ namespace osu.Game.Overlays
}
}
private Sample selectSample = null!;
public OverlayTabItem(T value)
: base(value)
{
@ -105,16 +101,10 @@ namespace osu.Game.Overlays
ExpandedSize = 5f,
CollapsedSize = 0
},
new HoverSounds(HoverSampleSet.TabSelect)
new HoverClickSounds(HoverSampleSet.TabSelect)
};
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
selectSample = audio.Samples.Get(@"UI/tabselect-select");
}
protected override bool OnHover(HoverEvent e)
{
base.OnHover(e);
@ -146,8 +136,6 @@ namespace osu.Game.Overlays
Text.Font = Text.Font.With(weight: FontWeight.Medium);
}
protected override void OnActivatedByUser() => selectSample.Play();
private void updateState()
{
if (Active.Value)

View File

@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Numerics;
using System.Globalization;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterface;
@ -13,7 +12,7 @@ namespace osu.Game.Overlays.Settings.Sections
/// A slider intended to show a "size" multiplier number, where 1x is 1.0.
/// </summary>
public partial class SizeSlider<T> : RoundedSliderBar<T>
where T : struct, INumber<T>, IMinMaxValue<T>, IFormattable
where T : struct, IEquatable<T>, IComparable<T>, IConvertible, IFormattable
{
public override LocalisableString TooltipText => Current.Value.ToString(@"0.##x", NumberFormatInfo.CurrentInfo);
}

View File

@ -1,7 +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.
using System.Numerics;
using System;
using osu.Framework.Graphics;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Settings
/// Mostly provided for convenience of use with <see cref="SettingSourceAttribute"/>.
/// </summary>
public partial class SettingsPercentageSlider<TValue> : SettingsSlider<TValue>
where TValue : struct, INumber<TValue>, IMinMaxValue<TValue>
where TValue : struct, IEquatable<TValue>, IComparable<TValue>, IConvertible
{
protected override Drawable CreateControl() => ((RoundedSliderBar<TValue>)base.CreateControl()).With(sliderBar => sliderBar.DisplayAsPercentage = true);
}

View File

@ -1,7 +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.
using System.Numerics;
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.UserInterface;
@ -9,12 +9,12 @@ using osu.Game.Graphics.UserInterface;
namespace osu.Game.Overlays.Settings
{
public partial class SettingsSlider<T> : SettingsSlider<T, RoundedSliderBar<T>>
where T : struct, INumber<T>, IMinMaxValue<T>
where T : struct, IEquatable<T>, IComparable<T>, IConvertible
{
}
public partial class SettingsSlider<TValue, TSlider> : SettingsItem<TValue>
where TValue : struct, INumber<TValue>, IMinMaxValue<TValue>
where TValue : struct, IEquatable<TValue>, IComparable<TValue>, IConvertible
where TSlider : RoundedSliderBar<TValue>, new()
{
protected override Drawable CreateControl() => new TSlider

View File

@ -3,8 +3,11 @@
#nullable disable
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -21,6 +24,8 @@ namespace osu.Game.Overlays.Toolbar
{
protected Drawable ModeButtonLine { get; private set; }
private readonly Dictionary<string, Sample> selectionSamples = new Dictionary<string, Sample>();
public ToolbarRulesetSelector()
{
RelativeSizeAxes = Axes.Y;
@ -28,7 +33,7 @@ namespace osu.Game.Overlays.Toolbar
}
[BackgroundDependencyLoader]
private void load()
private void load(AudioManager audio)
{
AddRangeInternal(new[]
{
@ -54,6 +59,9 @@ namespace osu.Game.Overlays.Toolbar
}
},
});
foreach (var ruleset in Rulesets.AvailableRulesets)
selectionSamples[ruleset.ShortName] = audio.Samples.Get($"UI/ruleset-select-{ruleset.ShortName}");
}
protected override void LoadComplete()
@ -80,6 +88,10 @@ namespace osu.Game.Overlays.Toolbar
if (SelectedTab != null)
{
ModeButtonLine.MoveToX(SelectedTab.DrawPosition.X, !hasInitialPosition ? 0 : 500, Easing.OutElasticQuarter);
if (hasInitialPosition)
selectionSamples[SelectedTab.Value.ShortName]?.Play();
hasInitialPosition = true;
}
}
@ -109,7 +121,7 @@ namespace osu.Game.Overlays.Toolbar
RulesetInfo found = Rulesets.AvailableRulesets.ElementAtOrDefault(requested);
if (found != null)
SelectItem(found);
Current.Value = found;
return true;
}

View File

@ -2,8 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
@ -19,8 +17,6 @@ namespace osu.Game.Overlays.Toolbar
{
private readonly RulesetButton ruleset;
private Sample? selectSample;
public ToolbarRulesetTabButton(RulesetInfo value)
: base(value)
{
@ -38,18 +34,10 @@ namespace osu.Game.Overlays.Toolbar
ruleset.SetIcon(rInstance.CreateIcon());
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
selectSample = audio.Samples.Get($@"UI/ruleset-select-{Value.ShortName}");
}
protected override void OnActivated() => ruleset.Active = true;
protected override void OnDeactivated() => ruleset.Active = false;
protected override void OnActivatedByUser() => selectSample?.Play();
private partial class RulesetButton : ToolbarButton
{
protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverSounds();

View File

@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Mods
}
}
private float maxValue = 10; // matches default max value of `CurrentNumber`
private float maxValue;
public float MaxValue
{

View File

@ -15,6 +15,7 @@ using osu.Framework.Extensions.ListExtensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Extensions.TypeExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Lists;
using osu.Framework.Threading;
using osu.Framework.Utils;
@ -631,7 +632,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
#endregion
public override bool UpdateSubTreeMasking() => false;
public override bool UpdateSubTreeMasking(Drawable source, RectangleF maskingBounds) => false;
protected override void UpdateAfterChildren()
{

View File

@ -129,13 +129,6 @@ namespace osu.Game.Rulesets.Scoring
OnIterationFail?.Invoke($"FAILED drop {testDrop}: recovery too low ({recovery} < {hpRecoveryAvailable})");
}
if (!fail && double.IsInfinity(HpMultiplierNormal))
{
OnIterationSuccess?.Invoke("Drain computation algorithm diverged to infinity. PASSING with zero drop, resetting HP multiplier to 1.");
HpMultiplierNormal = 1;
return 0;
}
if (!fail)
{
OnIterationSuccess?.Invoke($"PASSED drop {testDrop}");

View File

@ -119,7 +119,7 @@ namespace osu.Game.Rulesets.UI
break;
base.UpdateSubTree();
UpdateSubTreeMasking();
UpdateSubTreeMasking(this, ScreenSpaceDrawQuad.AABBFloat);
} while (state == PlaybackState.RequiresCatchUp && stopwatch.ElapsedMilliseconds < max_catchup_milliseconds);
return true;

View File

@ -7,6 +7,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Caching;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Logging;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
@ -19,7 +20,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
public partial class TimelineTickDisplay : TimelinePart<PointVisualisation>
{
// With current implementation every tick in the sub-tree should be visible, no need to check whether they are masked away.
public override bool UpdateSubTreeMasking() => false;
public override bool UpdateSubTreeMasking(Drawable source, RectangleF maskingBounds) => false;
[Resolved]
private EditorBeatmap beatmap { get; set; } = null!;

View File

@ -372,7 +372,7 @@ namespace osu.Game.Screens.Edit
}
}
},
screenSwitcher = new EditorScreenSwitcherControl
new EditorScreenSwitcherControl
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
@ -662,23 +662,23 @@ namespace osu.Game.Screens.Edit
return true;
case GlobalAction.EditorComposeMode:
screenSwitcher.SelectItem(EditorScreenMode.Compose);
Mode.Value = EditorScreenMode.Compose;
return true;
case GlobalAction.EditorDesignMode:
screenSwitcher.SelectItem(EditorScreenMode.Design);
Mode.Value = EditorScreenMode.Design;
return true;
case GlobalAction.EditorTimingMode:
screenSwitcher.SelectItem(EditorScreenMode.Timing);
Mode.Value = EditorScreenMode.Timing;
return true;
case GlobalAction.EditorSetupMode:
screenSwitcher.SelectItem(EditorScreenMode.SongSetup);
Mode.Value = EditorScreenMode.SongSetup;
return true;
case GlobalAction.EditorVerifyMode:
screenSwitcher.SelectItem(EditorScreenMode.Verify);
Mode.Value = EditorScreenMode.Verify;
return true;
case GlobalAction.EditorTestGameplay:
@ -959,8 +959,6 @@ namespace osu.Game.Screens.Edit
[CanBeNull]
private ScheduledDelegate playbackDisabledDebounce;
private EditorScreenSwitcherControl screenSwitcher;
private void updateSampleDisabledState()
{
bool shouldDisableSamples = clock.SeekingOrStopped.Value

View File

@ -1,7 +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.
using System.Numerics;
using System;
using System.Globalization;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@ -12,7 +12,7 @@ using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Overlays.Settings;
using osu.Game.Utils;
using Vector2 = osuTK.Vector2;
using osuTK;
namespace osu.Game.Screens.Edit.Timing
{
@ -22,7 +22,7 @@ namespace osu.Game.Screens.Edit.Timing
/// by providing an "indeterminate state".
/// </summary>
public partial class IndeterminateSliderWithTextBoxInput<T> : CompositeDrawable, IHasCurrentValue<T?>
where T : struct, INumber<T>, IMinMaxValue<T>
where T : struct, IEquatable<T>, IComparable<T>, IConvertible
{
/// <summary>
/// A custom step value for each key press which actuates a change on this control.
@ -136,7 +136,7 @@ namespace osu.Game.Screens.Edit.Timing
slider.Current.Value = nonNullValue;
// use the value from the slider to ensure that any precision/min/max set on it via the initial indeterminate value have been applied correctly.
decimal decimalValue = decimal.CreateTruncating(slider.Current.Value);
decimal decimalValue = slider.Current.Value.ToDecimal(NumberFormatInfo.InvariantInfo);
textBox.Text = decimalValue.ToString($@"N{FormatUtils.FindPrecision(decimalValue)}");
textBox.PlaceholderText = string.Empty;
}

View File

@ -4,8 +4,6 @@
#nullable disable
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -80,17 +78,14 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components
},
},
},
new HoverSounds(HoverSampleSet.TabSelect),
new HoverClickSounds(),
};
}
private Sample selectSample;
[BackgroundDependencyLoader]
private void load(OsuColour colours, AudioManager audio)
private void load(OsuColour colours)
{
selection.Colour = colours.Yellow;
selectSample = audio.Samples.Get(@"UI/tabselect-select");
}
protected override bool OnHover(HoverEvent e)
@ -114,8 +109,6 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components
{
selection.FadeOut(transition_duration, Easing.OutQuint);
}
protected override void OnActivatedByUser() => selectSample.Play();
}
}
}

View File

@ -1,7 +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.
using System.Numerics;
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Graphics;
@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings;
namespace osu.Game.Screens.Play.PlayerSettings
{
public partial class PlayerSliderBar<T> : SettingsSlider<T>
where T : struct, INumber<T>, IMinMaxValue<T>
where T : struct, IEquatable<T>, IComparable<T>, IConvertible
{
public RoundedSliderBar<T> Bar => (RoundedSliderBar<T>)Control;

View File

@ -35,8 +35,8 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Realm" Version="11.5.0" />
<PackageReference Include="ppy.osu.Framework" Version="2024.509.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2024.510.0" />
<PackageReference Include="ppy.osu.Framework" Version="2024.329.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2024.517.0" />
<PackageReference Include="Sentry" Version="4.3.0" />
<!-- Held back due to 0.34.0 failing AOT compilation on ZstdSharp.dll dependency. -->
<PackageReference Include="SharpCompress" Version="0.36.0" />

View File

@ -23,6 +23,6 @@
<RuntimeIdentifier>iossimulator-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.iOS" Version="2024.509.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2024.329.0" />
</ItemGroup>
</Project>