Skip to content

Commit

Permalink
Merge pull request #6234 from Susko3/upgrade-to-SDL3
Browse files Browse the repository at this point in the history
Upgrade to SDL3
  • Loading branch information
bdach committed Apr 9, 2024
2 parents 20d55fa + d5af283 commit f950831
Show file tree
Hide file tree
Showing 43 changed files with 1,895 additions and 2,484 deletions.
4 changes: 2 additions & 2 deletions osu.Framework.Tests/Visual/Platform/TestSceneBorderless.cs
Expand Up @@ -24,7 +24,7 @@ public partial class TestSceneBorderless : FrameworkTestScene
private readonly SpriteText currentWindowMode = new SpriteText();
private readonly SpriteText currentDisplay = new SpriteText();

private SDL2Window? window;
private SDL3Window? window;
private readonly Bindable<WindowMode> windowMode = new Bindable<WindowMode>();

public TestSceneBorderless()
Expand Down Expand Up @@ -57,7 +57,7 @@ public TestSceneBorderless()
[BackgroundDependencyLoader]
private void load(FrameworkConfigManager config, GameHost host)
{
window = host.Window as SDL2Window;
window = host.Window as SDL3Window;
config.BindWith(FrameworkSetting.WindowMode, windowMode);

windowMode.BindValueChanged(mode => currentWindowMode.Text = $"Window Mode: {mode.NewValue}", true);
Expand Down
Expand Up @@ -44,7 +44,7 @@ public void TestChangeCurrentDisplay(WindowState startingState)

WindowMode startingMode = getWindowModeForState(startingState);

// this shouldn't be necessary, but SDL2DesktopWindow doesn't set the config WindowMode when changing the WindowState only.
// this shouldn't be necessary, but SDL3DesktopWindow doesn't set the config WindowMode when changing the WindowState only.
AddStep($"switch to {startingMode}", () => window.WindowMode.Value = startingMode);

AddStep($"switch to {startingState}", () => window.WindowState = startingState);
Expand Down
2 changes: 1 addition & 1 deletion osu.Framework.Tests/Visual/Platform/TestSceneFullscreen.cs
Expand Up @@ -129,7 +129,7 @@ public void TestScreenModeSwitch()
if (window.SupportedWindowModes.Contains(WindowMode.Fullscreen))
{
AddStep("change to fullscreen", () => windowMode.Value = WindowMode.Fullscreen);
AddAssert("window position updated", () => ((SDL2Window)window).Position, () => Is.EqualTo(window.CurrentDisplayBindable.Value.Bounds.Location));
AddAssert("window position updated", () => ((SDL3Window)window).Position, () => Is.EqualTo(window.CurrentDisplayBindable.Value.Bounds.Location));
testResolution(1920, 1080);
testResolution(1280, 960);
testResolution(9999, 9999);
Expand Down
4 changes: 2 additions & 2 deletions osu.Framework.Tests/Visual/Platform/TestSceneWindowed.cs
Expand Up @@ -31,12 +31,12 @@ public partial class TestSceneWindowed : FrameworkTestScene
[Resolved]
private FrameworkConfigManager config { get; set; }

private SDL2Window sdlWindow;
private SDL3Window sdlWindow;

[BackgroundDependencyLoader]
private void load()
{
sdlWindow = (SDL2Window)host.Window;
sdlWindow = (SDL3Window)host.Window;
Children = new Drawable[]
{
new FillFlowContainer
Expand Down
4 changes: 2 additions & 2 deletions osu.Framework.Tests/Visual/Platform/WindowDisplaysPreview.cs
Expand Up @@ -36,7 +36,7 @@ public partial class WindowDisplaysPreview : Container
private static readonly Color4 window_fill = new Color4(95, 113, 197, 255);
private static readonly Color4 window_stroke = new Color4(36, 59, 166, 255);

private SDL2Window? window;
private SDL3Window? window;
private readonly Bindable<WindowMode> windowMode = new Bindable<WindowMode>();
private readonly Bindable<Display> currentDisplay = new Bindable<Display>();

Expand Down Expand Up @@ -90,7 +90,7 @@ public WindowDisplaysPreview()
[BackgroundDependencyLoader]
private void load(FrameworkConfigManager config, GameHost host)
{
window = host.Window as SDL2Window;
window = host.Window as SDL3Window;
config.BindWith(FrameworkSetting.WindowMode, windowMode);

if (window != null)
Expand Down
14 changes: 7 additions & 7 deletions osu.Framework.iOS/GameApplication.cs
Expand Up @@ -2,14 +2,14 @@
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using AVFoundation;
using Foundation;
using ManagedBass;
using ManagedBass.Fx;
using ManagedBass.Mix;
using ObjCRuntime;
using SDL2;
using SDL;

namespace osu.Framework.iOS
{
Expand All @@ -22,20 +22,20 @@ public static class GameApplication

private static readonly OutputVolumeObserver output_volume_observer = new OutputVolumeObserver();

public static void Main(Game target)
public static unsafe void Main(Game target)
{
NativeLibrary.SetDllImportResolver(typeof(Bass).Assembly, (_, assembly, path) => NativeLibrary.Load("@rpath/bass.framework/bass", assembly, path));
NativeLibrary.SetDllImportResolver(typeof(BassFx).Assembly, (_, assembly, path) => NativeLibrary.Load("@rpath/bass_fx.framework/bass_fx", assembly, path));
NativeLibrary.SetDllImportResolver(typeof(BassMix).Assembly, (_, assembly, path) => NativeLibrary.Load("@rpath/bassmix.framework/bassmix", assembly, path));
NativeLibrary.SetDllImportResolver(typeof(SDL3).Assembly, (_, assembly, path) => NativeLibrary.Load("@rpath/SDL3.framework/SDL3", assembly, path));

game = target;

SDL.PrepareLibraryForIOS();
SDL.SDL_UIKitRunApp(0, IntPtr.Zero, main);
SDL3.SDL_RunApp(0, null, &main, IntPtr.Zero);
}

[MonoPInvokeCallback(typeof(SDL.SDL_main_func))]
private static int main(int argc, IntPtr argv)
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
private static unsafe int main(int argc, byte** argv)
{
var audioSession = AVAudioSession.SharedInstance();
audioSession.AddObserver(output_volume_observer, output_volume, NSKeyValueObservingOptions.New, 0);
Expand Down
2 changes: 1 addition & 1 deletion osu.Framework.iOS/IOSGameHost.cs
Expand Up @@ -21,7 +21,7 @@

namespace osu.Framework.iOS
{
public class IOSGameHost : SDL2GameHost
public class IOSGameHost : SDL3GameHost
{
public IOSGameHost()
: base(string.Empty)
Expand Down
18 changes: 10 additions & 8 deletions osu.Framework.iOS/IOSWindow.cs
Expand Up @@ -4,16 +4,18 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using ObjCRuntime;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Platform;
using SDL2;
using SDL;
using UIKit;

namespace osu.Framework.iOS
{
internal class IOSWindow : SDL2Window
internal class IOSWindow : SDL3Window
{
private UIWindow? window;

Expand All @@ -34,10 +36,10 @@ public IOSWindow(GraphicsSurfaceType surfaceType)
{
}

protected override void UpdateWindowStateAndSize(WindowState state, Display display, DisplayMode displayMode)
protected override unsafe void UpdateWindowStateAndSize(WindowState state, Display display, DisplayMode displayMode)
{
// This sets the status bar to hidden.
SDL.SDL_SetWindowFullscreen(SDLWindowHandle, (uint)SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN);
SDL3.SDL_SetWindowFullscreen(SDLWindowHandle, SDL_bool.SDL_TRUE);

// Don't run base logic at all. Let's keep things simple.
}
Expand All @@ -50,7 +52,7 @@ public override void Create()
updateSafeArea();
}

protected override void RunMainLoop()
protected override unsafe void RunMainLoop()
{
// Delegate running the main loop to CADisplayLink.
//
Expand All @@ -60,11 +62,11 @@ protected override void RunMainLoop()
// iOS may be a good forward direction if this ever comes up, as a user may see a potentially higher
// frame rate with multi-threaded mode turned on, but it is going to give them worse input latency
// and higher power usage.
SDL.SDL_iPhoneSetEventPump(SDL.SDL_bool.SDL_FALSE);
SDL.SDL_iPhoneSetAnimationCallback(SDLWindowHandle, 1, runFrame, ObjectHandle.Handle);
SDL3.SDL_iPhoneSetEventPump(SDL_bool.SDL_FALSE);
SDL3.SDL_iPhoneSetAnimationCallback(SDLWindowHandle, 1, &runFrame, ObjectHandle.Handle);
}

[ObjCRuntime.MonoPInvokeCallback(typeof(SDL.SDL_iPhoneAnimationCallback))]
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
private static void runFrame(IntPtr userdata)
{
var handle = new ObjectHandle<IOSWindow>(userdata);
Expand Down
2 changes: 1 addition & 1 deletion osu.Framework/Extensions/BridgingExtensions.cs
Expand Up @@ -12,7 +12,7 @@ namespace osu.Framework.Extensions
{
/// <summary>
/// Temporary extension functions for bridging between osuTK, System.Drawing, and System.Numerics
/// Can be removed when the SDL2 migration is complete.
/// Can be removed when the SDL3 migration is complete.
/// </summary>
public static class BridgingExtensions
{
Expand Down
2 changes: 1 addition & 1 deletion osu.Framework/Extensions/ExtensionMethods.cs
Expand Up @@ -350,7 +350,7 @@ public static string TrimDirectorySeparator(this string path)
/// <param name="resolution">The <see cref="DisplayResolution"/> to convert.</param>
/// <returns>A <see cref="DisplayMode"/> structure populated with the corresponding properties.</returns>
internal static DisplayMode ToDisplayMode(this DisplayResolution resolution) =>
new DisplayMode(null, new Size(resolution.Width, resolution.Height), resolution.BitsPerPixel, (int)Math.Round(resolution.RefreshRate), 0);
new DisplayMode(null, new Size(resolution.Width, resolution.Height), resolution.BitsPerPixel, resolution.RefreshRate, 0);

/// <summary>
/// Checks whether the provided URL is a safe protocol to execute a system <see cref="Process.Start()"/> call with.
Expand Down
2 changes: 1 addition & 1 deletion osu.Framework/Input/Handlers/Joystick/JoystickHandler.cs
Expand Up @@ -29,7 +29,7 @@ public override bool Initialize(GameHost host)
if (!base.Initialize(host))
return false;

if (!(host.Window is SDL2Window window))
if (!(host.Window is SDL3Window window))
return false;

Enabled.BindValueChanged(e =>
Expand Down
2 changes: 1 addition & 1 deletion osu.Framework/Input/Handlers/Keyboard/KeyboardHandler.cs
Expand Up @@ -21,7 +21,7 @@ public override bool Initialize(GameHost host)
if (!base.Initialize(host))
return false;

if (!(host.Window is SDL2Window window))
if (!(host.Window is SDL3Window window))
return false;

Enabled.BindValueChanged(e =>
Expand Down
6 changes: 3 additions & 3 deletions osu.Framework/Input/Handlers/Mouse/MouseHandler.cs
Expand Up @@ -15,7 +15,7 @@
namespace osu.Framework.Input.Handlers.Mouse
{
/// <summary>
/// Handles mouse events from an <see cref="SDL2Window"/>.
/// Handles mouse events from an <see cref="SDL3Window"/>.
/// Will use relative mouse mode where possible.
/// </summary>
public class MouseHandler : InputHandler, IHasCursorSensitivity, INeedsMousePositionFeedback
Expand All @@ -41,7 +41,7 @@ public class MouseHandler : InputHandler, IHasCursorSensitivity, INeedsMousePosi

public override bool IsActive => true;

private SDL2Window window;
private SDL3Window window;

private Vector2? lastPosition;

Expand Down Expand Up @@ -76,7 +76,7 @@ public override bool Initialize(GameHost host)
if (!base.Initialize(host))
return false;

if (!(host.Window is SDL2Window desktopWindow))
if (!(host.Window is SDL3Window desktopWindow))
return false;

window = desktopWindow;
Expand Down
2 changes: 1 addition & 1 deletion osu.Framework/Input/Handlers/Touch/TouchHandler.cs
Expand Up @@ -18,7 +18,7 @@ public override bool Initialize(GameHost host)
if (!base.Initialize(host))
return false;

if (!(host.Window is SDL2Window window))
if (!(host.Window is SDL3Window window))
return false;

Enabled.BindValueChanged(enabled =>
Expand Down
Expand Up @@ -6,11 +6,11 @@

namespace osu.Framework.Input
{
internal class SDL2WindowTextInput : TextInputSource
internal class SDL3WindowTextInput : TextInputSource
{
private readonly SDL2Window window;
private readonly SDL3Window window;

public SDL2WindowTextInput(SDL2Window window)
public SDL3WindowTextInput(SDL3Window window)
{
this.window = window;
}
Expand Down
2 changes: 1 addition & 1 deletion osu.Framework/Input/UserInputManager.cs
Expand Up @@ -90,7 +90,7 @@ private bool mouseOutsideAllDisplays(Vector2 mousePosition)
switch (Host.Window.WindowMode.Value)
{
case WindowMode.Windowed:
windowLocation = Host.Window is SDL2Window sdlWindow ? sdlWindow.Position : Point.Empty;
windowLocation = Host.Window is SDL3Window sdlWindow ? sdlWindow.Position : Point.Empty;
break;

default:
Expand Down
2 changes: 1 addition & 1 deletion osu.Framework/Platform/DesktopGameHost.cs
Expand Up @@ -13,7 +13,7 @@

namespace osu.Framework.Platform
{
public abstract class DesktopGameHost : SDL2GameHost
public abstract class DesktopGameHost : SDL3GameHost
{
private TcpIpcProvider ipcProvider;
private readonly int? ipcPort;
Expand Down
4 changes: 2 additions & 2 deletions osu.Framework/Platform/DisplayMode.cs
Expand Up @@ -29,14 +29,14 @@ namespace osu.Framework.Platform
/// <summary>
/// The refresh rate in hertz.
/// </summary>
public readonly int RefreshRate;
public readonly float RefreshRate;

/// <summary>
/// The index of the display this mode belongs to as determined by the windowing backend.
/// </summary>
public readonly int DisplayIndex;

public DisplayMode(string? format, Size size, int bitsPerPixel, int refreshRate, int displayIndex)
public DisplayMode(string? format, Size size, int bitsPerPixel, float refreshRate, int displayIndex)
{
Format = format ?? "Unknown";
Size = size;
Expand Down
6 changes: 3 additions & 3 deletions osu.Framework/Platform/GameHost.cs
Expand Up @@ -732,7 +732,7 @@ public void Run(Game game)

ChooseAndSetupRenderer();

// Window creation may fail in the case of a catastrophic failure (ie. graphics driver or SDL2 level).
// Window creation may fail in the case of a catastrophic failure (ie. graphics driver or SDL3 level).
// In such cases, we want to throw here to immediately mark this renderer setup as failed.
if (RequireWindowExists && Window == null)
{
Expand Down Expand Up @@ -780,7 +780,7 @@ public void Run(Game game)
{
switch (Window)
{
case SDL2Window window:
case SDL3Window window:
window.Update += windowUpdate;
break;

Expand Down Expand Up @@ -1323,7 +1323,7 @@ private void updateFrameSyncMode()
if (Window == null)
return;

int refreshRate = Window.CurrentDisplayMode.Value.RefreshRate;
int refreshRate = (int)MathF.Round(Window.CurrentDisplayMode.Value.RefreshRate);

// For invalid refresh rates let's assume 60 Hz as it is most common.
if (refreshRate <= 0)
Expand Down
8 changes: 4 additions & 4 deletions osu.Framework/Platform/Linux/LinuxGameHost.cs
Expand Up @@ -3,10 +3,10 @@

using System.Collections.Generic;
using System.Linq;
using SDL2;
using osu.Framework.Input;
using osu.Framework.Input.Handlers;
using osu.Framework.Input.Handlers.Mouse;
using SDL;

namespace osu.Framework.Platform.Linux
{
Expand All @@ -29,11 +29,11 @@ internal LinuxGameHost(string gameName, HostOptions? options)

protected override void SetupForRun()
{
SDL.SDL_SetHint(SDL.SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, BypassCompositor ? "1" : "0");
SDL3.SDL_SetHint(SDL3.SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, BypassCompositor ? "1"u8 : "0"u8);
base.SetupForRun();
}

protected override IWindow CreateWindow(GraphicsSurfaceType preferredSurface) => new SDL2DesktopWindow(preferredSurface);
protected override IWindow CreateWindow(GraphicsSurfaceType preferredSurface) => new SDL3DesktopWindow(preferredSurface);

protected override ReadableKeyCombinationProvider CreateReadableKeyCombinationProvider() => new LinuxReadableKeyCombinationProvider();

Expand All @@ -43,7 +43,7 @@ protected override IEnumerable<InputHandler> CreateAvailableInputHandlers()

foreach (var h in handlers.OfType<MouseHandler>())
{
// There are several bugs we need to fix with Linux / SDL2 cursor handling before switching this on.
// There are several bugs we need to fix with Linux / SDL3 cursor handling before switching this on.
h.UseRelativeMode.Value = false;
h.UseRelativeMode.Default = false;
}
Expand Down
Expand Up @@ -2,12 +2,12 @@
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Input.Bindings;
using osu.Framework.Platform.SDL2;
using SDL2;
using osu.Framework.Platform.SDL;
using SDL;

namespace osu.Framework.Platform.Linux
{
public class LinuxReadableKeyCombinationProvider : SDL2ReadableKeyCombinationProvider
public class LinuxReadableKeyCombinationProvider : SDL3ReadableKeyCombinationProvider
{
protected override string GetReadableKey(InputKey key)
{
Expand All @@ -21,15 +21,15 @@ protected override string GetReadableKey(InputKey key)
}
}

protected override bool TryGetNameFromKeycode(SDL.SDL_Keycode keycode, out string name)
protected override bool TryGetNameFromKeycode(SDL_Keycode keycode, out string name)
{
switch (keycode)
{
case SDL.SDL_Keycode.SDLK_LGUI:
case SDL_Keycode.SDLK_LGUI:
name = "LSuper";
return true;

case SDL.SDL_Keycode.SDLK_RGUI:
case SDL_Keycode.SDLK_RGUI:
name = "RSuper";
return true;

Expand Down

0 comments on commit f950831

Please sign in to comment.