diff --git a/Blarg.GameFramework.SDL2/Blarg.GameFramework.SDL2.csproj b/Blarg.GameFramework.SDL2/Blarg.GameFramework.SDL2.csproj index 17fec1e..25a7532 100644 --- a/Blarg.GameFramework.SDL2/Blarg.GameFramework.SDL2.csproj +++ b/Blarg.GameFramework.SDL2/Blarg.GameFramework.SDL2.csproj @@ -48,6 +48,7 @@ + diff --git a/Blarg.GameFramework.SDL2/SDLLooper.cs b/Blarg.GameFramework.SDL2/SDLLooper.cs new file mode 100644 index 0000000..7c102d9 --- /dev/null +++ b/Blarg.GameFramework.SDL2/SDLLooper.cs @@ -0,0 +1,119 @@ +using System; +using SDL2; +using Blarg.GameFramework.Input; +using Blarg.GameFramework.IO; + +namespace Blarg.GameFramework +{ + public class SDLLooper : ILooper + { + bool _isSDLinited; + IntPtr _window; + IntPtr _glContext; + SDLKeyboard _keyboard; + SDLMouse _mouse; + SDLFileSystem _filesystem; + + public SDLLooper() + { + } + + public void Run(IGameApp gameApp) + { + if (gameApp == null) + throw new ArgumentNullException("gameApp"); + + Platform.Services.Logger.Info("Looper", "Running..."); + + if (!InitSDL()) + { + Platform.Services.Logger.Error("Looper", "SDL initialization failed. Aborting."); + return; + } + } + + private bool InitSDL() + { + Platform.Services.Logger.Info("Looper", "SDL initialization starting."); + + SDL.SDL_version sdlVersion; + SDL.SDL_VERSION(out sdlVersion); + Platform.Services.Logger.Info("Looper", "SDL Runtime Version: {0}.{1}.{2}", sdlVersion.major, sdlVersion.minor, sdlVersion.patch); + Platform.Services.Logger.Info("Looper", "SDL Linked Version: {0}.{1}.{2}", SDL.SDL_MAJOR_VERSION, SDL.SDL_MINOR_VERSION, SDL.SDL_PATCHLEVEL); + + if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO | SDL.SDL_INIT_AUDIO | SDL.SDL_INIT_GAMECONTROLLER | SDL.SDL_INIT_JOYSTICK | SDL.SDL_INIT_TIMER) == -1) + { + Platform.Services.Logger.Error("Looper", "SDL_Init() failed: {0}", SDL.SDL_GetError()); + return false; + } + + _keyboard = new SDLKeyboard(); + Platform.Services.Logger.Info("Looper", "Keyboard input device ready."); + + _mouse = new SDLMouse(); + Platform.Services.Logger.Info("Looper", "Mouse input device ready."); + + int numJoysticks = SDL.SDL_NumJoysticks(); + + Platform.Services.Logger.Info("Looper", "{0} joystick input devices found.", numJoysticks); + for (int i = 0; i < numJoysticks; ++i) + { + Platform.Services.Logger.Info("Looper", "Joystick #{0}. {1}:", (i + 1), SDL.SDL_JoystickNameForIndex(i)); + IntPtr joystick = SDL.SDL_JoystickOpen(i); + if (joystick != IntPtr.Zero) + { + Platform.Services.Logger.Info("Looper", "\tAxes: {0}", SDL.SDL_JoystickNumAxes(joystick)); + Platform.Services.Logger.Info("Looper", "\tBalls: {0}", SDL.SDL_JoystickNumBalls(joystick)); + Platform.Services.Logger.Info("Looper", "\tHats: {0}", SDL.SDL_JoystickNumHats(joystick)); + Platform.Services.Logger.Info("Looper", "\tButtons: {0}", SDL.SDL_JoystickNumButtons(joystick)); + SDL.SDL_JoystickClose(joystick); + } + else + Platform.Services.Logger.Warn("Looper", "\tMore information could not be obtained."); + } + + _filesystem = new SDLFileSystem(); + Platform.Services.Logger.Info("Looper", "Filesystem access initialized."); + + Platform.Services.Logger.Info("Looper", "SDL initialization finished."); + return true; + } + + #region IDisposable + + private void ReleaseSDL() + { + if (!_isSDLinited) + return; + + if (_glContext != IntPtr.Zero) + { + SDL.SDL_GL_DeleteContext(_glContext); + _glContext = IntPtr.Zero; + } + if (_window != IntPtr.Zero) + { + SDL.SDL_DestroyWindow(_window); + _window = IntPtr.Zero; + } + + SDL.SDL_Quit(); + + Platform.Services.Logger.Info("Looper", "SDL shutdown."); + } + + ~SDLLooper() + { + ReleaseSDL(); + } + + public void Dispose() + { + ReleaseSDL(); + GC.SuppressFinalize(this); + } + + #endregion + } +} + diff --git a/Blarg.GameFramework/ILooper.cs b/Blarg.GameFramework/ILooper.cs index 31ff8a6..f794b61 100644 --- a/Blarg.GameFramework/ILooper.cs +++ b/Blarg.GameFramework/ILooper.cs @@ -2,7 +2,7 @@ using System; namespace Blarg.GameFramework { - public interface ILooper + public interface ILooper : IDisposable { void Run(IGameApp gameApp); }