initial SDL platform implementation support
yay for code-dumps!
This commit is contained in:
parent
1b4abf1bfe
commit
6e321c77f3
|
@ -49,6 +49,10 @@
|
|||
<Compile Include="IO\SDLFileSystem.cs" />
|
||||
<Compile Include="SDLLogger.cs" />
|
||||
<Compile Include="SDLLooper.cs" />
|
||||
<Compile Include="SDLWindow.cs" />
|
||||
<Compile Include="SDLConfiguration.cs" />
|
||||
<Compile Include="SDLPlatformServices.cs" />
|
||||
<Compile Include="CurrentOS.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
|
152
Blarg.GameFramework.SDL2/CurrentOS.cs
Normal file
152
Blarg.GameFramework.SDL2/CurrentOS.cs
Normal file
|
@ -0,0 +1,152 @@
|
|||
//
|
||||
// CurrentOS Class by blez
|
||||
// http://blez.wordpress.com/2012/09/17/determine-os-with-netmono/
|
||||
// Detects the current OS (Windows, Linux, MacOS)
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace Blarg.GameFramework
|
||||
{
|
||||
public static class CurrentOS
|
||||
{
|
||||
public static bool IsWindows { get; private set; }
|
||||
public static bool IsUnix { get; private set; }
|
||||
public static bool IsMac { get; private set; }
|
||||
public static bool IsLinux { get; private set; }
|
||||
public static bool IsUnknown { get; private set; }
|
||||
public static bool Is32bit { get; private set; }
|
||||
public static bool Is64bit { get; private set; }
|
||||
public static bool Is64BitProcess { get { return (IntPtr.Size == 8); } }
|
||||
public static bool Is32BitProcess { get { return (IntPtr.Size == 4); } }
|
||||
public static string Name { get; private set; }
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool wow64Process);
|
||||
|
||||
private static bool Is64bitWindows
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major >= 6)
|
||||
{
|
||||
using (Process p = Process.GetCurrentProcess())
|
||||
{
|
||||
bool retVal;
|
||||
if (!IsWow64Process(p.Handle, out retVal))
|
||||
return false;
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static CurrentOS()
|
||||
{
|
||||
IsWindows = Path.DirectorySeparatorChar == '\\';
|
||||
if (IsWindows)
|
||||
{
|
||||
Name = Environment.OSVersion.VersionString;
|
||||
|
||||
Name = Name.Replace("Microsoft ", "");
|
||||
Name = Name.Replace(" ", " ");
|
||||
Name = Name.Replace(" )", ")");
|
||||
Name = Name.Trim();
|
||||
|
||||
Name = Name.Replace("NT 6.2", "8 %bit 6.2");
|
||||
Name = Name.Replace("NT 6.1", "7 %bit 6.1");
|
||||
Name = Name.Replace("NT 6.0", "Vista %bit 6.0");
|
||||
Name = Name.Replace("NT 5.", "XP %bit 5.");
|
||||
Name = Name.Replace("%bit", (Is64bitWindows ? "64bit" : "32bit"));
|
||||
|
||||
if (Is64bitWindows)
|
||||
Is64bit = true;
|
||||
else
|
||||
Is32bit = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
string UnixName = ReadProcessOutput("uname");
|
||||
if (UnixName.Contains("Darwin"))
|
||||
{
|
||||
IsUnix = true;
|
||||
IsMac = true;
|
||||
|
||||
Name = "MacOS X " + ReadProcessOutput("sw_vers", "-productVersion");
|
||||
Name = Name.Trim();
|
||||
|
||||
string machine = ReadProcessOutput("uname", "-m");
|
||||
if (machine.Contains("x86_64"))
|
||||
Is64bit = true;
|
||||
else
|
||||
Is32bit = true;
|
||||
|
||||
Name += " " + (Is32bit ? "32bit" : "64bit");
|
||||
}
|
||||
else if (UnixName.Contains("Linux"))
|
||||
{
|
||||
IsUnix = true;
|
||||
IsLinux = true;
|
||||
|
||||
Name = ReadProcessOutput("lsb_release", "-d");
|
||||
Name = Name.Substring(Name.IndexOf(":") + 1);
|
||||
Name = Name.Trim();
|
||||
|
||||
string machine = ReadProcessOutput("uname", "-m");
|
||||
if (machine.Contains("x86_64"))
|
||||
Is64bit = true;
|
||||
else
|
||||
Is32bit = true;
|
||||
|
||||
Name += " " + (Is32bit ? "32bit" : "64bit");
|
||||
}
|
||||
else if (UnixName != "")
|
||||
IsUnix = true;
|
||||
else
|
||||
IsUnknown = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static string ReadProcessOutput(string name)
|
||||
{
|
||||
return ReadProcessOutput(name, null);
|
||||
}
|
||||
|
||||
private static string ReadProcessOutput(string name, string args)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process p = new Process();
|
||||
p.StartInfo.UseShellExecute = false;
|
||||
p.StartInfo.RedirectStandardOutput = true;
|
||||
if (args != null && args != "")
|
||||
p.StartInfo.Arguments = " " + args;
|
||||
p.StartInfo.FileName = name;
|
||||
p.Start();
|
||||
// Do not wait for the child process to exit before
|
||||
// reading to the end of its redirected stream.
|
||||
// p.WaitForExit();
|
||||
// Read the output stream first and then wait.
|
||||
string output = p.StandardOutput.ReadToEnd();
|
||||
p.WaitForExit();
|
||||
if (output == null)
|
||||
output = "";
|
||||
output = output.Trim();
|
||||
return output;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
36
Blarg.GameFramework.SDL2/SDLConfiguration.cs
Normal file
36
Blarg.GameFramework.SDL2/SDLConfiguration.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
|
||||
namespace Blarg.GameFramework
|
||||
{
|
||||
public class SDLConfiguration : IPlatformConfiguration
|
||||
{
|
||||
public string Title;
|
||||
public int Width;
|
||||
public int Height;
|
||||
public bool Fullscreen;
|
||||
public bool Resizeable;
|
||||
|
||||
public bool glDoubleBuffer;
|
||||
public int glDepthBufferSize;
|
||||
public int glRedSize;
|
||||
public int glGreenSize;
|
||||
public int glBlueSize;
|
||||
public int glAlphaSize;
|
||||
|
||||
public SDLConfiguration()
|
||||
{
|
||||
Title = "SDL Application";
|
||||
Width = 854;
|
||||
Height = 480;
|
||||
Fullscreen = false;
|
||||
Resizeable = false;
|
||||
glDoubleBuffer = true;
|
||||
glDepthBufferSize = 24;
|
||||
glRedSize = 8;
|
||||
glGreenSize = 8;
|
||||
glBlueSize = 8;
|
||||
glAlphaSize = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +1,578 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using SDL2;
|
||||
using Blarg.GameFramework.Graphics;
|
||||
using Blarg.GameFramework.Input;
|
||||
using Blarg.GameFramework.IO;
|
||||
|
||||
namespace Blarg.GameFramework
|
||||
{
|
||||
public class SDLLooper : ILooper
|
||||
public class SDLLooper : BaseLooper
|
||||
{
|
||||
const string LOOPER_TAG = "SDLLOOPER";
|
||||
|
||||
bool _isSDLinited;
|
||||
IntPtr _window;
|
||||
IntPtr _glContext;
|
||||
SDLKeyboard _keyboard;
|
||||
SDLMouse _mouse;
|
||||
SDLFileSystem _filesystem;
|
||||
SDLWindow _windowInfo;
|
||||
|
||||
bool _isWindowActive;
|
||||
bool _isPaused;
|
||||
bool _isQuitting;
|
||||
|
||||
int _fps;
|
||||
float _frameTime;
|
||||
int _rendersPerSecond;
|
||||
int _updatesPerSecond;
|
||||
int _renderTime;
|
||||
int _updateTime;
|
||||
|
||||
int _targetUpdatesPerSecond;
|
||||
int _ticksPerUpdate;
|
||||
float _fixedUpdateInterval;
|
||||
float _fixedRenderInterval;
|
||||
int _maxFrameSkip = 10;
|
||||
|
||||
public override int FPS
|
||||
{
|
||||
get { return _fps; }
|
||||
}
|
||||
|
||||
public override float FrameTime
|
||||
{
|
||||
get { return _frameTime; }
|
||||
}
|
||||
|
||||
public override int RendersPerSecond
|
||||
{
|
||||
get { return _rendersPerSecond; }
|
||||
}
|
||||
|
||||
public override int UpdatesPerSecond
|
||||
{
|
||||
get { return _updatesPerSecond; }
|
||||
}
|
||||
|
||||
public override int RenderTime
|
||||
{
|
||||
get { return _renderTime; }
|
||||
}
|
||||
|
||||
public override int UpdateTime
|
||||
{
|
||||
get { return _updateTime; }
|
||||
}
|
||||
|
||||
public SDLLooper()
|
||||
{
|
||||
Platform.Services = new SDLPlatformServices();
|
||||
_windowInfo = new SDLWindow();
|
||||
|
||||
SetUpdateFrequency(60);
|
||||
}
|
||||
|
||||
public void Run(IGameApp gameApp)
|
||||
public override void Run(IGameApp gameApp, IPlatformConfiguration config)
|
||||
{
|
||||
if (gameApp == null)
|
||||
throw new ArgumentNullException("gameApp");
|
||||
GameApp = gameApp;
|
||||
|
||||
Platform.Services.Logger.Info("Looper", "Running...");
|
||||
if (config == null)
|
||||
throw new ArgumentNullException("config");
|
||||
if (!(config is SDLConfiguration))
|
||||
throw new ArgumentException("Must pass a SDLConfiguration object.", "config");
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Running...");
|
||||
|
||||
SDLConfiguration sdlConfig = (SDLConfiguration)config;
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Received SDL configuration:");
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tTitle: {0}", sdlConfig.Title);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tWidth: {0}", sdlConfig.Width);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tHeight: {0}", sdlConfig.Height);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tFullscreen: {0}", sdlConfig.Fullscreen);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tResizeable: {0}", sdlConfig.Resizeable);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "GL Doublebuffer: {0}", sdlConfig.glDoubleBuffer);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "GL Depth Buffer Size: {0}", sdlConfig.glDepthBufferSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "GL Red Size: {0}", sdlConfig.glRedSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "GL Green Size: {0}", sdlConfig.glGreenSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "GL Blue Size: {0}", sdlConfig.glBlueSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "GL Alpha Size: {0}", sdlConfig.glAlphaSize);
|
||||
|
||||
if (!InitSDL())
|
||||
{
|
||||
Platform.Services.Logger.Error("Looper", "SDL initialization failed. Aborting.");
|
||||
Platform.Services.Logger.Error(LOOPER_TAG, "SDL initialization failed. Aborting.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InitSDLWindow(sdlConfig))
|
||||
{
|
||||
Platform.Services.Logger.Error(LOOPER_TAG, "SDL window creation failed. Aborting.");
|
||||
return;
|
||||
}
|
||||
|
||||
(Platform.Services as SDLPlatformServices).Keyboard = _keyboard;
|
||||
(Platform.Services as SDLPlatformServices).Mouse = _mouse;
|
||||
(Platform.Services as SDLPlatformServices).FileSystem = _filesystem;
|
||||
(Platform.Services as SDLPlatformServices).GL = new PortableGL.SDL.SDLGL20();
|
||||
|
||||
OnNewContext();
|
||||
OnResize(ScreenOrientation.Rotation0, _windowInfo.ClientRectangle);
|
||||
OnLoad();
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Main loop starting.");
|
||||
MainLoop();
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Main loop finished.");
|
||||
|
||||
OnUnload();
|
||||
OnLostContext();
|
||||
|
||||
GameApp.Dispose();
|
||||
GameApp = null;
|
||||
|
||||
ReleaseSDL();
|
||||
}
|
||||
|
||||
private bool InitSDL()
|
||||
{
|
||||
Platform.Services.Logger.Info("Looper", "SDL initialization starting.");
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "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);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "SDL Runtime Version: {0}.{1}.{2}", sdlVersion.major, sdlVersion.minor, sdlVersion.patch);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "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());
|
||||
Platform.Services.Logger.Error(LOOPER_TAG, "SDL_Init() failed: {0}", SDL.SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
_isSDLinited = true;
|
||||
|
||||
_keyboard = new SDLKeyboard();
|
||||
Platform.Services.Logger.Info("Looper", "Keyboard input device ready.");
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Keyboard input device ready.");
|
||||
|
||||
_mouse = new SDLMouse();
|
||||
Platform.Services.Logger.Info("Looper", "Mouse input device ready.");
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Mouse input device ready.");
|
||||
|
||||
int numJoysticks = SDL.SDL_NumJoysticks();
|
||||
|
||||
Platform.Services.Logger.Info("Looper", "{0} joystick input devices found.", numJoysticks);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "{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));
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "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));
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tAxes: {0}", SDL.SDL_JoystickNumAxes(joystick));
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tBalls: {0}", SDL.SDL_JoystickNumBalls(joystick));
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tHats: {0}", SDL.SDL_JoystickNumHats(joystick));
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tButtons: {0}", SDL.SDL_JoystickNumButtons(joystick));
|
||||
SDL.SDL_JoystickClose(joystick);
|
||||
}
|
||||
else
|
||||
Platform.Services.Logger.Warn("Looper", "\tMore information could not be obtained.");
|
||||
Platform.Services.Logger.Warn(LOOPER_TAG, "\tMore information could not be obtained.");
|
||||
}
|
||||
|
||||
_filesystem = new SDLFileSystem();
|
||||
Platform.Services.Logger.Info("Looper", "Filesystem access initialized.");
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Filesystem access initialized.");
|
||||
|
||||
Platform.Services.Logger.Info("Looper", "SDL initialization finished.");
|
||||
int numVideoDrivers = SDL.SDL_GetNumVideoDrivers();
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Video drivers present: {0}.", numVideoDrivers);
|
||||
for (int i = 0; i < numVideoDrivers; ++i)
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\t{0}: {1}", (i + 1), SDL.SDL_GetVideoDriver(i));
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Currently using video driver: {0}", SDL.SDL_GetCurrentVideoDriver());
|
||||
|
||||
int numAudioDrivers = SDL.SDL_GetNumAudioDrivers();
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Audio drivers present: {0}", numAudioDrivers);
|
||||
for (int i = 0; i < numAudioDrivers; ++i)
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\t{0}: {1}", (i + 1), SDL.SDL_GetAudioDriver(i));
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Currently using audio driver: {0}", SDL.SDL_GetCurrentAudioDriver());
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "SDL initialization finished.");
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetUpdateFrequency(int targetFrequency)
|
||||
{
|
||||
_targetUpdatesPerSecond = targetFrequency;
|
||||
_ticksPerUpdate = 1000 / _targetUpdatesPerSecond;
|
||||
_fixedUpdateInterval = _ticksPerUpdate / 1000.0f;
|
||||
}
|
||||
|
||||
private void MainLoop()
|
||||
{
|
||||
_isWindowActive = true;
|
||||
_isPaused = false;
|
||||
_isQuitting = false;
|
||||
|
||||
int numUpdatesThisFrame = 0;
|
||||
int numLoops = 0;
|
||||
int timeElapsed = 0;
|
||||
bool isDirty = false;
|
||||
|
||||
bool isRunningSlowly = false;
|
||||
|
||||
int updateTime = 0;
|
||||
int renderTime = 0;
|
||||
int numUpdates = 0;
|
||||
int numRenders = 0;
|
||||
|
||||
int nextUpdateAt = Environment.TickCount;
|
||||
int currentTime = Environment.TickCount;
|
||||
|
||||
while (!_isQuitting)
|
||||
{
|
||||
if (_isPaused)
|
||||
{
|
||||
// we always want to be processing events, even when paused
|
||||
DoEvents();
|
||||
}
|
||||
else
|
||||
{
|
||||
int newTime = Environment.TickCount;
|
||||
int frameTime = newTime - currentTime;
|
||||
currentTime = newTime;
|
||||
timeElapsed += frameTime;
|
||||
|
||||
// every second recalculate the FPS
|
||||
if (timeElapsed >= 1000)
|
||||
{
|
||||
_fps = numLoops;
|
||||
_frameTime = 1000.0f / _fps;
|
||||
|
||||
_rendersPerSecond = numRenders;
|
||||
_updatesPerSecond = numUpdates;
|
||||
_renderTime = renderTime;
|
||||
_updateTime = updateTime;
|
||||
|
||||
numUpdates = 0;
|
||||
numRenders = 0;
|
||||
|
||||
numLoops = 0;
|
||||
timeElapsed = 0;
|
||||
}
|
||||
|
||||
// we're "running slowly" if we're more then one update behind
|
||||
if (currentTime > nextUpdateAt + _ticksPerUpdate)
|
||||
isRunningSlowly = true;
|
||||
else
|
||||
isRunningSlowly = false;
|
||||
|
||||
numUpdatesThisFrame = 0;
|
||||
while (Environment.TickCount >= nextUpdateAt && numUpdatesThisFrame < _maxFrameSkip)
|
||||
{
|
||||
if (numUpdatesThisFrame > 0)
|
||||
isRunningSlowly = true;
|
||||
|
||||
int before = Environment.TickCount;
|
||||
DoEvents();
|
||||
OnUpdate(_fixedUpdateInterval);
|
||||
updateTime += Environment.TickCount - before;
|
||||
|
||||
++numUpdatesThisFrame;
|
||||
nextUpdateAt += _ticksPerUpdate;
|
||||
|
||||
++numUpdates;
|
||||
|
||||
// just updated, so we need to render the new game state
|
||||
isDirty = true;
|
||||
}
|
||||
|
||||
if (isDirty && _isWindowActive)
|
||||
{
|
||||
int before = Environment.TickCount;
|
||||
OnRender(_fixedRenderInterval); // TODO
|
||||
SDL.SDL_GL_SwapWindow(_window);
|
||||
renderTime += Environment.TickCount - before;
|
||||
|
||||
++numRenders;
|
||||
|
||||
// don't render again until we hve something new to show
|
||||
isDirty = false;
|
||||
}
|
||||
|
||||
++numLoops;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Window Management
|
||||
|
||||
private bool InitSDLWindow(SDLConfiguration config)
|
||||
{
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "SDL Window initialization starting.");
|
||||
|
||||
int flags = (int)SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | (int)SDL.SDL_WindowFlags.SDL_WINDOW_SHOWN;
|
||||
if (config.Fullscreen)
|
||||
flags |= (int)SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN;
|
||||
if (config.Resizeable)
|
||||
flags |= (int)SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE;
|
||||
|
||||
if (!CreateWindow(config.Title, config.Width, config.Height, flags))
|
||||
return false;
|
||||
|
||||
if (!CreateOpenGLContext(config))
|
||||
return false;
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "SDL Window initialization finished.");
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool CreateWindow(string title, int width, int height, int flags)
|
||||
{
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Attempting to set up new window with dimensions {0}x{1}.", width, height);
|
||||
if (_window != IntPtr.Zero)
|
||||
throw new InvalidOperationException("Cannot create new window before destorying existing one.");
|
||||
|
||||
_window = SDL.SDL_CreateWindow(title, SDL.SDL_WINDOWPOS_UNDEFINED, SDL.SDL_WINDOWPOS_UNDEFINED, width, height, (SDL.SDL_WindowFlags)flags);
|
||||
if (_window == IntPtr.Zero)
|
||||
{
|
||||
Platform.Services.Logger.Error(LOOPER_TAG, "Window creation failed: {0}", SDL.SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
SetWindowInfo();
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Window creation succeeded.");
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool DestroyWindow()
|
||||
{
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Destroying window.");
|
||||
if (_window == IntPtr.Zero)
|
||||
{
|
||||
Platform.Services.Logger.Warn(LOOPER_TAG, "No window currently exists, not doing anything.");
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL.SDL_DestroyWindow(_window);
|
||||
_window = IntPtr.Zero;
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Window destroyed.");
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetWindowInfo()
|
||||
{
|
||||
if (_window == IntPtr.Zero)
|
||||
throw new InvalidOperationException("Cannot set window info for a non-existant window.");
|
||||
|
||||
int windowX;
|
||||
int windowY;
|
||||
SDL.SDL_GetWindowPosition(_window, out windowX, out windowY);
|
||||
|
||||
int clientWidth;
|
||||
int clientHeight;
|
||||
SDL.SDL_GetWindowSize(_window, out clientWidth, out clientHeight);
|
||||
|
||||
_windowInfo.ClientWidth = clientWidth;
|
||||
_windowInfo.ClientHeight = clientHeight;
|
||||
_windowInfo.ClientRectangle = new Rect(0, 0, clientWidth, clientHeight);
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Window content area set to {0}", _windowInfo.ClientRectangle);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OpenGL Context Management
|
||||
|
||||
private bool CreateOpenGLContext(SDLConfiguration config)
|
||||
{
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Attempting to create OpenGL context.");
|
||||
if (_glContext != IntPtr.Zero)
|
||||
throw new InvalidOperationException("Cannoy create new OpenGL context before destroying existing one.");
|
||||
if (_window == IntPtr.Zero)
|
||||
throw new InvalidOperationException("Cannot create an OpenGL context without an existing window.");
|
||||
|
||||
// minimum requirements
|
||||
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DOUBLEBUFFER, config.glDoubleBuffer ? 1 : 0);
|
||||
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DEPTH_SIZE, config.glDepthBufferSize);
|
||||
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_RED_SIZE, config.glRedSize);
|
||||
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_GREEN_SIZE, config.glGreenSize);
|
||||
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_BLUE_SIZE, config.glBlueSize);
|
||||
SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_ALPHA_SIZE, config.glAlphaSize);
|
||||
|
||||
_glContext = SDL.SDL_GL_CreateContext(_window);
|
||||
if (_glContext == IntPtr.Zero)
|
||||
{
|
||||
Platform.Services.Logger.Error(LOOPER_TAG, "OpenGL context creation failed: {0}", SDL.SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "OpenGL context creation succeeded.");
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Setting OpenTK's OpenGL context and loading OpenGL extensions.");
|
||||
OpenTK.Graphics.GraphicsContext.CurrentContext = _glContext;
|
||||
OpenTK.Graphics.OpenGL.GL.LoadAll();
|
||||
|
||||
int redSize;
|
||||
int greenSize;
|
||||
int blueSize;
|
||||
int alphaSize;
|
||||
int bufferSize;
|
||||
int doubleBuffer;
|
||||
int depthSize;
|
||||
int stencilSize;
|
||||
int accumRedSize;
|
||||
int accumGreenSize;
|
||||
int accumBlueSize;
|
||||
int accumAlphaSize;
|
||||
int stereo;
|
||||
int multisampleBuffers;
|
||||
int multisampleSamples;
|
||||
int acceleratedVisual;
|
||||
int contextMajorVersion;
|
||||
int contextMinorVersion;
|
||||
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_RED_SIZE, out redSize);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_GREEN_SIZE, out greenSize);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_BLUE_SIZE, out blueSize);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_ALPHA_SIZE, out alphaSize);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_BUFFER_SIZE, out bufferSize);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_DOUBLEBUFFER, out doubleBuffer);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_DEPTH_SIZE, out depthSize);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_STENCIL_SIZE, out stencilSize);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_ACCUM_RED_SIZE, out accumRedSize);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_ACCUM_GREEN_SIZE, out accumGreenSize);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_ACCUM_BLUE_SIZE, out accumBlueSize);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_ACCUM_ALPHA_SIZE, out accumAlphaSize);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_STEREO, out stereo);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_MULTISAMPLEBUFFERS, out multisampleBuffers);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_MULTISAMPLESAMPLES, out multisampleSamples);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_ACCELERATED_VISUAL, out acceleratedVisual);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MAJOR_VERSION, out contextMajorVersion);
|
||||
SDL.SDL_GL_GetAttribute(SDL.SDL_GLattr.SDL_GL_CONTEXT_MINOR_VERSION, out contextMinorVersion);
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "OpenGL context attributes:");
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_RED_SIZE: {0}", redSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_GREEN_SIZE: {0}", greenSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_BLUE_SIZE: {0}", blueSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_ALPHA_SIZE: {0}", alphaSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_BUFFER_SIZE: {0}", bufferSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_DOUBLEBUFFER: {0}", doubleBuffer);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_DEPTH_SIZE: {0}", depthSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_STENCIL_SIZE: {0}", stencilSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_ACCUM_RED_SIZE: {0}", accumRedSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_ACCUM_GREEN_SIZE: {0}", accumGreenSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_ACCUM_BLUE_SIZE: {0}", accumBlueSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_ACCUM_ALPHA_SIZE: {0}", accumAlphaSize);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_STEREO: {0}", stereo);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_MULTISAMPLEBUFFERS: {0}", multisampleBuffers);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_MULTISAMPLESAMPLES: {0}", multisampleSamples);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_ACCELERATED_VISUAL: {0}", acceleratedVisual);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_CONTEXT_MAJOR_VERSION: {0}", contextMajorVersion);
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "\tGL_CONTEXT_MINOR_VERSION: {0}", contextMinorVersion);
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Attempting to enable V-sync.");
|
||||
if (SDL.SDL_GL_SetSwapInterval(1) != 0)
|
||||
Platform.Services.Logger.Warn(LOOPER_TAG, "Could not set swap interval: {0}", SDL.SDL_GetError());
|
||||
else
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Swap interval set successful.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool DestroyOpenGLContext()
|
||||
{
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Destroying OpenGL context.");
|
||||
if (_glContext == IntPtr.Zero)
|
||||
{
|
||||
Platform.Services.Logger.Warn(LOOPER_TAG, "No OpenGL context currently exists, not doing anything.");
|
||||
return true;
|
||||
}
|
||||
|
||||
SDL.SDL_GL_DeleteContext(_glContext);
|
||||
_glContext = IntPtr.Zero;
|
||||
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "OpenGL context destroyed.");
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
private void DoEvents()
|
||||
{
|
||||
SDL.SDL_Event e;
|
||||
while (SDL.SDL_PollEvent(out e) != 0)
|
||||
{
|
||||
if (e.type == SDL.SDL_EventType.SDL_WINDOWEVENT)
|
||||
{
|
||||
switch (e.window.windowEvent)
|
||||
{
|
||||
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_MINIMIZED:
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Window focus lost.");
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Window marked inactive.");
|
||||
break;
|
||||
|
||||
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESTORED:
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Window focus gained.");
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Window marked active.");
|
||||
break;
|
||||
|
||||
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_ENTER:
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Gained mouse focus.");
|
||||
break;
|
||||
|
||||
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_LEAVE:
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Lost mouse focus.");
|
||||
break;
|
||||
|
||||
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Gained input device focus.");
|
||||
OnAppGainFocus();
|
||||
break;
|
||||
|
||||
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Lost input device focus.");
|
||||
OnAppLostFocus();
|
||||
break;
|
||||
|
||||
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED:
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Window resized to {0}x{1}.", e.window.data1, e.window.data2);
|
||||
Rect size = new Rect();
|
||||
size.Right = e.window.data1;
|
||||
size.Bottom = e.window.data2;
|
||||
SetWindowInfo();
|
||||
OnResize(ScreenOrientation.Rotation0, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (e.type)
|
||||
{
|
||||
case SDL.SDL_EventType.SDL_QUIT:
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Event: SQL_QUIT");
|
||||
_isQuitting = true;
|
||||
break;
|
||||
|
||||
case SDL.SDL_EventType.SDL_KEYDOWN:
|
||||
case SDL.SDL_EventType.SDL_KEYUP:
|
||||
_keyboard.OnKeyEvent(e.key);
|
||||
break;
|
||||
|
||||
case SDL.SDL_EventType.SDL_MOUSEMOTION:
|
||||
_mouse.OnMotionEvent(e.motion);
|
||||
break;
|
||||
|
||||
case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN:
|
||||
case SDL.SDL_EventType.SDL_MOUSEBUTTONUP:
|
||||
_mouse.OnButtonEvent(e.button);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable
|
||||
|
||||
private void ReleaseSDL()
|
||||
|
@ -86,20 +580,14 @@ namespace Blarg.GameFramework
|
|||
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;
|
||||
}
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "Releasing SDL.");
|
||||
|
||||
DestroyOpenGLContext();
|
||||
DestroyWindow();
|
||||
SDL.SDL_Quit();
|
||||
_isSDLinited = false;
|
||||
|
||||
Platform.Services.Logger.Info("Looper", "SDL shutdown.");
|
||||
Platform.Services.Logger.Info(LOOPER_TAG, "SDL shutdown.");
|
||||
}
|
||||
|
||||
~SDLLooper()
|
||||
|
@ -107,7 +595,7 @@ namespace Blarg.GameFramework
|
|||
ReleaseSDL();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public override void Dispose()
|
||||
{
|
||||
ReleaseSDL();
|
||||
GC.SuppressFinalize(this);
|
||||
|
|
38
Blarg.GameFramework.SDL2/SDLPlatformServices.cs
Normal file
38
Blarg.GameFramework.SDL2/SDLPlatformServices.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using PortableGL;
|
||||
using Blarg.GameFramework.Input;
|
||||
using Blarg.GameFramework.IO;
|
||||
|
||||
namespace Blarg.GameFramework
|
||||
{
|
||||
public class SDLPlatformServices : IPlatformServices
|
||||
{
|
||||
public SDLPlatformServices()
|
||||
{
|
||||
if (CurrentOS.IsWindows)
|
||||
OperatingSystem = PlatformOS.Windows;
|
||||
else if (CurrentOS.IsLinux)
|
||||
OperatingSystem = PlatformOS.Linux;
|
||||
else if (CurrentOS.IsMac)
|
||||
OperatingSystem = PlatformOS.MacOS;
|
||||
else
|
||||
throw new Exception("Unable to determine OS.");
|
||||
|
||||
Logger = new SDLLogger();
|
||||
}
|
||||
|
||||
public PlatformOS OperatingSystem { get; private set; }
|
||||
public PlatformType Type
|
||||
{
|
||||
get { return PlatformType.Desktop; }
|
||||
}
|
||||
|
||||
public IPlatformLogger Logger { get; internal set; }
|
||||
public IFileSystem FileSystem { get; internal set; }
|
||||
public IKeyboard Keyboard { get; internal set; }
|
||||
public IMouse Mouse { get; internal set; }
|
||||
public ITouchScreen TouchScreen { get; internal set; }
|
||||
public GL20 GL { get; internal set; }
|
||||
}
|
||||
}
|
||||
|
16
Blarg.GameFramework.SDL2/SDLWindow.cs
Normal file
16
Blarg.GameFramework.SDL2/SDLWindow.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
|
||||
namespace Blarg.GameFramework
|
||||
{
|
||||
public class SDLWindow : IPlatformWindow
|
||||
{
|
||||
public Rect ClientRectangle { get; internal set; }
|
||||
public int ClientWidth { get; internal set; }
|
||||
public int ClientHeight { get; internal set; }
|
||||
public int X { get; internal set; }
|
||||
public int Y { get; internal set; }
|
||||
public int Width { get; internal set; }
|
||||
public int Height { get; internal set; }
|
||||
}
|
||||
}
|
||||
|
91
Blarg.GameFramework/BaseLooper.cs
Normal file
91
Blarg.GameFramework/BaseLooper.cs
Normal file
|
@ -0,0 +1,91 @@
|
|||
using System;
|
||||
using Blarg.GameFramework.Graphics;
|
||||
|
||||
namespace Blarg.GameFramework
|
||||
{
|
||||
public abstract class BaseLooper : ILooper
|
||||
{
|
||||
IGameApp _gameApp;
|
||||
|
||||
public IGameApp GameApp
|
||||
{
|
||||
get
|
||||
{
|
||||
return _gameApp;
|
||||
}
|
||||
protected set
|
||||
{
|
||||
_gameApp = value;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract int FPS { get; }
|
||||
public abstract float FrameTime { get; }
|
||||
public abstract int RendersPerSecond { get; }
|
||||
public abstract int UpdatesPerSecond { get; }
|
||||
public abstract int RenderTime { get; }
|
||||
public abstract int UpdateTime { get; }
|
||||
|
||||
public abstract void Run(IGameApp gameApp, IPlatformConfiguration config);
|
||||
|
||||
protected void OnAppGainFocus()
|
||||
{
|
||||
GameApp.OnAppGainFocus();
|
||||
}
|
||||
|
||||
protected void OnAppLostFocus()
|
||||
{
|
||||
GameApp.OnAppLostFocus();
|
||||
}
|
||||
|
||||
protected void OnAppPause()
|
||||
{
|
||||
GameApp.OnAppPause();
|
||||
}
|
||||
|
||||
protected void OnAppResume()
|
||||
{
|
||||
GameApp.OnAppResume();
|
||||
}
|
||||
|
||||
protected void OnLoad()
|
||||
{
|
||||
GameApp.OnLoad();
|
||||
}
|
||||
|
||||
protected void OnUnload()
|
||||
{
|
||||
GameApp.OnUnload();
|
||||
}
|
||||
|
||||
protected void OnLostContext()
|
||||
{
|
||||
GameApp.OnLostContext();
|
||||
}
|
||||
|
||||
protected void OnNewContext()
|
||||
{
|
||||
GameApp.OnNewContext();
|
||||
}
|
||||
|
||||
protected void OnRender(float delta)
|
||||
{
|
||||
GameApp.OnRender(delta);
|
||||
}
|
||||
|
||||
protected void OnResize(ScreenOrientation orientation, Rect size)
|
||||
{
|
||||
GameApp.OnResize(orientation, size);
|
||||
}
|
||||
|
||||
protected void OnUpdate(float delta)
|
||||
{
|
||||
GameApp.OnUpdate(delta);
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -82,6 +82,9 @@
|
|||
<Compile Include="Graphics\Image.cs" />
|
||||
<Compile Include="Graphics\ScreenOrientation.cs" />
|
||||
<Compile Include="IGameApp.cs" />
|
||||
<Compile Include="BaseLooper.cs" />
|
||||
<Compile Include="IPlatformWindow.cs" />
|
||||
<Compile Include="IPlatformConfiguration.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
|
|
@ -3,13 +3,12 @@ using Blarg.GameFramework.Graphics;
|
|||
|
||||
namespace Blarg.GameFramework
|
||||
{
|
||||
public interface IGameApp
|
||||
public interface IGameApp : IDisposable
|
||||
{
|
||||
void OnAppGainFocus();
|
||||
void OnAppLostFocus();
|
||||
void OnAppPause();
|
||||
void OnAppResume();
|
||||
bool OnInit();
|
||||
void OnLoad();
|
||||
void OnUnload();
|
||||
void OnLostContext();
|
||||
|
|
|
@ -4,7 +4,14 @@ namespace Blarg.GameFramework
|
|||
{
|
||||
public interface ILooper : IDisposable
|
||||
{
|
||||
void Run(IGameApp gameApp);
|
||||
int FPS { get; }
|
||||
float FrameTime { get; }
|
||||
int RendersPerSecond { get; }
|
||||
int UpdatesPerSecond { get; }
|
||||
int RenderTime { get; }
|
||||
int UpdateTime { get; }
|
||||
|
||||
void Run(IGameApp gameApp, IPlatformConfiguration config);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
9
Blarg.GameFramework/IPlatformConfiguration.cs
Normal file
9
Blarg.GameFramework/IPlatformConfiguration.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace Blarg.GameFramework
|
||||
{
|
||||
public interface IPlatformConfiguration
|
||||
{
|
||||
}
|
||||
}
|
||||
|
16
Blarg.GameFramework/IPlatformWindow.cs
Normal file
16
Blarg.GameFramework/IPlatformWindow.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
|
||||
namespace Blarg.GameFramework
|
||||
{
|
||||
public interface IPlatformWindow
|
||||
{
|
||||
Rect ClientRectangle { get; }
|
||||
int ClientWidth { get; }
|
||||
int ClientHeight { get; }
|
||||
int X { get; }
|
||||
int Y { get; }
|
||||
int Width { get; }
|
||||
int Height { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -17,9 +17,21 @@ namespace Blarg.GameFramework
|
|||
Desktop
|
||||
}
|
||||
|
||||
public static partial class Platform
|
||||
public static class Platform
|
||||
{
|
||||
public static IPlatformServices Services { get; private set; }
|
||||
static IPlatformServices _services;
|
||||
|
||||
public static IPlatformServices Services
|
||||
{
|
||||
get { return _services; }
|
||||
set
|
||||
{
|
||||
if (_services != null)
|
||||
throw new InvalidOperationException();
|
||||
else
|
||||
_services = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,9 +35,13 @@
|
|||
<Reference Include="System" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="PortableGL">
|
||||
<HintPath>..\Libs\PortableGL.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="GameApp.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
|
65
Game.Core/GameApp.cs
Normal file
65
Game.Core/GameApp.cs
Normal file
|
@ -0,0 +1,65 @@
|
|||
using System;
|
||||
using PortableGL;
|
||||
using Blarg.GameFramework;
|
||||
using Blarg.GameFramework.Graphics;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
public class GameApp : IGameApp
|
||||
{
|
||||
public GameApp()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnAppGainFocus()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnAppLostFocus()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnAppPause()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnAppResume()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnLoad()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnUnload()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnLostContext()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnNewContext()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRender(float delta)
|
||||
{
|
||||
Platform.Services.GL.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
|
||||
Platform.Services.GL.glClearColor(0.25f, 0.5f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
public void OnResize(ScreenOrientation orientation, Rect size)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnUpdate(float delta)
|
||||
{
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
<ProductVersion>10.0.0</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{4C73802F-6EB0-490C-BB32-64718B0FEEBA}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>Game</RootNamespace>
|
||||
<AssemblyName>Game.SDL2</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
@ -18,7 +18,7 @@
|
|||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Externalconsole>true</Externalconsole>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
using System;
|
||||
using Blarg.GameFramework;
|
||||
|
||||
namespace Game.SDL2
|
||||
{
|
||||
class MainClass
|
||||
public static class MainClass
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Hello World!");
|
||||
var game = new GameApp();
|
||||
var config = new SDLConfiguration();
|
||||
config.Title = "Test Game";
|
||||
|
||||
var looper = new SDLLooper();
|
||||
looper.Run(game, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue