diff --git a/src/SlatedGameToolkit.Framework/DataTypes/FloatVector2.cs b/src/SlatedGameToolkit.Framework/DataTypes/FloatVector2.cs index 149a125..fd72c0d 100644 --- a/src/SlatedGameToolkit.Framework/DataTypes/FloatVector2.cs +++ b/src/SlatedGameToolkit.Framework/DataTypes/FloatVector2.cs @@ -2,5 +2,10 @@ namespace SlatedGameToolkit.Framework.DataTypes { public struct FloatVector2 { public volatile float x, y; + + public FloatVector2(float x, float y) { + this.x = x; + this.y = y; + } } } \ No newline at end of file diff --git a/src/SlatedGameToolkit.Framework/Exceptions/FrameworkException.cs b/src/SlatedGameToolkit.Framework/Exceptions/FrameworkException.cs new file mode 100644 index 0000000..a14656b --- /dev/null +++ b/src/SlatedGameToolkit.Framework/Exceptions/FrameworkException.cs @@ -0,0 +1,17 @@ +using System; + +namespace SlatedGameToolkit.Framework.Exceptions +{ + public abstract class FrameworkException : Exception { + public FrameworkException() { + + } + + public FrameworkException(string message) : base(message) { + + } + + public FrameworkException(string message, Exception inner) : base(message, inner) { + } + } +} \ No newline at end of file diff --git a/src/SlatedGameToolkit.Framework/Exceptions/FrameworkSDLException.cs b/src/SlatedGameToolkit.Framework/Exceptions/FrameworkSDLException.cs new file mode 100644 index 0000000..51571cc --- /dev/null +++ b/src/SlatedGameToolkit.Framework/Exceptions/FrameworkSDLException.cs @@ -0,0 +1,21 @@ +using System; + +namespace SlatedGameToolkit.Framework.Exceptions +{ + /// + /// Any errors generated by an SDL feature that the engine requires are wrapped in the form of this type of exception. + /// + public class FrameworkSDLException : SDLException { + + public FrameworkSDLException() : base() { + + } + + public FrameworkSDLException(string message) : base(message) { + + } + + public FrameworkSDLException(string message, Exception inner) : base(message, inner) { + } + } +} \ No newline at end of file diff --git a/src/SlatedGameToolkit.Framework/Exceptions/FrameworkUsageException.cs b/src/SlatedGameToolkit.Framework/Exceptions/FrameworkUsageException.cs new file mode 100644 index 0000000..5ea0489 --- /dev/null +++ b/src/SlatedGameToolkit.Framework/Exceptions/FrameworkUsageException.cs @@ -0,0 +1,20 @@ +using System; + +namespace SlatedGameToolkit.Framework.Exceptions +{ + /// + /// An exception that is thrown when there is an inappropriate use of the framework. + /// + public class FrameworkUsageException : FrameworkException { + public FrameworkUsageException() : base() { + + } + + public FrameworkUsageException(string message) : base(message) { + + } + + public FrameworkUsageException(string message, Exception inner) : base(message, inner) { + } + } +} \ No newline at end of file diff --git a/src/SlatedGameToolkit.Framework/Exceptions/InternalFrameworkException.cs b/src/SlatedGameToolkit.Framework/Exceptions/InternalFrameworkException.cs new file mode 100644 index 0000000..ac03516 --- /dev/null +++ b/src/SlatedGameToolkit.Framework/Exceptions/InternalFrameworkException.cs @@ -0,0 +1,18 @@ +using System; + +namespace SlatedGameToolkit.Framework.Exceptions +{ + internal class InternalFrameworkException : FrameworkException { + const string ADDITIONAL_MESSAGE = "\nThis exception is a framework bug!"; + public InternalFrameworkException() : base() { + + } + + public InternalFrameworkException(string message) : base(message + ADDITIONAL_MESSAGE) { + + } + + public InternalFrameworkException(string message, Exception inner) : base(message + ADDITIONAL_MESSAGE, inner) { + } + } +} \ No newline at end of file diff --git a/src/SlatedGameToolkit.Framework/Exceptions/OptionalSDLException.cs b/src/SlatedGameToolkit.Framework/Exceptions/OptionalSDLException.cs new file mode 100644 index 0000000..9d90c3a --- /dev/null +++ b/src/SlatedGameToolkit.Framework/Exceptions/OptionalSDLException.cs @@ -0,0 +1,22 @@ +using System; + +namespace SlatedGameToolkit.Framework.Exceptions +{ + /// + /// This exception is produced when the error producing SDL feature is not something the framework considers critical. + /// This can happen if not all framework supported platforms support a specific feature that SDL provides. + /// + public class OptionalSDLException : SDLException { + + public OptionalSDLException() : base() { + + } + + public OptionalSDLException(string message) : base(message) { + + } + + public OptionalSDLException(string message, Exception inner) : base(message, inner) { + } + } +} \ No newline at end of file diff --git a/src/SlatedGameToolkit.Framework/Exceptions/SDLException.cs b/src/SlatedGameToolkit.Framework/Exceptions/SDLException.cs index 938129c..afe4ff4 100644 --- a/src/SlatedGameToolkit.Framework/Exceptions/SDLException.cs +++ b/src/SlatedGameToolkit.Framework/Exceptions/SDLException.cs @@ -7,7 +7,7 @@ namespace SlatedGameToolkit.Framework.Exceptions /// An SDLException is defined as an exception that is thrown whenever an error occurrs in any SDL functions. /// [Serializable] - public class SDLException : Exception { + public abstract class SDLException : Exception { public string SDLMessage { get; } /// diff --git a/src/SlatedGameToolkit.Framework/Exceptions/SlatedGameToolkitException.cs b/src/SlatedGameToolkit.Framework/Exceptions/SlatedGameToolkitException.cs deleted file mode 100644 index 42484d5..0000000 --- a/src/SlatedGameToolkit.Framework/Exceptions/SlatedGameToolkitException.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace SlatedGameToolkit.Framework.Exceptions -{ - public class SlatedGameToolkitException : Exception { - public SlatedGameToolkitException() { - - } - - public SlatedGameToolkitException(string message) : base(message) { - - } - - public SlatedGameToolkitException(string message, Exception inner) : base(message, inner) { - } - } -} \ No newline at end of file diff --git a/src/SlatedGameToolkit.Framework/GameEngine.cs b/src/SlatedGameToolkit.Framework/GameEngine.cs index 278a599..e0d1ba2 100644 --- a/src/SlatedGameToolkit.Framework/GameEngine.cs +++ b/src/SlatedGameToolkit.Framework/GameEngine.cs @@ -5,7 +5,6 @@ using Serilog; using Serilog.Core; using SlatedGameToolkit.Framework.Exceptions; using SlatedGameToolkit.Framework.StateSystem; -using SlatedGameToolkit.Framework.Window; namespace SlatedGameToolkit.Framework { /// @@ -108,7 +107,7 @@ namespace SlatedGameToolkit.Framework { logger.Warning(String.Format("Engine was designed with SDL version {0}, currently running on {1}", SDLVersion.ToString(), SDLBuiltVersion.ToString())); if (SDLVersion.major < 2) { logger.Error("This engine was designed to work with SDL2. The version you're currently running is severely outdated."); - throw new SlatedGameToolkitException("Outdated SDL binaries."); + throw new FrameworkUsageException("Outdated SDL binaries."); } } lock (ignitionLock) { @@ -116,10 +115,10 @@ namespace SlatedGameToolkit.Framework { loopCompleted = false; exit = false; if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO) != 0) { - throw new SDLException(); + throw new FrameworkSDLException(); } if (SDL.SDL_Init(SDL.SDL_INIT_AUDIO) != 0) { - throw new SDLException(); + throw new FrameworkSDLException(); } thread = new Thread(Loop); thread.Start(manager); diff --git a/src/SlatedGameToolkit.Framework/Graphics/Window/WindowHandle.cs b/src/SlatedGameToolkit.Framework/Graphics/Window/WindowHandle.cs index 9dc6db0..b37473a 100644 --- a/src/SlatedGameToolkit.Framework/Graphics/Window/WindowHandle.cs +++ b/src/SlatedGameToolkit.Framework/Graphics/Window/WindowHandle.cs @@ -1,13 +1,17 @@ using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; using SDL2; using SlatedGameToolkit.Framework.DataTypes; using SlatedGameToolkit.Framework.Exceptions; namespace SlatedGameToolkit.Framework.Graphics.Window { + public delegate WindowRegion WindowRegionHit(FloatVector2 hitPoint); public sealed class WindowHandle : IDisposable { public readonly IntPtr window; + public event WindowRegionHit windowRegionHitEvent; IntPtr windowSurfaceHandle; public bool Shown { @@ -42,7 +46,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window get { int top, bottom, left, right; int errorCode = SDL.SDL_GetWindowBordersSize(window, out top, out left, out bottom, out right); - if (errorCode < 0) throw new SDLException(); + if (errorCode < 0) throw new OptionalSDLException(); return top > 0 || bottom > 0 || left > 0 || right > 0; } } @@ -92,12 +96,12 @@ namespace SlatedGameToolkit.Framework.Graphics.Window public float Opacity { set { int errorCode = SDL.SDL_SetWindowOpacity(window, value); - if (errorCode < 0) throw new SDLException(); + if (errorCode < 0) throw new OptionalSDLException(); } get { float value; int errorCode = SDL.SDL_GetWindowOpacity(window, out value); - if (errorCode < 0) throw new SDLException(); + if (errorCode < 0) throw new OptionalSDLException(); return value; } } @@ -116,18 +120,40 @@ namespace SlatedGameToolkit.Framework.Graphics.Window } } - public WindowHandle(string title, int x, int y, int width, int height, WindowOptions options) { + public bool GrabbingInput { + set { + SDL.SDL_SetWindowGrab(window, value ? SDL.SDL_bool.SDL_TRUE : SDL.SDL_bool.SDL_FALSE); + } + get { + return SDL.SDL_GetWindowGrab(window) == SDL.SDL_bool.SDL_TRUE ? true : false; + } + } + + public WindowHandle(string title, int x, int y, int width, int height, bool specialRegions, WindowOptions options) { window = SDL.SDL_CreateWindow(title, x, y, width, height, SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | options.ToSDLWindowFlag()); + if (window == null) { + throw new FrameworkSDLException(); + } + if (SDL.SDL_SetWindowHitTest(window, SpecialRegionHit, IntPtr.Zero) < 0) { + throw new OptionalSDLException(); + } windowSurfaceHandle = SDL.SDL_GetWindowSurface(window); } + private SDL.SDL_HitTestResult SpecialRegionHit(IntPtr window, IntPtr hitPtr, IntPtr data) { + SDL.SDL_Point SDLPoint = Marshal.PtrToStructure(hitPtr); + FloatVector2 point = new FloatVector2(SDLPoint.x, SDLPoint.y); + WindowRegion region = windowRegionHitEvent.Invoke(point); + return region.ToSDLHitTestResult(); + } + public void RaiseToTop() { SDL.SDL_RaiseWindow(window); } public int GetDisplayIndex() { int index = SDL.SDL_GetWindowDisplayIndex(window); - if (index < 0) throw new SDLException(); + if (index < 0) throw new FrameworkSDLException(); return index; } diff --git a/src/SlatedGameToolkit.Framework/Graphics/Window/WindowRegion.cs b/src/SlatedGameToolkit.Framework/Graphics/Window/WindowRegion.cs new file mode 100644 index 0000000..fa281cf --- /dev/null +++ b/src/SlatedGameToolkit.Framework/Graphics/Window/WindowRegion.cs @@ -0,0 +1,28 @@ +using System; +using SDL2; +using SlatedGameToolkit.Framework.Exceptions; + +namespace SlatedGameToolkit.Framework.Graphics.Window +{ + public enum WindowRegion { + NORMAL = SDL.SDL_HitTestResult.SDL_HITTEST_NORMAL, + DRAGGABLE = SDL.SDL_HitTestResult.SDL_HITTEST_DRAGGABLE, + TOP_LEFT = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_TOPLEFT, + TOP_RIGHT = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_TOPRIGHT, + BOTTOM_LEFT = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_BOTTOMLEFT, + BOTTOM_RIGHT = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_BOTTOMRIGHT, + TOP = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_TOP, + BOTTOM = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_BOTTOM, + RIGHT = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_RIGHT, + LEFT = SDL.SDL_HitTestResult.SDL_HITTEST_RESIZE_LEFT, + } + + internal static class WindowRegionExtensions { + public static SDL.SDL_HitTestResult ToSDLHitTestResult(this WindowRegion region) { + SDL.SDL_HitTestResult result; + if (!Enum.TryParse(((int) region).ToString(), out result)) throw new InternalFrameworkException("Unable to convert window regions."); + + return result; + } + } +} \ No newline at end of file diff --git a/src/SlatedGameToolkit.Framework/Graphics/Window/WindowsOptions.cs b/src/SlatedGameToolkit.Framework/Graphics/Window/WindowsOptions.cs index a59c640..b9bd260 100644 --- a/src/SlatedGameToolkit.Framework/Graphics/Window/WindowsOptions.cs +++ b/src/SlatedGameToolkit.Framework/Graphics/Window/WindowsOptions.cs @@ -1,5 +1,6 @@ using System; using SDL2; +using SlatedGameToolkit.Framework.Exceptions; namespace SlatedGameToolkit.Framework.Graphics.Window { @@ -11,7 +12,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window internal static class WindowOptionsExtension { public static SDL.SDL_WindowFlags ToSDLWindowFlag(this WindowOptions options) { SDL.SDL_WindowFlags sdlFlag; - Enum.TryParse(((uint) options).ToString(), out sdlFlag); + if (!(Enum.TryParse(((uint) options).ToString(), out sdlFlag))) throw new InternalFrameworkException("Unable to convert window options."); return sdlFlag; } }