#region License /* FNA - XNA4 Reimplementation for Desktop Platforms * Copyright 2009-2015 Ethan Lee and the MonoGame Team * * Released under the Microsoft Public License. * See LICENSE for details. */ #endregion #region Using Statements using System; using System.IO; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; #endregion namespace Microsoft.Xna.Framework { abstract class GamePlatform : IDisposable { #region Public Properties /// /// Gets the Game instance that owns this GamePlatform instance. /// public Game Game { get; private set; } public bool IsActive { get { return _isActive; } internal set { if (_isActive != value) { _isActive = value; Raise(_isActive ? Activated : Deactivated, EventArgs.Empty); } } } public bool IsMouseVisible { get { return _isMouseVisible; } set { if (_isMouseVisible != value) { _isMouseVisible = value; OnIsMouseVisibleChanged(); } } } public GameWindow Window { get { return _window; } protected set { if (_window == null) { Mouse.WindowHandle = value.Handle; } _window = value; } } #endregion #region Internal Properties internal string OSVersion { get; private set; } #endregion #region Protected Properties protected bool IsDisposed { get { return disposed; } } #endregion #region Protected Variables protected TimeSpan _inactiveSleepTime = TimeSpan.FromMilliseconds(20.0); protected bool _needsToResetElapsedTime = false; #endregion #region Private Variables bool disposed; private bool _isActive; private bool _isMouseVisible; private GameWindow _window; #endregion #region Protected Constructor protected GamePlatform(Game game, string osVersion) { if (game == null) { throw new ArgumentNullException("game"); } Game = game; OSVersion = osVersion; } #endregion #region Deconstructor ~GamePlatform() { Dispose(false); } #endregion #region Events public event EventHandler Activated; public event EventHandler Deactivated; #endregion #region Public Methods /// /// Gives derived classes an opportunity to do work before any /// components are initialized. Note that the base implementation sets /// IsActive to true, so derived classes should either call the base /// implementation or set IsActive to true by their own means. /// public virtual void BeforeInitialize() { IsActive = true; if (this.Game.GraphicsDevice == null) { IGraphicsDeviceManager graphicsDeviceManager = Game.Services.GetService( typeof(IGraphicsDeviceManager) ) as IGraphicsDeviceManager; graphicsDeviceManager.CreateDevice(); } } /// /// Gives derived classes an opportunity to do work just before the /// run loop is begun. Implementations may also return false to prevent /// the run loop from starting. /// /// public virtual bool BeforeRun() { return true; } /// /// When implemented in a derived class, ends the active run loop. /// public abstract void Exit(); /// /// When implemented in a derived class, starts the run loop and blocks /// until it has ended. /// public abstract void RunLoop(); /// /// Gives derived classes an opportunity to do work just before Update /// is called for all IUpdatable components. Returning false from this /// method will result in this round of Update calls being skipped. /// /// /// public abstract bool BeforeUpdate(GameTime gameTime); /// /// Gives derived classes an opportunity to do work just before Draw /// is called for all IDrawable components. Returning false from this /// method will result in this round of Draw calls being skipped. /// /// /// public abstract bool BeforeDraw(GameTime gameTime); /// /// Gives derived classes an opportunity to modify /// Game.TargetElapsedTime before it is set. /// /// The proposed new value of TargetElapsedTime. /// The new value of TargetElapsedTime that will be set. public virtual TimeSpan TargetElapsedTimeChanging(TimeSpan value) { return value; } /// /// Starts a device transition (windowed to full screen or vice versa). /// /// /// Specifies whether the device will be in full-screen mode upon completion of /// the change. /// public abstract void BeginScreenDeviceChange( bool willBeFullScreen ); /// /// Completes a device transition. /// /// /// Screen device name. /// /// /// The new width of the game's client window. /// /// /// The new height of the game's client window. /// public abstract void EndScreenDeviceChange( string screenDeviceName, int clientWidth, int clientHeight ); /// /// Gives derived classes an opportunity to take action after /// Game.TargetElapsedTime has been set. /// public virtual void TargetElapsedTimeChanged() {} /// /// MSDN: Use this method if your game is recovering from a slow-running state, and /// ElapsedGameTime is too large to be useful. Frame timing is generally handled /// by the Game class, but some platforms still handle it elsewhere. Once all /// platforms rely on the Game class's functionality, this method and any overrides /// should be removed. /// public virtual void ResetElapsedTime() {} protected virtual void OnIsMouseVisibleChanged() {} public virtual void Present() {} public abstract void ShowRuntimeError( String title, String message ); #endregion #region Internal Methods internal abstract DisplayMode GetCurrentDisplayMode(); internal abstract DisplayModeCollection GetDisplayModes(); internal abstract void SetPresentationInterval(PresentInterval interval); internal abstract bool HasTouch(); internal abstract void TextureDataFromStream( Stream stream, out int width, out int height, out byte[] pixels, int reqWidth = -1, int reqHeight = -1, bool zoom = false ); internal abstract void SavePNG( Stream stream, int width, int height, int imgWidth, int imgHeight, byte[] data ); internal abstract Keys GetKeyFromScancode(Keys scancode); #endregion #region Private Methods private void Raise(EventHandler handler, TEventArgs e) where TEventArgs : EventArgs { if (handler != null) { handler(this, e); } } #endregion #region Public Static Methods public static GamePlatform Create(Game game) { /* I suspect you may have an urge to put an #if in here for new * GamePlatform implementations. * * DON'T. * * Determine this at runtime, or load dynamically. * No amount of whining will get me to budge on this. * -flibit */ return new SDL2_GamePlatform(game); } #endregion #region IDisposable implementation /// /// Performs application-defined tasks associated with freeing, /// releasing, or resetting unmanaged resources. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!disposed) { Mouse.WindowHandle = IntPtr.Zero; disposed = true; } } /// /// Log the specified Message. /// /// /// /// [System.Diagnostics.Conditional("DEBUG")] public virtual void Log(string Message) {} #endregion } }