Skip to content

Commit

Permalink
Temporary rollback of framework / SDL3
Browse files Browse the repository at this point in the history
  • Loading branch information
peppy committed May 21, 2024
1 parent e740b8b commit d7d569c
Show file tree
Hide file tree
Showing 44 changed files with 304 additions and 226 deletions.
2 changes: 1 addition & 1 deletion osu.Android.props
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
76 changes: 76 additions & 0 deletions osu.Android/AndroidJoystickSettings.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
97 changes: 97 additions & 0 deletions osu.Android/AndroidMouseSettings.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
22 changes: 22 additions & 0 deletions osu.Android/OsuGameAndroid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
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;

Expand Down Expand Up @@ -84,6 +88,24 @@ public override void SetHost(GameHost host)

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;
Expand Down
11 changes: 5 additions & 6 deletions osu.Desktop/OsuGameDesktop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
using osu.Game.Online.Multiplayer;
using osu.Game.Performance;
using osu.Game.Utils;
using SDL;
using SDL2;

namespace osu.Desktop
{
Expand Down Expand Up @@ -161,7 +161,7 @@ public override void SetHost(GameHost host)
host.Window.Title = Name;
}

protected override BatteryInfo CreateBatteryInfo() => new SDL3BatteryInfo();
protected override BatteryInfo CreateBatteryInfo() => new SDL2BatteryInfo();

protected override void Dispose(bool isDisposing)
{
Expand All @@ -170,14 +170,13 @@ protected override void Dispose(bool isDisposing)
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;
Expand All @@ -186,7 +185,7 @@ public override double? ChargeLevel
}
}

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;
}
}
}
33 changes: 12 additions & 21 deletions osu.Desktop/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
using osu.Game;
using osu.Game.IPC;
using osu.Game.Tournament;
using SDL;
using SDL2;
using Squirrel;

namespace osu.Desktop
Expand Down Expand Up @@ -52,19 +52,16 @@ public static void Main(string[] args)
// 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();
Expand Down Expand Up @@ -107,13 +104,7 @@ public static void Main(string[] args)
}
}

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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ protected override void LoadComplete()
}

// 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.
Expand Down
3 changes: 2 additions & 1 deletion osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
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;
Expand Down Expand Up @@ -36,7 +37,7 @@ public partial class OsuPlayfield : Playfield

// 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; }
Expand Down
3 changes: 2 additions & 1 deletion osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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;
Expand Down Expand Up @@ -344,7 +345,7 @@ private partial class ProxyContainer : LifetimeManagementContainer
{
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.
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Tournament/Screens/Ladder/LadderDragContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public partial class LadderDragContainer : Container

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)
{
Expand Down
5 changes: 0 additions & 5 deletions osu.Game/Database/EmptyRealmSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using JetBrains.Annotations;
using Realms;
using Realms.Schema;

Expand All @@ -16,12 +15,8 @@ public class EmptyRealmSet<T> : IRealmCollection<T>
{
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);
Expand Down
Loading

0 comments on commit d7d569c

Please sign in to comment.