Setup entry point + integrated moonworks stuff
This commit is contained in:
8
Nerfed.Runtime/Window/ScreenMode.cs
Normal file
8
Nerfed.Runtime/Window/ScreenMode.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Nerfed.Runtime;
|
||||
|
||||
public enum ScreenMode
|
||||
{
|
||||
Fullscreen,
|
||||
BorderlessFullscreen,
|
||||
Windowed
|
||||
}
|
234
Nerfed.Runtime/Window/Window.cs
Normal file
234
Nerfed.Runtime/Window/Window.cs
Normal file
@ -0,0 +1,234 @@
|
||||
using Nerfed.Runtime.Graphics;
|
||||
using SDL2;
|
||||
|
||||
namespace Nerfed.Runtime;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a window in the client operating system. <br/>
|
||||
/// Every Game has a MainWindow automatically. <br/>
|
||||
/// You can create additional Windows if you desire. They must be Claimed by the GraphicsDevice to be rendered to.
|
||||
/// </summary>
|
||||
public class Window
|
||||
{
|
||||
internal IntPtr Handle { get; }
|
||||
public ScreenMode ScreenMode { get; private set; }
|
||||
public uint Width { get; private set; }
|
||||
public uint Height { get; private set; }
|
||||
internal Texture SwapchainTexture { get; set; }
|
||||
|
||||
public bool Claimed { get; internal set; }
|
||||
public SwapchainComposition SwapchainComposition { get; internal set; }
|
||||
public TextureFormat SwapchainFormat { get; internal set; }
|
||||
|
||||
public (int, int) Position
|
||||
{
|
||||
get
|
||||
{
|
||||
SDL.SDL_GetWindowPosition(Handle, out int x, out int y);
|
||||
return (x, y);
|
||||
}
|
||||
}
|
||||
|
||||
public string Title { get; private set;}
|
||||
|
||||
private bool IsDisposed;
|
||||
private System.Action<uint, uint> SizeChangeCallback = null;
|
||||
|
||||
private static readonly Dictionary<uint, Window> windowsById = new Dictionary<uint, Window>();
|
||||
|
||||
public Window(GraphicsDevice graphicsDevice, WindowCreateInfo windowCreateInfo)
|
||||
{
|
||||
SDL.SDL_WindowFlags flags = SDL.SDL_WindowFlags.SDL_WINDOW_SHOWN;
|
||||
|
||||
if (graphicsDevice.Backend == BackendFlags.Vulkan)
|
||||
{
|
||||
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_VULKAN;
|
||||
}
|
||||
else if (graphicsDevice.Backend == BackendFlags.Metal)
|
||||
{
|
||||
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_METAL;
|
||||
}
|
||||
|
||||
if (windowCreateInfo.ScreenMode == ScreenMode.Fullscreen)
|
||||
{
|
||||
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN;
|
||||
}
|
||||
else if (windowCreateInfo.ScreenMode == ScreenMode.BorderlessFullscreen)
|
||||
{
|
||||
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
|
||||
if (windowCreateInfo.SystemResizable)
|
||||
{
|
||||
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE;
|
||||
}
|
||||
|
||||
if (windowCreateInfo.StartMaximized)
|
||||
{
|
||||
flags |= SDL.SDL_WindowFlags.SDL_WINDOW_MAXIMIZED;
|
||||
}
|
||||
|
||||
ScreenMode = windowCreateInfo.ScreenMode;
|
||||
|
||||
SDL.SDL_GetDesktopDisplayMode(0, out SDL.SDL_DisplayMode displayMode);
|
||||
|
||||
Handle = SDL.SDL_CreateWindow(
|
||||
windowCreateInfo.WindowTitle,
|
||||
SDL.SDL_WINDOWPOS_CENTERED,
|
||||
SDL.SDL_WINDOWPOS_CENTERED,
|
||||
windowCreateInfo.ScreenMode == ScreenMode.Windowed ? (int) windowCreateInfo.WindowWidth : displayMode.w,
|
||||
windowCreateInfo.ScreenMode == ScreenMode.Windowed ? (int) windowCreateInfo.WindowHeight : displayMode.h,
|
||||
flags
|
||||
);
|
||||
|
||||
/* Requested size might be different in fullscreen, so let's just get the area */
|
||||
SDL.SDL_GetWindowSize(Handle, out int width, out int height);
|
||||
Width = (uint) width;
|
||||
Height = (uint) height;
|
||||
|
||||
windowsById.Add(SDL.SDL_GetWindowID(Handle), this);
|
||||
}
|
||||
|
||||
internal static void ProcessEvent(ref SDL.SDL_Event ev)
|
||||
{
|
||||
uint windowId = ev.window.windowID;
|
||||
if (!windowsById.TryGetValue(windowId, out Window window))
|
||||
{
|
||||
Log.Error($"Received window event for unknown window id {windowsById}");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ev.window.windowEvent)
|
||||
{
|
||||
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
window.ProcessSizeChangedEvent(ref ev.window);
|
||||
break;
|
||||
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_CLOSE:
|
||||
window.ProcessCloseEvent(ref ev.window);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessSizeChangedEvent(ref SDL.SDL_WindowEvent ev)
|
||||
{
|
||||
uint newWidth = (uint)ev.data1;
|
||||
uint newHeight = (uint)ev.data2;
|
||||
Width = newWidth;
|
||||
Height = newHeight;
|
||||
|
||||
if (SizeChangeCallback != null)
|
||||
{
|
||||
SizeChangeCallback(newWidth, newHeight);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessCloseEvent(ref SDL.SDL_WindowEvent ev)
|
||||
{
|
||||
Engine.GraphicsDevice.UnclaimWindow(this);
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the ScreenMode of this window.
|
||||
/// </summary>
|
||||
public void SetScreenMode(ScreenMode screenMode)
|
||||
{
|
||||
SDL.SDL_WindowFlags windowFlag = 0;
|
||||
|
||||
if (screenMode == ScreenMode.Fullscreen)
|
||||
{
|
||||
windowFlag = SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN;
|
||||
}
|
||||
else if (screenMode == ScreenMode.BorderlessFullscreen)
|
||||
{
|
||||
windowFlag = SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
|
||||
SDL.SDL_SetWindowFullscreen(Handle, (uint) windowFlag);
|
||||
|
||||
if (screenMode == ScreenMode.Windowed)
|
||||
{
|
||||
SDL.SDL_SetWindowPosition(Handle, SDL.SDL_WINDOWPOS_CENTERED, SDL.SDL_WINDOWPOS_CENTERED);
|
||||
}
|
||||
|
||||
ScreenMode = screenMode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resizes the window. <br/>
|
||||
/// Note that you are responsible for recreating any graphics resources that need to change as a result of the size change.
|
||||
/// </summary>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
public void SetSize(uint width, uint height)
|
||||
{
|
||||
SDL.SDL_SetWindowSize(Handle, (int) width, (int) height);
|
||||
Width = width;
|
||||
Height = height;
|
||||
|
||||
if (ScreenMode == ScreenMode.Windowed)
|
||||
{
|
||||
SDL.SDL_SetWindowPosition(Handle, SDL.SDL_WINDOWPOS_CENTERED, SDL.SDL_WINDOWPOS_CENTERED);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the window position.
|
||||
/// </summary>
|
||||
public void SetPosition(int x, int y)
|
||||
{
|
||||
SDL.SDL_SetWindowPosition(Handle, x, y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the window title.
|
||||
/// </summary>
|
||||
public void SetTitle(string title)
|
||||
{
|
||||
SDL.SDL_SetWindowTitle(Handle, title);
|
||||
Title = title;
|
||||
}
|
||||
|
||||
internal void Show()
|
||||
{
|
||||
SDL.SDL_ShowWindow(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// You can specify a method to run when the window size changes.
|
||||
/// </summary>
|
||||
public void RegisterSizeChangeCallback(System.Action<uint, uint> sizeChangeCallback)
|
||||
{
|
||||
SizeChangeCallback = sizeChangeCallback;
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!IsDisposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// dispose managed state (managed objects)
|
||||
}
|
||||
|
||||
windowsById.Remove(SDL.SDL_GetWindowID(Handle));
|
||||
SDL.SDL_DestroyWindow(Handle);
|
||||
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
~Window()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
48
Nerfed.Runtime/Window/WindowCreateInfo.cs
Normal file
48
Nerfed.Runtime/Window/WindowCreateInfo.cs
Normal file
@ -0,0 +1,48 @@
|
||||
namespace Nerfed.Runtime;
|
||||
|
||||
/// <summary>
|
||||
/// All the information required for window creation.
|
||||
/// </summary>
|
||||
public struct WindowCreateInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the window that will be displayed in the operating system.
|
||||
/// </summary>
|
||||
public string WindowTitle;
|
||||
/// <summary>
|
||||
/// The width of the window.
|
||||
/// </summary>
|
||||
public uint WindowWidth;
|
||||
/// <summary>
|
||||
/// The height of the window.
|
||||
/// </summary>
|
||||
public uint WindowHeight;
|
||||
/// <summary>
|
||||
/// Specifies if the window will be created in windowed mode or a fullscreen mode.
|
||||
/// </summary>
|
||||
public ScreenMode ScreenMode;
|
||||
/// <summary>
|
||||
/// Whether the window can be resized using the operating system's window dragging feature.
|
||||
/// </summary>
|
||||
public bool SystemResizable;
|
||||
/// <summary>
|
||||
/// Specifies if the window will open at the maximum desktop resolution.
|
||||
/// </summary>
|
||||
public bool StartMaximized;
|
||||
|
||||
public WindowCreateInfo(
|
||||
string windowTitle,
|
||||
uint windowWidth,
|
||||
uint windowHeight,
|
||||
ScreenMode screenMode,
|
||||
bool systemResizable = false,
|
||||
bool startMaximized = false
|
||||
) {
|
||||
WindowTitle = windowTitle;
|
||||
WindowWidth = windowWidth;
|
||||
WindowHeight = windowHeight;
|
||||
ScreenMode = screenMode;
|
||||
SystemResizable = systemResizable;
|
||||
StartMaximized = startMaximized;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user