2#pragma warning disable CA1416
9using System.Runtime.InteropServices;
11using System.Diagnostics;
12using System.Reflection;
13using System.Runtime.CompilerServices;
16using SixLabors.ImageSharp;
17using SixLabors.ImageSharp.PixelFormats;
19using Monitor = Silk.NET.Windowing.Monitor;
21using System.Runtime.InteropServices;
25using Silk.NET.Windowing;
30using Silk.NET.Core.Contexts;
51 public static EngineActivity Activity => EngineActivity.m_activity;
53 public static SDLSurface m_surface;
63#pragma warning disable CS0169
65#pragma warning restore CS0169
80 if (monitor ==
null) {
82 monitor =
Monitor.GetMainMonitor(
null);
85 if (e is PlatformNotSupportedException) {
88 "GLFW Window Platform is not applicable. Please install Microsoft Visual C++ Redistributable. Click \"OK\" to open download page.\nGLFW 窗口平台无法使用。请安装 Microsoft Visual C++ Redistributable,点击\"确定\"来打开下载页面。";
89 const string downloadLink =
90 "https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version";
91 Log.
Error($
"GLFW Window Platform is not applicable. Please install Microsoft Visual C++ Redistributable. GLFW 窗口平台无法使用。请安装 Microsoft Visual C++ Redistributable。\nDownload page 下载页: {downloadLink}\nException details: {e}");
93 if (MessageBox(IntPtr.Zero, str,
null, 0x11u) == 1) {
97 ) { UseShellExecute =
true }
103 if (OperatingSystem.IsLinux()) {
105 "GLFW Window Platform is not applicable. Please check: https://dotnet.github.io/Silk.NET/docs/hlu/troubleshooting.html";
106 Process.Start(
"notify-send", $
"-a \"Survivalcraft API\" -u critical \"Error\" \"{str}\"");
112 Log.
Error($
"Get screen size failed.\n{e}");
117 Vector2D<int> size = monitor.Bounds.Size;
118 return new Point2(size.X, size.Y);
154 m_gameWindow.WindowBorder = WindowBorder.Fixed;
156 m_gameWindow.WindowState = WindowState.Normal;
160 m_gameWindow.WindowBorder = WindowBorder.Resizable;
162 m_gameWindow.WindowState = WindowState.Normal;
166 m_gameWindow.WindowBorder = WindowBorder.Hidden;
168 m_gameWindow.WindowState = WindowState.Normal;
172 m_gameWindow.WindowBorder = WindowBorder.Resizable;
173 m_gameWindow.WindowState = WindowState.Normal;
174 m_gameWindow.WindowState = WindowState.Fullscreen;
194#if !MOBILE && !BROWSER
198 m_gameWindow.Position =
new Vector2D<int>(value.X, value.Y);
216#if !MOBILE && !BROWSER
220 m_gameWindow.Size =
new Vector2D<int>(value.X, value.Y);
246 string newTitle = $
"{m_titlePrefix}{m_titleSuffix}";
250 m_gameWindow.Title = newTitle;
270 string newTitle = $
"{m_titlePrefix}{m_titleSuffix}";
274 m_gameWindow.Title = newTitle;
304 m_gameWindow.Title = value;
324 value = Math.Clamp(value, 0, 4);
329 m_view.GLContext?.SwapInterval(value);
340 INativeWindow native =
m_view.Native;
341 if (native !=
null) {
342 NativeWindowFlags kind = native.Kind;
343 if (kind.HasFlag(NativeWindowFlags.Win32)) {
344 return native.Win32?.Hwnd ?? IntPtr.Zero;
346 if (kind.HasFlag(NativeWindowFlags.Android)) {
347 return native.Android?.Window ?? IntPtr.Zero;
349 if (kind.HasFlag(NativeWindowFlags.X11)) {
350 return (IntPtr)(native.X11?.Window.ToUInt64() ?? 0UL);
352 if (kind.HasFlag(NativeWindowFlags.Wayland)) {
353 return native.Wayland?.Surface ?? IntPtr.Zero;
386 public static event Action<List<(Stream stream,
string fileName)>>
FileDropped;
398 throw new InvalidOperationException(
"Window is already opened.");
401 width = Math.Max(width, 0);
402 height = Math.Max(height, 0);
405 throw new ArgumentOutOfRangeException(nameof(height));
409 throw new ArgumentOutOfRangeException(nameof(width));
411 AppDomain.CurrentDomain.UnhandledException += delegate(
object _, UnhandledExceptionEventArgs args) {
412 Exception ex = args.ExceptionObject as Exception;
413 ex ??=
new Exception($
"Unknown exception. Additional information: {args.ExceptionObject}");
417 Log.
Error(
"Application terminating due to unhandled exception {0}", unhandledExceptionInfo.
Exception);
422 Silk.NET.Windowing.Window.ShouldLoadFirstPartyPlatforms(
false);
425#if DIRECT3D11 || ANGLE
426 GraphicsAPI api = GraphicsAPI.None;
428 GraphicsAPI api =
new(ContextAPI.OpenGLES, ContextProfile.Core, ContextFlags.Default,
new APIVersion(3, 0));
431 GraphicsAPI api =
new(ContextAPI.OpenGLES, ContextProfile.Compatability, ContextFlags.Debug,
new APIVersion(3, 2));
433 Activity.GetGlEsVersion(out
int major, out
int minor);
434 GraphicsAPI api =
new(ContextAPI.OpenGLES,
new APIVersion(major, minor));
436 GraphicsAPI api =
new(ContextAPI.OpenGLES,
new APIVersion(3, 2));
442 Log.
Information($
"Android.OS.Build.Manufacturer: {Build.Manufacturer}");
446 Log.
Information($
"Android.OS.Build.VERSION.SdkInt: {(int)Build.VERSION.SdkInt}");
447 ViewOptions options = ViewOptions.Default with { API = api };
448 m_view = Silk.NET.Windowing.Window.GetView(options);
449 Activity.Paused += PausedHandler;
450 Activity.Resumed += ResumedHandler;
451 Activity.Destroyed += DestroyedHandler;
452 Activity.NewIntent += NewIntentHandler;
454 ViewOptions options = ViewOptions.Default with { API = api };
455 m_view = Silk.NET.Windowing.Window.GetView(options);
460 if (screenSize.
X == 0
461 && screenSize.
Y == 0) {
464 width = width == 0 ? screenSize.X * 4 / 5 : width;
465 height = height == 0 ? screenSize.Y * 4 / 5 : height;
466 WindowOptions windowOptions = WindowOptions.Default with {
467 Title = title, PreferredDepthBufferBits = 24, PreferredStencilBufferBits = 8, API = api,
Size =
new Vector2D<int>(width, height)
469 m_gameWindow = Silk.NET.Windowing.Window.Create(windowOptions);
478 m_view.ShouldSwapAutomatically =
false;
484 catch (GlfwException e) {
485 if (e.ErrorCode == ErrorCode.VersionUnavailable) {
487 "Your graphics card driver does not support the graphics API used by the current program. Please try updating your graphics card driver or using the compatible patch.\n你的显卡驱动不支持当前程序使用的图形API,请尝试更新显卡驱动,或使用兼容补丁。";
490 new Thread(() => { MessageBox(IntPtr.Zero, str,
null, 0x10u); }).
Start();
492 if (OperatingSystem.IsLinux()) {
493 Process.Start(
"notify-send", $
"-a \"Survivalcraft API\" -u critical \"Error\" \"{str}\"");
498 Log.
Error($
"Unhandled exception.\n{e}");
578 List<(Stream stream,
string fileName)> results =
new(paths.Length);
579 foreach (
string path
in paths) {
581 Stream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
584 catch (Exception e) {
601 [UnmanagedCallersOnly]
602 public static int BrowserRenderFrameHandler(
double time, nint userData) {
627 if (Build.VERSION.SdkInt >= (BuildVersionCodes)21) {
628 Activity.FinishAndRemoveTask();
631 Activity.FinishAffinity();
651 public static void PausedHandler() {
659 public static void ResumedHandler() {
662 Activity.EnableImmersiveMode();
664 Time.QueueFrameIndexDelayedExecution(10, () => {
m_view.GLContext?.SwapInterval(0); });
670 public static void DestroyedHandler() {
680 public static void NewIntentHandler(Intent intent) {
683 Uri uriFromIntent = GetUriFromIntent(intent);
684 if (uriFromIntent !=
null) {
690 public static Uri GetUriFromIntent(Intent intent) {
692 if (!
string.IsNullOrEmpty(intent.DataString)) {
693 Uri.TryCreate(intent.DataString, UriKind.RelativeOrAbsolute, out result);
702 throw new InvalidOperationException(
"Window is not opened.");
723#if !MOBILE && !BROWSER
744 if (SDLActivity.ContentView is ViewGroup viewGroup
745 && viewGroup.ChildCount >= 1
746 && viewGroup.GetChildAt(0) is SDLSurface surface) {
749#elif !IOS && !BROWSER
750 using (Stream iconStream = typeof(
Window).GetTypeInfo().Assembly.GetManifestResourceStream(
"Engine.Resources.icon.png")) {
751 if (iconStream !=
null) {
753 byte[] pixelBytes =
new byte[image.Width * image.Height * Unsafe.SizeOf<Rgba32>()];
754 image.CopyPixelDataTo(pixelBytes);
755 m_gameWindow.SetWindowIcon([
new RawImage(image.Width, image.Height, pixelBytes)]);
758 InputWindowExtensions.ShouldLoadFirstPartyPlatforms(
false);
773 catch (Exception ex) {
774 Log.
Error($
"Error occupies in InitializeAll: {ex}");
814 [DllImport(
"user32.dll", CharSet = CharSet.Unicode)]
815 public static extern int MessageBox(IntPtr hWnd,
string text,
string caption, uint type);
Silk.NET.Windowing.Monitor Monitor
System.Environment Environment
static void BeforeFrame()
static partial void SetTitle(string title)
static partial void SetFullscreen(bool fullscreen)
static partial string GetTitle()
static partial void Reload()
static partial void Close()
static partial void Initialize(IntPtr sharedInputMemoryPtr)
static unsafe void RequestAnimationFrameLoop(void *f, nint userDataPtr)
static void BeforeFrame()
static void Present(int presentationInterval)
static void BeforeFrame()
static bool SwapInterval(IntPtr dpy, int interval)
static bool SwapBuffers(IntPtr dpy, IntPtr surface)
static void Error(object message)
static void Information(object message)
static string GetFileName(string path)
static void BeforeFrame()
readonly Exception Exception
static string m_titleSuffix
static void UnsubscribeFromEvents()
static void InitializeAll()
static string TitleSuffix
static bool m_closingRequested
static float m_lastRenderDelta
const string WindowingLibrary
static string TitlePrefix
static void Run(int width=0, int height=0, WindowMode windowMode=WindowMode.Resizable, string title="")
static void DisplayCutoutInsetsChangedHandler(Vector4 insets, bool hasWideNotch)
static void VerifyWindowOpened()
static void FocusedChangedHandler(bool focused)
static string m_titlePrefix
static Action Deactivated
static IInputContext m_inputContext
static Action< UnhandledExceptionInfo > UnhandledException
static Action< Vector4, bool > DisplayCutoutInsetsChanged
static IWindow m_gameWindow
static void FileDropHandler(string[] paths)
static ? int m_swapInterval
static Action< Uri > HandleUri
static WindowMode WindowMode
static void BeforeFrameAll()
static void SubscribeToEvents()
static int PresentationInterval
static Action< List<(Stream stream, string fileName)> > FileDropped
static void ClosedHandler()
static void LoadHandler()
static void ResizeHandler(Vector2D< int > _)
static bool IsWindowOpened()
const string InputLibrary
static Vector4 DisplayCutoutInsets
刘海/水滴/挖孔在屏幕边缘的宽度。X: 左边,Y: 顶部,Z: 右边,W: 底部
static void AfterFrameAll()
static void RenderFrameHandler(double lastRenderDelta)
static readonly Point2 Zero
static readonly Vector4 Zero