diff --git a/MonoGame.Framework/Android/AndroidGameWindow.cs b/MonoGame.Framework/Android/AndroidGameWindow.cs
index adb82f1719b..55ab4ff5dae 100644
--- a/MonoGame.Framework/Android/AndroidGameWindow.cs
+++ b/MonoGame.Framework/Android/AndroidGameWindow.cs
@@ -1,490 +1,490 @@
-#region License
-/*
-Microsoft Public License (Ms-PL)
-MonoGame - Copyright © 2009 The MonoGame Team
-
-All rights reserved.
-
-This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
-accept the license, do not use the software.
-
-1. Definitions
-The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
-U.S. copyright law.
-
-A "contribution" is the original software, or any additions or changes to the software.
-A "contributor" is any person that distributes its contribution under this license.
-"Licensed patents" are a contributor's patent claims that read directly on its contribution.
-
-2. Grant of Rights
-(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
-each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
-(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
-each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
-
-3. Conditions and Limitations
-(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
-(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
-your patent license from such contributor to the software ends automatically.
-(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
-notices that are present in the software.
-(D) If you distribute any portion of the software in source code form, you may do so only under this license by including
-a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
-code form, you may only do so under a license that complies with this license.
-(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
-or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
-permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
-purpose and non-infringement.
-*/
-#endregion License
-
-#region Using Statements
-using System;
-using System.Drawing;
-using System.Collections.Generic;
-using System.ComponentModel;
-using Android.Content;
-using Android.Content.PM;
-using Android.Content.Res;
-using Android.Util;
-using Android.Views;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Graphics;
-using OpenTK.Platform.Android;
-
-using OpenTK;
-using OpenTK.Platform;
-using OpenTK.Graphics;
-using OpenTK.Graphics.ES20;
-
-using Microsoft.Xna.Framework.Input;
-using Microsoft.Xna.Framework.Input.Touch;
-#endregion Using Statements
-
-namespace Microsoft.Xna.Framework
-{
- public class AndroidGameWindow : AndroidGameView , Android.Views.View.IOnTouchListener, ISurfaceHolderCallback
- {
- private Rectangle clientBounds;
- private Game _game;
- private DisplayOrientation supportedOrientations = DisplayOrientation.Default;
- private DisplayOrientation _currentOrientation;
- private AndroidTouchEventManager _touchManager = null;
- private bool _contextWasLost = false;
-
- public bool TouchEnabled
- {
- get { return _touchManager.Enabled; }
- set { _touchManager.Enabled = value; }
- }
-
- public AndroidGameWindow(Context context, Game game) : base(context)
- {
- _game = game;
- Initialize();
- }
-
- private void Initialize()
- {
- clientBounds = new Rectangle(0, 0, Context.Resources.DisplayMetrics.WidthPixels, Context.Resources.DisplayMetrics.HeightPixels);
-
- this.RequestFocus();
- this.FocusableInTouchMode = true;
-
- _touchManager = new AndroidTouchEventManager(_game);
-
-#if OUYA
- GamePad.Initialize();
-#endif
- }
-
- protected override void OnLoad (EventArgs e)
- {
- base.OnLoad (e);
- MakeCurrent();
- }
-
- public override bool OnKeyDown(Keycode keyCode, KeyEvent e)
- {
-#if OUYA
- if (GamePad.OnKeyDown(keyCode, e))
- return true;
-#endif
-
- Keyboard.KeyDown(keyCode);
- // we need to handle the Back key here because it doesnt work any other way
-#if !OUYA
- if (keyCode == Keycode.Back)
- GamePad.Instance.SetBack();
-#endif
-
- if (keyCode == Keycode.VolumeUp)
- Sound.IncreaseMediaVolume();
-
- if (keyCode == Keycode.VolumeDown)
- Sound.DecreaseMediaVolume();
-
- return true;
- }
-
- public override bool OnKeyUp(Keycode keyCode, KeyEvent e)
- {
-#if OUYA
- if (GamePad.OnKeyUp(keyCode, e))
- return true;
-#endif
- Keyboard.KeyUp(keyCode);
- return true;
- }
-
-#if OUYA
- public override bool OnGenericMotionEvent(MotionEvent e)
- {
- if (GamePad.OnGenericMotionEvent(e))
- return true;
-
- return base.OnGenericMotionEvent(e);
- }
-#endif
-
- protected override void CreateFrameBuffer()
- {
- Android.Util.Log.Debug("MonoGame", "AndroidGameWindow.CreateFrameBuffer");
- try
- {
- GLContextVersion = GLContextVersion.Gles2_0;
- try
- {
- base.CreateFrameBuffer();
- }
- catch(Exception)
- {
- // try again using a more basic mode which hopefully the device will support
- GraphicsMode = new AndroidGraphicsMode(0, 0, 0, 0, 0, false);
- base.CreateFrameBuffer();
- }
- All status = GL.CheckFramebufferStatus(All.Framebuffer);
- Android.Util.Log.Debug("MonoGame", "Framebuffer Status: " + status.ToString());
- }
- catch (Exception)
- {
- throw new NotSupportedException("Could not create OpenGLES 2.0 frame buffer");
- }
- if (_game.GraphicsDevice != null && _contextWasLost)
- {
- _game.GraphicsDevice.Initialize();
- Android.Util.Log.Debug("MonoGame", "Begin reloading graphics content");
- Microsoft.Xna.Framework.Content.ContentManager.ReloadGraphicsContent();
- Android.Util.Log.Debug("MonoGame", "End reloading graphics content");
-
- // DeviceReset events
- _game.graphicsDeviceManager.OnDeviceReset(EventArgs.Empty);
- _game.GraphicsDevice.OnDeviceReset();
-
- _contextWasLost = false;
- }
-
- MakeCurrent();
- }
-
- protected override void DestroyFrameBuffer()
- {
- // DeviceResetting events
- _game.graphicsDeviceManager.OnDeviceResetting(EventArgs.Empty);
- _game.GraphicsDevice.OnDeviceResetting();
-
- Android.Util.Log.Debug("MonoGame", "AndroidGameWindow.DestroyFrameBuffer");
-
- base.DestroyFrameBuffer();
-
- _contextWasLost = GraphicsContext == null || GraphicsContext.IsDisposed;
- }
-
- #region AndroidGameView Methods
-
- protected override void OnRenderFrame(FrameEventArgs e)
- {
- base.OnRenderFrame(e);
-
- if (GraphicsContext == null || GraphicsContext.IsDisposed)
- return;
-
- if (!GraphicsContext.IsCurrent)
- MakeCurrent();
-
- Threading.Run();
- }
-
- protected override void OnUpdateFrame(FrameEventArgs e)
- {
- base.OnUpdateFrame(e);
-
- if (_contextWasLost)
- return;
-
- if (!GraphicsContext.IsCurrent)
- MakeCurrent();
-
- Threading.Run();
-
- if (_game != null)
- {
- if ( _game.Platform.IsActive && !ScreenReceiver.ScreenLocked) //Only call draw if an update has occured
- {
- _game.Tick();
- }
- else if (_game.GraphicsDevice != null)
- {
- _game.GraphicsDevice.Clear(Color.Black);
- _game.Platform.Present();
- }
- }
- }
-
- #endregion
-
-
- internal void SetSupportedOrientations(DisplayOrientation orientations)
- {
- supportedOrientations = orientations;
- }
-
- ///
- /// In Xna, setting SupportedOrientations = DisplayOrientation.Default (which is the default value)
- /// has the effect of setting SupportedOrientations to landscape only or portrait only, based on the
- /// aspect ratio of PreferredBackBufferWidth / PreferredBackBufferHeight
- ///
- ///
- internal DisplayOrientation GetEffectiveSupportedOrientations()
- {
- if (supportedOrientations == DisplayOrientation.Default)
- {
- var deviceManager = (_game.Services.GetService(typeof(IGraphicsDeviceManager)) as GraphicsDeviceManager);
- if (deviceManager == null)
- return DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;
-
- if (deviceManager.PreferredBackBufferWidth > deviceManager.PreferredBackBufferHeight)
- {
- return DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;
- }
- else
- {
- return DisplayOrientation.Portrait | DisplayOrientation.PortraitUpsideDown;
- }
- }
- else
- {
- return supportedOrientations;
- }
- }
-
- ///
- /// Updates the screen orientation. Filters out requests for unsupported orientations.
- ///
- internal void SetOrientation(DisplayOrientation newOrientation, bool applyGraphicsChanges)
- {
- DisplayOrientation supported = GetEffectiveSupportedOrientations();
-
- // If the new orientation is not supported, force a supported orientation
- if ((supported & newOrientation) == 0)
- {
- if ((supported & DisplayOrientation.LandscapeLeft) != 0)
- newOrientation = DisplayOrientation.LandscapeLeft;
- else if ((supported & DisplayOrientation.LandscapeRight) != 0)
- newOrientation = DisplayOrientation.LandscapeRight;
- else if ((supported & DisplayOrientation.Portrait) != 0)
- newOrientation = DisplayOrientation.Portrait;
- else if ((supported & DisplayOrientation.PortraitUpsideDown) != 0)
- newOrientation = DisplayOrientation.PortraitUpsideDown;
- }
-
- DisplayOrientation oldOrientation = CurrentOrientation;
-
- CurrentOrientation = newOrientation;
- TouchPanel.DisplayOrientation = newOrientation;
-
- if (applyGraphicsChanges && oldOrientation != CurrentOrientation && _game.graphicsDeviceManager != null)
- _game.graphicsDeviceManager.ApplyChanges();
- }
-
- #region IOnTouchListener implementation
- public bool OnTouch (View v, MotionEvent e)
- {
- return OnTouchEvent(e);
- }
- #endregion
-
- public override bool OnTouchEvent(MotionEvent e)
- {
- _touchManager.OnTouchEvent(e);
- return true;
- }
-
- public string ScreenDeviceName
- {
- get
- {
- throw new System.NotImplementedException ();
- }
- }
-
-
- public Rectangle ClientBounds
- {
- get
- {
- return clientBounds;
- }
- internal set
- {
- clientBounds = value;
- //if(ClientSizeChanged != null)
- // ClientSizeChanged(this, EventArgs.Empty);
- }
- }
-
- public bool AllowUserResizing
- {
- get
- {
- return false;
- }
- set
- {
- // Do nothing; Ignore rather than raising and exception
- }
- }
-
- // A copy of ScreenOrientation from Android 2.3
- // This allows us to continue to support 2.2 whilst
- // utilising the 2.3 improved orientation support.
- enum ScreenOrientationAll
- {
- Unspecified = -1,
- Landscape = 0,
- Portrait = 1,
- User = 2,
- Behind = 3,
- Sensor = 4,
- Nosensor = 5,
- SensorLandscape = 6,
- SensorPortrait = 7,
- ReverseLandscape = 8,
- ReversePortrait = 9,
- FullSensor = 10,
- }
-
- public DisplayOrientation CurrentOrientation
- {
- get
- {
- return _currentOrientation;
- }
- private set
- {
- if (value != _currentOrientation)
- {
- DisplayOrientation supported = GetEffectiveSupportedOrientations();
- ScreenOrientation requestedOrientation = ScreenOrientation.Unspecified;
- bool wasPortrait = _currentOrientation == DisplayOrientation.Portrait || _currentOrientation == DisplayOrientation.PortraitUpsideDown;
- bool requestPortrait = false;
-
- bool didOrientationChange = false;
- // Android 2.3 and above support reverse orientations
- int sdkVer = (int)Android.OS.Build.VERSION.SdkInt;
- if (sdkVer >= 10)
- {
- // Check if the requested orientation is supported. Default means all are supported.
- if ((supported & value) != 0)
- {
- didOrientationChange = true;
- _currentOrientation = value;
- switch (value)
- {
- case DisplayOrientation.LandscapeLeft:
- requestedOrientation = (ScreenOrientation)ScreenOrientationAll.Landscape;
- requestPortrait = false;
- break;
- case DisplayOrientation.LandscapeRight:
- requestedOrientation = (ScreenOrientation)ScreenOrientationAll.ReverseLandscape;
- requestPortrait = false;
- break;
- case DisplayOrientation.Portrait:
- requestedOrientation = (ScreenOrientation)ScreenOrientationAll.Portrait;
- requestPortrait = true;
- break;
- case DisplayOrientation.PortraitUpsideDown:
- requestedOrientation = (ScreenOrientation)ScreenOrientationAll.ReversePortrait;
- requestPortrait = true;
- break;
- }
- }
- }
- else
- {
- // Check if the requested orientation is either of the landscape orientations and any landscape orientation is supported.
- if ((value == DisplayOrientation.LandscapeLeft || value == DisplayOrientation.LandscapeRight) &&
- ((supported & (DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight)) != 0))
- {
- didOrientationChange = true;
- _currentOrientation = DisplayOrientation.LandscapeLeft;
- requestedOrientation = ScreenOrientation.Landscape;
- requestPortrait = false;
- }
- // Check if the requested orientation is either of the portrain orientations and any portrait orientation is supported.
- else if ((value == DisplayOrientation.Portrait || value == DisplayOrientation.PortraitUpsideDown) &&
- ((supported & (DisplayOrientation.Portrait | DisplayOrientation.PortraitUpsideDown)) != 0))
- {
- didOrientationChange = true;
- _currentOrientation = DisplayOrientation.Portrait;
- requestedOrientation = ScreenOrientation.Portrait;
- requestPortrait = true;
- }
- }
-
- if (didOrientationChange)
- {
- // Android doesn't fire Released events for existing touches
- // so we need to clear them out.
- if (wasPortrait != requestPortrait)
- {
- TouchPanel.ReleaseAllTouches();
- }
-
- Game.Activity.RequestedOrientation = requestedOrientation;
-
- if (OrientationChanged != null)
- OrientationChanged(this, EventArgs.Empty);
- }
- }
- }
- }
-
- public event EventHandler OrientationChanged;
- public event EventHandler ClientSizeChanged;
- public event EventHandler ScreenDeviceNameChanged;
-
-
- void ISurfaceHolderCallback.SurfaceChanged(ISurfaceHolder holder, Android.Graphics.Format format, int width, int height)
- {
- base.SurfaceChanged(holder, format, width, height);
- Android.Util.Log.Debug("MonoGame", "AndroidGameWindow.SurfaceChanged: format = " + format + ", width = " + width + ", height = " + height);
-
- if (_game.GraphicsDevice != null)
- _game.graphicsDeviceManager.ResetClientBounds();
- }
-
- void ISurfaceHolderCallback.SurfaceDestroyed(ISurfaceHolder holder)
- {
- base.SurfaceDestroyed(holder);
- Android.Util.Log.Debug("MonoGame", "AndroidGameWindow.SurfaceDestroyed");
- }
-
- void ISurfaceHolderCallback.SurfaceCreated(ISurfaceHolder holder)
- {
- base.SurfaceCreated(holder);
- Android.Util.Log.Debug("MonoGame", "AndroidGameWindow.SurfaceCreated: surfaceFrame = " + holder.SurfaceFrame.ToString());
- }
- }
-}
-
+#region License
+/*
+Microsoft Public License (Ms-PL)
+MonoGame - Copyright © 2009 The MonoGame Team
+
+All rights reserved.
+
+This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
+accept the license, do not use the software.
+
+1. Definitions
+The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
+U.S. copyright law.
+
+A "contribution" is the original software, or any additions or changes to the software.
+A "contributor" is any person that distributes its contribution under this license.
+"Licensed patents" are a contributor's patent claims that read directly on its contribution.
+
+2. Grant of Rights
+(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
+each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
+(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
+each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
+
+3. Conditions and Limitations
+(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
+(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
+your patent license from such contributor to the software ends automatically.
+(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
+notices that are present in the software.
+(D) If you distribute any portion of the software in source code form, you may do so only under this license by including
+a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
+code form, you may only do so under a license that complies with this license.
+(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
+or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
+permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
+purpose and non-infringement.
+*/
+#endregion License
+
+#region Using Statements
+using System;
+using System.Drawing;
+using System.Collections.Generic;
+using System.ComponentModel;
+using Android.Content;
+using Android.Content.PM;
+using Android.Content.Res;
+using Android.Util;
+using Android.Views;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Graphics;
+using OpenTK.Platform.Android;
+
+using OpenTK;
+using OpenTK.Platform;
+using OpenTK.Graphics;
+using OpenTK.Graphics.ES20;
+
+using Microsoft.Xna.Framework.Input;
+using Microsoft.Xna.Framework.Input.Touch;
+#endregion Using Statements
+
+namespace Microsoft.Xna.Framework
+{
+ public class AndroidGameWindow : AndroidGameView , Android.Views.View.IOnTouchListener, ISurfaceHolderCallback
+ {
+ private Rectangle clientBounds;
+ private Game _game;
+ private DisplayOrientation supportedOrientations = DisplayOrientation.Default;
+ private DisplayOrientation _currentOrientation;
+ private AndroidTouchEventManager _touchManager = null;
+ private bool _contextWasLost = false;
+
+ public bool TouchEnabled
+ {
+ get { return _touchManager.Enabled; }
+ set { _touchManager.Enabled = value; }
+ }
+
+ public AndroidGameWindow(Context context, Game game) : base(context)
+ {
+ _game = game;
+ Initialize();
+ }
+
+ private void Initialize()
+ {
+ clientBounds = new Rectangle(0, 0, Context.Resources.DisplayMetrics.WidthPixels, Context.Resources.DisplayMetrics.HeightPixels);
+
+ this.RequestFocus();
+ this.FocusableInTouchMode = true;
+
+ _touchManager = new AndroidTouchEventManager(_game);
+
+#if OUYA
+ GamePad.Initialize();
+#endif
+ }
+
+ protected override void OnLoad (EventArgs e)
+ {
+ base.OnLoad (e);
+ MakeCurrent();
+ }
+
+ public override bool OnKeyDown(Keycode keyCode, KeyEvent e)
+ {
+#if OUYA
+ if (GamePad.OnKeyDown(keyCode, e))
+ return true;
+#endif
+
+ Keyboard.KeyDown(keyCode);
+ // we need to handle the Back key here because it doesnt work any other way
+#if !OUYA
+ if (keyCode == Keycode.Back)
+ GamePad.Instance.SetBack();
+#endif
+
+ if (keyCode == Keycode.VolumeUp)
+ Sound.IncreaseMediaVolume();
+
+ if (keyCode == Keycode.VolumeDown)
+ Sound.DecreaseMediaVolume();
+
+ return true;
+ }
+
+ public override bool OnKeyUp(Keycode keyCode, KeyEvent e)
+ {
+#if OUYA
+ if (GamePad.OnKeyUp(keyCode, e))
+ return true;
+#endif
+ Keyboard.KeyUp(keyCode);
+ return true;
+ }
+
+#if OUYA
+ public override bool OnGenericMotionEvent(MotionEvent e)
+ {
+ if (GamePad.OnGenericMotionEvent(e))
+ return true;
+
+ return base.OnGenericMotionEvent(e);
+ }
+#endif
+
+ protected override void CreateFrameBuffer()
+ {
+ Android.Util.Log.Debug("MonoGame", "AndroidGameWindow.CreateFrameBuffer");
+ try
+ {
+ GLContextVersion = GLContextVersion.Gles2_0;
+ try
+ {
+ base.CreateFrameBuffer();
+ }
+ catch(Exception)
+ {
+ // try again using a more basic mode which hopefully the device will support
+ GraphicsMode = new AndroidGraphicsMode(0, 0, 0, 0, 0, false);
+ base.CreateFrameBuffer();
+ }
+ All status = GL.CheckFramebufferStatus(All.Framebuffer);
+ Android.Util.Log.Debug("MonoGame", "Framebuffer Status: " + status.ToString());
+ }
+ catch (Exception)
+ {
+ throw new NotSupportedException("Could not create OpenGLES 2.0 frame buffer");
+ }
+ if (_game.GraphicsDevice != null && _contextWasLost)
+ {
+ _game.GraphicsDevice.Initialize();
+ Android.Util.Log.Debug("MonoGame", "Begin reloading graphics content");
+ Microsoft.Xna.Framework.Content.ContentManager.ReloadGraphicsContent();
+ Android.Util.Log.Debug("MonoGame", "End reloading graphics content");
+
+ // DeviceReset events
+ _game.graphicsDeviceManager.OnDeviceReset(EventArgs.Empty);
+ _game.GraphicsDevice.OnDeviceReset();
+
+ _contextWasLost = false;
+ }
+
+ MakeCurrent();
+ }
+
+ protected override void DestroyFrameBuffer()
+ {
+ // DeviceResetting events
+ _game.graphicsDeviceManager.OnDeviceResetting(EventArgs.Empty);
+ _game.GraphicsDevice.OnDeviceResetting();
+
+ Android.Util.Log.Debug("MonoGame", "AndroidGameWindow.DestroyFrameBuffer");
+
+ base.DestroyFrameBuffer();
+
+ _contextWasLost = GraphicsContext == null || GraphicsContext.IsDisposed;
+ }
+
+ #region AndroidGameView Methods
+
+ protected override void OnRenderFrame(FrameEventArgs e)
+ {
+ base.OnRenderFrame(e);
+
+ if (GraphicsContext == null || GraphicsContext.IsDisposed)
+ return;
+
+ if (!GraphicsContext.IsCurrent)
+ MakeCurrent();
+
+ Threading.Run();
+ }
+
+ protected override void OnUpdateFrame(FrameEventArgs e)
+ {
+ base.OnUpdateFrame(e);
+
+ if (_contextWasLost)
+ return;
+
+ if (!GraphicsContext.IsCurrent)
+ MakeCurrent();
+
+ Threading.Run();
+
+ if (_game != null)
+ {
+ if ( _game.Platform.IsActive && !ScreenReceiver.ScreenLocked) //Only call draw if an update has occured
+ {
+ _game.Tick();
+ }
+ else if (_game.GraphicsDevice != null)
+ {
+ _game.GraphicsDevice.Clear(Color.Black);
+ _game.Platform.Present();
+ }
+ }
+ }
+
+ #endregion
+
+
+ internal void SetSupportedOrientations(DisplayOrientation orientations)
+ {
+ supportedOrientations = orientations;
+ }
+
+ ///
+ /// In Xna, setting SupportedOrientations = DisplayOrientation.Default (which is the default value)
+ /// has the effect of setting SupportedOrientations to landscape only or portrait only, based on the
+ /// aspect ratio of PreferredBackBufferWidth / PreferredBackBufferHeight
+ ///
+ ///
+ internal DisplayOrientation GetEffectiveSupportedOrientations()
+ {
+ if (supportedOrientations == DisplayOrientation.Default)
+ {
+ var deviceManager = (_game.Services.GetService(typeof(IGraphicsDeviceManager)) as GraphicsDeviceManager);
+ if (deviceManager == null)
+ return DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;
+
+ if (deviceManager.PreferredBackBufferWidth > deviceManager.PreferredBackBufferHeight)
+ {
+ return DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;
+ }
+ else
+ {
+ return DisplayOrientation.Portrait | DisplayOrientation.PortraitDown;
+ }
+ }
+ else
+ {
+ return supportedOrientations;
+ }
+ }
+
+ ///
+ /// Updates the screen orientation. Filters out requests for unsupported orientations.
+ ///
+ internal void SetOrientation(DisplayOrientation newOrientation, bool applyGraphicsChanges)
+ {
+ DisplayOrientation supported = GetEffectiveSupportedOrientations();
+
+ // If the new orientation is not supported, force a supported orientation
+ if ((supported & newOrientation) == 0)
+ {
+ if ((supported & DisplayOrientation.LandscapeLeft) != 0)
+ newOrientation = DisplayOrientation.LandscapeLeft;
+ else if ((supported & DisplayOrientation.LandscapeRight) != 0)
+ newOrientation = DisplayOrientation.LandscapeRight;
+ else if ((supported & DisplayOrientation.Portrait) != 0)
+ newOrientation = DisplayOrientation.Portrait;
+ else if ((supported & DisplayOrientation.PortraitDown) != 0)
+ newOrientation = DisplayOrientation.PortraitDown;
+ }
+
+ DisplayOrientation oldOrientation = CurrentOrientation;
+
+ CurrentOrientation = newOrientation;
+ TouchPanel.DisplayOrientation = newOrientation;
+
+ if (applyGraphicsChanges && oldOrientation != CurrentOrientation && _game.graphicsDeviceManager != null)
+ _game.graphicsDeviceManager.ApplyChanges();
+ }
+
+ #region IOnTouchListener implementation
+ public bool OnTouch (View v, MotionEvent e)
+ {
+ return OnTouchEvent(e);
+ }
+ #endregion
+
+ public override bool OnTouchEvent(MotionEvent e)
+ {
+ _touchManager.OnTouchEvent(e);
+ return true;
+ }
+
+ public string ScreenDeviceName
+ {
+ get
+ {
+ throw new System.NotImplementedException ();
+ }
+ }
+
+
+ public Rectangle ClientBounds
+ {
+ get
+ {
+ return clientBounds;
+ }
+ internal set
+ {
+ clientBounds = value;
+ //if(ClientSizeChanged != null)
+ // ClientSizeChanged(this, EventArgs.Empty);
+ }
+ }
+
+ public bool AllowUserResizing
+ {
+ get
+ {
+ return false;
+ }
+ set
+ {
+ // Do nothing; Ignore rather than raising and exception
+ }
+ }
+
+ // A copy of ScreenOrientation from Android 2.3
+ // This allows us to continue to support 2.2 whilst
+ // utilising the 2.3 improved orientation support.
+ enum ScreenOrientationAll
+ {
+ Unspecified = -1,
+ Landscape = 0,
+ Portrait = 1,
+ User = 2,
+ Behind = 3,
+ Sensor = 4,
+ Nosensor = 5,
+ SensorLandscape = 6,
+ SensorPortrait = 7,
+ ReverseLandscape = 8,
+ ReversePortrait = 9,
+ FullSensor = 10,
+ }
+
+ public DisplayOrientation CurrentOrientation
+ {
+ get
+ {
+ return _currentOrientation;
+ }
+ private set
+ {
+ if (value != _currentOrientation)
+ {
+ DisplayOrientation supported = GetEffectiveSupportedOrientations();
+ ScreenOrientation requestedOrientation = ScreenOrientation.Unspecified;
+ bool wasPortrait = _currentOrientation == DisplayOrientation.Portrait || _currentOrientation == DisplayOrientation.PortraitDown;
+ bool requestPortrait = false;
+
+ bool didOrientationChange = false;
+ // Android 2.3 and above support reverse orientations
+ int sdkVer = (int)Android.OS.Build.VERSION.SdkInt;
+ if (sdkVer >= 10)
+ {
+ // Check if the requested orientation is supported. Default means all are supported.
+ if ((supported & value) != 0)
+ {
+ didOrientationChange = true;
+ _currentOrientation = value;
+ switch (value)
+ {
+ case DisplayOrientation.LandscapeLeft:
+ requestedOrientation = (ScreenOrientation)ScreenOrientationAll.Landscape;
+ requestPortrait = false;
+ break;
+ case DisplayOrientation.LandscapeRight:
+ requestedOrientation = (ScreenOrientation)ScreenOrientationAll.ReverseLandscape;
+ requestPortrait = false;
+ break;
+ case DisplayOrientation.Portrait:
+ requestedOrientation = (ScreenOrientation)ScreenOrientationAll.Portrait;
+ requestPortrait = true;
+ break;
+ case DisplayOrientation.PortraitDown:
+ requestedOrientation = (ScreenOrientation)ScreenOrientationAll.ReversePortrait;
+ requestPortrait = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ // Check if the requested orientation is either of the landscape orientations and any landscape orientation is supported.
+ if ((value == DisplayOrientation.LandscapeLeft || value == DisplayOrientation.LandscapeRight) &&
+ ((supported & (DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight)) != 0))
+ {
+ didOrientationChange = true;
+ _currentOrientation = DisplayOrientation.LandscapeLeft;
+ requestedOrientation = ScreenOrientation.Landscape;
+ requestPortrait = false;
+ }
+ // Check if the requested orientation is either of the portrain orientations and any portrait orientation is supported.
+ else if ((value == DisplayOrientation.Portrait || value == DisplayOrientation.PortraitDown) &&
+ ((supported & (DisplayOrientation.Portrait | DisplayOrientation.PortraitDown)) != 0))
+ {
+ didOrientationChange = true;
+ _currentOrientation = DisplayOrientation.Portrait;
+ requestedOrientation = ScreenOrientation.Portrait;
+ requestPortrait = true;
+ }
+ }
+
+ if (didOrientationChange)
+ {
+ // Android doesn't fire Released events for existing touches
+ // so we need to clear them out.
+ if (wasPortrait != requestPortrait)
+ {
+ TouchPanel.ReleaseAllTouches();
+ }
+
+ Game.Activity.RequestedOrientation = requestedOrientation;
+
+ if (OrientationChanged != null)
+ OrientationChanged(this, EventArgs.Empty);
+ }
+ }
+ }
+ }
+
+ public event EventHandler OrientationChanged;
+ public event EventHandler ClientSizeChanged;
+ public event EventHandler ScreenDeviceNameChanged;
+
+
+ void ISurfaceHolderCallback.SurfaceChanged(ISurfaceHolder holder, Android.Graphics.Format format, int width, int height)
+ {
+ base.SurfaceChanged(holder, format, width, height);
+ Android.Util.Log.Debug("MonoGame", "AndroidGameWindow.SurfaceChanged: format = " + format + ", width = " + width + ", height = " + height);
+
+ if (_game.GraphicsDevice != null)
+ _game.graphicsDeviceManager.ResetClientBounds();
+ }
+
+ void ISurfaceHolderCallback.SurfaceDestroyed(ISurfaceHolder holder)
+ {
+ base.SurfaceDestroyed(holder);
+ Android.Util.Log.Debug("MonoGame", "AndroidGameWindow.SurfaceDestroyed");
+ }
+
+ void ISurfaceHolderCallback.SurfaceCreated(ISurfaceHolder holder)
+ {
+ base.SurfaceCreated(holder);
+ Android.Util.Log.Debug("MonoGame", "AndroidGameWindow.SurfaceCreated: surfaceFrame = " + holder.SurfaceFrame.ToString());
+ }
+ }
+}
+
diff --git a/MonoGame.Framework/Android/OrientationListener.cs b/MonoGame.Framework/Android/OrientationListener.cs
index 84b164534a7..fb59b863d05 100644
--- a/MonoGame.Framework/Android/OrientationListener.cs
+++ b/MonoGame.Framework/Android/OrientationListener.cs
@@ -55,7 +55,7 @@ public override void OnOrientationChanged(int orientation)
break;
case 0: disporientation = DisplayOrientation.Portrait;
break;
- case 180: disporientation = DisplayOrientation.PortraitUpsideDown;
+ case 180: disporientation = DisplayOrientation.PortraitDown;
break;
default:
disporientation = DisplayOrientation.LandscapeLeft;
diff --git a/MonoGame.Framework/MacOS/GameWindow.cs b/MonoGame.Framework/MacOS/GameWindow.cs
index 8fa0d17447d..19a020ab90c 100644
--- a/MonoGame.Framework/MacOS/GameWindow.cs
+++ b/MonoGame.Framework/MacOS/GameWindow.cs
@@ -1,672 +1,672 @@
-#region License
-/*
-Microsoft Public License (Ms-PL)
-XnaTouch - Copyright © 2009 The XnaTouch Team
-
-All rights reserved.
-
-This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
-accept the license, do not use the software.
-
-1. Definitions
-The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
-U.S. copyright law.
-
-A "contribution" is the original software, or any additions or changes to the software.
-A "contributor" is any person that distributes its contribution under this license.
-"Licensed patents" are a contributor's patent claims that read directly on its contribution.
-
-2. Grant of Rights
-(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
-each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
-(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
-each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
-
-3. Conditions and Limitations
-(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
-(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
-your patent license from such contributor to the software ends automatically.
-(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
-notices that are present in the software.
-(D) If you distribute any portion of the software in source code form, you may do so only under this license by including
-a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
-code form, you may only do so under a license that complies with this license.
-(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
-or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
-permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
-purpose and non-infringement.
-*/
-#endregion License
-
-#region Using Statements
-using System;
-using System.Drawing;
-using System.Collections.Generic;
-
-using MonoMac.CoreAnimation;
-using MonoMac.Foundation;
-using MonoMac.ObjCRuntime;
-using MonoMac.OpenGL;
-using MonoMac.AppKit;
-
-using Microsoft.Xna.Framework.Input;
-using Microsoft.Xna.Framework.Input.Touch;
-
-#endregion Using Statements
-
-namespace Microsoft.Xna.Framework
-{
- public class GameWindow : MonoMacGameView
- {
- //private readonly Rectangle clientBounds;
- private Rectangle clientBounds;
- private Game _game;
- private MacGamePlatform _platform;
-
- private NSTrackingArea _trackingArea;
- private bool _needsToResetElapsedTime = false;
-
- public static Func CreateWindowDelegate
- {
- get;
- set;
- }
-
- #region GameWindow Methods
- public GameWindow(Game game, RectangleF frame) : base (frame)
- {
- if (game == null)
- throw new ArgumentNullException("game");
- _game = game;
- _platform = (MacGamePlatform)_game.Services.GetService(typeof(MacGamePlatform));
-
- //LayerRetainsBacking = false;
- //LayerColorFormat = EAGLColorFormat.RGBA8;
- this.AutoresizingMask = MonoMac.AppKit.NSViewResizingMask.HeightSizable
- | MonoMac.AppKit.NSViewResizingMask.MaxXMargin
- | MonoMac.AppKit.NSViewResizingMask.MinYMargin
- | MonoMac.AppKit.NSViewResizingMask.WidthSizable;
-
- RectangleF rect = NSScreen.MainScreen.Frame;
-
- clientBounds = new Rectangle (0,0,(int)rect.Width,(int)rect.Height);
-
- // Enable multi-touch
- //MultipleTouchEnabled = true;
-
- Mouse.Window = this;
- }
-
- public GameWindow(Game game, RectangleF frame, NSOpenGLContext context) :
- this(game, frame)
- {
- }
-
- [Export("initWithFrame:")]
- public GameWindow () : base (NSScreen.MainScreen.Frame)
- {
- this.AutoresizingMask = MonoMac.AppKit.NSViewResizingMask.HeightSizable
- | MonoMac.AppKit.NSViewResizingMask.MaxXMargin
- | MonoMac.AppKit.NSViewResizingMask.MinYMargin
- | MonoMac.AppKit.NSViewResizingMask.WidthSizable;
-
- RectangleF rect = NSScreen.MainScreen.Frame;
- clientBounds = new Rectangle (0,0,(int)rect.Width,(int)rect.Height);
-
- // Enable multi-touch
- //MultipleTouchEnabled = true;
-
- }
-
- ~GameWindow ()
- {
- //
- }
-
- #endregion
-
- public void StartRunLoop(double updateRate)
- {
- Run(updateRate);
- }
-
- public void ResetElapsedTime ()
- {
- _needsToResetElapsedTime = true;
- }
- #region MonoMacGameView Methods
-
- protected override void OnClosed (EventArgs e)
- {
- base.OnClosed (e);
- }
-
- protected override void OnDisposed (EventArgs e)
- {
- base.OnDisposed (e);
- }
-
- protected override void OnLoad (EventArgs e)
- {
- base.OnLoad (e);
- }
-
- protected override void OnRenderFrame (FrameEventArgs e)
- {
- base.OnRenderFrame (e);
-
- // FIXME: Since Game.Exit may be called during an Update loop (and
- // in fact that is quite likely to happen), this code is now
- // littered with checks to _platform.IsRunning. It would be
- // nice if there weren't quite so many. The move to a
- // Game.Tick-centric architecture may eliminate this problem
- // automatically.
- if (_game != null && _platform.IsRunning) {
- _game.Tick();
- }
- }
-// protected override void OnUpdateFrame (FrameEventArgs e)
-// {
-// base.OnUpdateFrame (e);
-//
-// }
- protected override void OnResize (EventArgs e)
- {
- var manager = (GraphicsDeviceManager)_game.Services.GetService(typeof(IGraphicsDeviceManager));
- if (_game.Initialized)
- {
- manager.OnDeviceResetting(EventArgs.Empty);
-
- Microsoft.Xna.Framework.Graphics.Viewport _vp =
- new Microsoft.Xna.Framework.Graphics.Viewport();
-
- _game.GraphicsDevice.PresentationParameters.BackBufferWidth = (int)Bounds.Width;
- _game.GraphicsDevice.PresentationParameters.BackBufferHeight = (int)Bounds.Height;
-
- _vp.X = (int)Bounds.X;
- _vp.Y = (int)Bounds.Y;
- _vp.Width = (int)Bounds.Width;
- _vp.Height = (int)Bounds.Height;
-
- _game.GraphicsDevice.Viewport = _vp;
- }
-
- clientBounds = new Rectangle((int)Bounds.X,(int)Bounds.Y,(int)Bounds.Width,(int)Bounds.Height);
-
- base.OnResize(e);
- OnClientSizeChanged(e);
-
- if (_game.Initialized)
- manager.OnDeviceReset(EventArgs.Empty);
- }
-
- protected virtual void OnClientSizeChanged (EventArgs e)
- {
- var h = ClientSizeChanged;
- if (h != null)
- h (this, e);
- }
-
- protected override void OnTitleChanged (EventArgs e)
- {
- base.OnTitleChanged (e);
- }
-
- protected override void OnUnload (EventArgs e)
- {
- base.OnUnload (e);
- }
-
- protected override void OnVisibleChanged (EventArgs e)
- {
- base.OnVisibleChanged (e);
- }
-
- protected override void OnWindowStateChanged (EventArgs e)
- {
- base.OnWindowStateChanged (e);
- }
-
- #endregion
-
- #region UIVIew Methods
-
- /* TODO private readonly Dictionary previousTouches = new Dictionary();
-
- private void FillTouchCollection(NSSet touches)
- {
- UITouch []touchesArray = touches.ToArray();
-
- TouchPanel.Collection.Clear();
- TouchPanel.Collection.Capacity = touchesArray.Length;
-
- for (int i=0; i ClientSizeChanged;
- public event EventHandler OrientationChanged;
- public event EventHandler ScreenDeviceNameChanged;
-
- // make sure we get mouse move events.
- public override bool AcceptsFirstResponder ()
- {
- return true;
- }
-
- public override bool BecomeFirstResponder ()
- {
- return true;
- }
- public override void CursorUpdate (NSEvent theEvent)
- {
- base.CursorUpdate (theEvent);
- }
-
- public override void ViewWillMoveToWindow (NSWindow newWindow)
- {
- //Console.WriteLine("View will move to window");
- if (_trackingArea != null) RemoveTrackingArea(_trackingArea);
- _trackingArea = new NSTrackingArea(Frame,
- NSTrackingAreaOptions.MouseMoved |
- NSTrackingAreaOptions.MouseEnteredAndExited |
- NSTrackingAreaOptions.EnabledDuringMouseDrag |
- NSTrackingAreaOptions.ActiveWhenFirstResponder |
- NSTrackingAreaOptions.InVisibleRect |
- NSTrackingAreaOptions.CursorUpdate,
- this, new NSDictionary());
- AddTrackingArea(_trackingArea);
-
- }
-
- // These variables are to handle our custom cursor for when IsMouseVisible is false.
- // Hiding and unhiding the cursor was such a pain that I decided to let the system
- // take care of this with Cursor Rectangles
- NSImage cursorImage = null; // Will be set to our custom image
- NSCursor cursor = null; // Our custom cursor
- public override void ResetCursorRects ()
- {
-
- // If we do not have a cursor then we create an image size 1 x 1
- // and then create our custom cursor with clear colors
- if (cursor == null) {
- cursorImage = new NSImage(new SizeF(1,1));
- cursor = new NSCursor(cursorImage, NSColor.Clear, NSColor.Clear, new PointF(0,0));
- }
-
- // if the cursor is not to be visible then we us our custom cursor.
- if (!_game.IsMouseVisible)
- AddCursorRect(Frame, cursor);
- else
- AddCursorRect(Frame, NSCursor.ArrowCursor);
-
- }
-
- public override void DiscardCursorRects ()
- {
- base.DiscardCursorRects ();
- //Console.WriteLine("DiscardCursorRects");
- }
- private void UpdateKeyboardState ()
- {
- _keyStates.Clear ();
- _keyStates.AddRange (_flags);
- _keyStates.AddRange (_keys);
- Keyboard.SetKeys(_keyStates);
- }
-
- // This method should only be called when necessary like when the Guide is displayed
- internal void ClearKeyCacheState() {
- _keys.Clear();
- }
-
- List _keys = new List ();
- List _keyStates = new List ();
-
- public override void KeyDown (NSEvent theEvent)
- {
- Keys kk = KeyUtil.GetKeys (theEvent);
-
- if (!_keys.Contains (kk))
- _keys.Add (kk);
-
- UpdateKeyboardState ();
- }
-
- public override void KeyUp (NSEvent theEvent)
- {
- Keys kk = KeyUtil.GetKeys (theEvent);
-
- _keys.Remove (kk);
-
- UpdateKeyboardState ();
- }
-
- List _flags = new List ();
-
- public override void FlagsChanged (NSEvent theEvent)
- {
-
- _flags.Clear ();
- var modInt = (uint)theEvent.ModifierFlags & 0xFFFF0000;
- var modifier = ((NSEventModifierMask)Enum.ToObject (typeof(NSEventModifierMask), modInt));
-
- switch (modifier) {
- //case NSEventModifierMask.AlphaShiftKeyMask:
- // return Keys.None;
- case NSEventModifierMask.AlternateKeyMask:
- _flags.Add (Keys.LeftAlt);
- _flags.Add (Keys.RightAlt);
- break;
-
- case NSEventModifierMask.CommandKeyMask:
- _flags.Add (Keys.LeftWindows);
- _flags.Add (Keys.RightWindows);
- break;
- case NSEventModifierMask.ControlKeyMask:
- _flags.Add (Keys.LeftControl);
- _flags.Add (Keys.RightControl);
- break;
- case NSEventModifierMask.HelpKeyMask:
- _flags.Add (Keys.Help);
- break;
- case NSEventModifierMask.ShiftKeyMask:
- _flags.Add (Keys.RightShift);
- _flags.Add (Keys.LeftShift);
- break;
- }
-
- UpdateKeyboardState ();
- }
-
- public override void MouseDown (NSEvent theEvent)
- {
- PointF loc = theEvent.LocationInWindow;
- UpdateMousePosition (loc);
- switch (theEvent.Type) {
- case NSEventType.LeftMouseDown:
- Mouse.State.LeftButton = ButtonState.Pressed;
- break;
- }
- }
-
- public override void MouseUp (NSEvent theEvent)
- {
- PointF loc = theEvent.LocationInWindow;
- UpdateMousePosition (loc);
- switch (theEvent.Type) {
-
- case NSEventType.LeftMouseUp:
- Mouse.State.LeftButton = ButtonState.Released;
- break;
- }
- }
-
- public override void MouseDragged (NSEvent theEvent)
- {
- PointF loc = theEvent.LocationInWindow;
- UpdateMousePosition (loc);
- }
-
- public override void RightMouseDown (NSEvent theEvent)
- {
- PointF loc = theEvent.LocationInWindow;
- UpdateMousePosition (loc);
- switch (theEvent.Type) {
- case NSEventType.RightMouseDown:
- Mouse.State.RightButton = ButtonState.Pressed;
- break;
- }
- }
-
- public override void RightMouseUp (NSEvent theEvent)
- {
- PointF loc = theEvent.LocationInWindow;
- UpdateMousePosition (loc);
- switch (theEvent.Type) {
- case NSEventType.RightMouseUp:
- Mouse.State.RightButton = ButtonState.Released;
- break;
- }
- }
-
- public override void RightMouseDragged (NSEvent theEvent)
- {
- PointF loc = theEvent.LocationInWindow;
- UpdateMousePosition (loc);
- }
-
- public override void OtherMouseDown (NSEvent theEvent)
- {
- PointF loc = theEvent.LocationInWindow;
- UpdateMousePosition (loc);
- switch (theEvent.Type) {
- case NSEventType.OtherMouseDown:
- Mouse.State.MiddleButton = ButtonState.Pressed;
- break;
- }
- }
-
- public override void OtherMouseUp (NSEvent theEvent)
- {
- PointF loc = theEvent.LocationInWindow;
- UpdateMousePosition (loc);
- switch (theEvent.Type) {
- case NSEventType.OtherMouseUp:
- Mouse.State.MiddleButton = ButtonState.Released;
- break;
- }
- }
-
- public override void OtherMouseDragged (NSEvent theEvent)
- {
- PointF loc = theEvent.LocationInWindow;
- UpdateMousePosition (loc);
- }
-
- public override void ScrollWheel (NSEvent theEvent)
- {
- PointF loc = theEvent.LocationInWindow;
- UpdateMousePosition(loc);
-
- switch (theEvent.Type) {
- case NSEventType.ScrollWheel:
- if (theEvent.DeltaY > 0) {
- Mouse.ScrollWheelValue += (theEvent.DeltaY*0.1f+0.09f)*1200;
- } else {
- Mouse.ScrollWheelValue += (theEvent.DeltaY*0.1f-0.09f)*1200;
- }
- break;
- }
- }
-
- public override void MouseMoved (NSEvent theEvent)
- {
- PointF loc = theEvent.LocationInWindow;
- UpdateMousePosition (loc);
-
- switch (theEvent.Type) {
- case NSEventType.MouseMoved:
- //Mouse.Moved = true;
- break;
- }
- }
-
- private void UpdateMousePosition (PointF location)
- {
- Mouse.State.X = (int)location.X;
- Mouse.State.Y = (int)(ClientBounds.Height - location.Y);
- }
-
- }
-}
-
+#region License
+/*
+Microsoft Public License (Ms-PL)
+XnaTouch - Copyright © 2009 The XnaTouch Team
+
+All rights reserved.
+
+This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
+accept the license, do not use the software.
+
+1. Definitions
+The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
+U.S. copyright law.
+
+A "contribution" is the original software, or any additions or changes to the software.
+A "contributor" is any person that distributes its contribution under this license.
+"Licensed patents" are a contributor's patent claims that read directly on its contribution.
+
+2. Grant of Rights
+(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
+each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
+(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
+each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
+
+3. Conditions and Limitations
+(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
+(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
+your patent license from such contributor to the software ends automatically.
+(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
+notices that are present in the software.
+(D) If you distribute any portion of the software in source code form, you may do so only under this license by including
+a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
+code form, you may only do so under a license that complies with this license.
+(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
+or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
+permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
+purpose and non-infringement.
+*/
+#endregion License
+
+#region Using Statements
+using System;
+using System.Drawing;
+using System.Collections.Generic;
+
+using MonoMac.CoreAnimation;
+using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
+using MonoMac.OpenGL;
+using MonoMac.AppKit;
+
+using Microsoft.Xna.Framework.Input;
+using Microsoft.Xna.Framework.Input.Touch;
+
+#endregion Using Statements
+
+namespace Microsoft.Xna.Framework
+{
+ public class GameWindow : MonoMacGameView
+ {
+ //private readonly Rectangle clientBounds;
+ private Rectangle clientBounds;
+ private Game _game;
+ private MacGamePlatform _platform;
+
+ private NSTrackingArea _trackingArea;
+ private bool _needsToResetElapsedTime = false;
+
+ public static Func CreateWindowDelegate
+ {
+ get;
+ set;
+ }
+
+ #region GameWindow Methods
+ public GameWindow(Game game, RectangleF frame) : base (frame)
+ {
+ if (game == null)
+ throw new ArgumentNullException("game");
+ _game = game;
+ _platform = (MacGamePlatform)_game.Services.GetService(typeof(MacGamePlatform));
+
+ //LayerRetainsBacking = false;
+ //LayerColorFormat = EAGLColorFormat.RGBA8;
+ this.AutoresizingMask = MonoMac.AppKit.NSViewResizingMask.HeightSizable
+ | MonoMac.AppKit.NSViewResizingMask.MaxXMargin
+ | MonoMac.AppKit.NSViewResizingMask.MinYMargin
+ | MonoMac.AppKit.NSViewResizingMask.WidthSizable;
+
+ RectangleF rect = NSScreen.MainScreen.Frame;
+
+ clientBounds = new Rectangle (0,0,(int)rect.Width,(int)rect.Height);
+
+ // Enable multi-touch
+ //MultipleTouchEnabled = true;
+
+ Mouse.Window = this;
+ }
+
+ public GameWindow(Game game, RectangleF frame, NSOpenGLContext context) :
+ this(game, frame)
+ {
+ }
+
+ [Export("initWithFrame:")]
+ public GameWindow () : base (NSScreen.MainScreen.Frame)
+ {
+ this.AutoresizingMask = MonoMac.AppKit.NSViewResizingMask.HeightSizable
+ | MonoMac.AppKit.NSViewResizingMask.MaxXMargin
+ | MonoMac.AppKit.NSViewResizingMask.MinYMargin
+ | MonoMac.AppKit.NSViewResizingMask.WidthSizable;
+
+ RectangleF rect = NSScreen.MainScreen.Frame;
+ clientBounds = new Rectangle (0,0,(int)rect.Width,(int)rect.Height);
+
+ // Enable multi-touch
+ //MultipleTouchEnabled = true;
+
+ }
+
+ ~GameWindow ()
+ {
+ //
+ }
+
+ #endregion
+
+ public void StartRunLoop(double updateRate)
+ {
+ Run(updateRate);
+ }
+
+ public void ResetElapsedTime ()
+ {
+ _needsToResetElapsedTime = true;
+ }
+ #region MonoMacGameView Methods
+
+ protected override void OnClosed (EventArgs e)
+ {
+ base.OnClosed (e);
+ }
+
+ protected override void OnDisposed (EventArgs e)
+ {
+ base.OnDisposed (e);
+ }
+
+ protected override void OnLoad (EventArgs e)
+ {
+ base.OnLoad (e);
+ }
+
+ protected override void OnRenderFrame (FrameEventArgs e)
+ {
+ base.OnRenderFrame (e);
+
+ // FIXME: Since Game.Exit may be called during an Update loop (and
+ // in fact that is quite likely to happen), this code is now
+ // littered with checks to _platform.IsRunning. It would be
+ // nice if there weren't quite so many. The move to a
+ // Game.Tick-centric architecture may eliminate this problem
+ // automatically.
+ if (_game != null && _platform.IsRunning) {
+ _game.Tick();
+ }
+ }
+// protected override void OnUpdateFrame (FrameEventArgs e)
+// {
+// base.OnUpdateFrame (e);
+//
+// }
+ protected override void OnResize (EventArgs e)
+ {
+ var manager = (GraphicsDeviceManager)_game.Services.GetService(typeof(IGraphicsDeviceManager));
+ if (_game.Initialized)
+ {
+ manager.OnDeviceResetting(EventArgs.Empty);
+
+ Microsoft.Xna.Framework.Graphics.Viewport _vp =
+ new Microsoft.Xna.Framework.Graphics.Viewport();
+
+ _game.GraphicsDevice.PresentationParameters.BackBufferWidth = (int)Bounds.Width;
+ _game.GraphicsDevice.PresentationParameters.BackBufferHeight = (int)Bounds.Height;
+
+ _vp.X = (int)Bounds.X;
+ _vp.Y = (int)Bounds.Y;
+ _vp.Width = (int)Bounds.Width;
+ _vp.Height = (int)Bounds.Height;
+
+ _game.GraphicsDevice.Viewport = _vp;
+ }
+
+ clientBounds = new Rectangle((int)Bounds.X,(int)Bounds.Y,(int)Bounds.Width,(int)Bounds.Height);
+
+ base.OnResize(e);
+ OnClientSizeChanged(e);
+
+ if (_game.Initialized)
+ manager.OnDeviceReset(EventArgs.Empty);
+ }
+
+ protected virtual void OnClientSizeChanged (EventArgs e)
+ {
+ var h = ClientSizeChanged;
+ if (h != null)
+ h (this, e);
+ }
+
+ protected override void OnTitleChanged (EventArgs e)
+ {
+ base.OnTitleChanged (e);
+ }
+
+ protected override void OnUnload (EventArgs e)
+ {
+ base.OnUnload (e);
+ }
+
+ protected override void OnVisibleChanged (EventArgs e)
+ {
+ base.OnVisibleChanged (e);
+ }
+
+ protected override void OnWindowStateChanged (EventArgs e)
+ {
+ base.OnWindowStateChanged (e);
+ }
+
+ #endregion
+
+ #region UIVIew Methods
+
+ /* TODO private readonly Dictionary previousTouches = new Dictionary();
+
+ private void FillTouchCollection(NSSet touches)
+ {
+ UITouch []touchesArray = touches.ToArray();
+
+ TouchPanel.Collection.Clear();
+ TouchPanel.Collection.Capacity = touchesArray.Length;
+
+ for (int i=0; i ClientSizeChanged;
+ public event EventHandler OrientationChanged;
+ public event EventHandler ScreenDeviceNameChanged;
+
+ // make sure we get mouse move events.
+ public override bool AcceptsFirstResponder ()
+ {
+ return true;
+ }
+
+ public override bool BecomeFirstResponder ()
+ {
+ return true;
+ }
+ public override void CursorUpdate (NSEvent theEvent)
+ {
+ base.CursorUpdate (theEvent);
+ }
+
+ public override void ViewWillMoveToWindow (NSWindow newWindow)
+ {
+ //Console.WriteLine("View will move to window");
+ if (_trackingArea != null) RemoveTrackingArea(_trackingArea);
+ _trackingArea = new NSTrackingArea(Frame,
+ NSTrackingAreaOptions.MouseMoved |
+ NSTrackingAreaOptions.MouseEnteredAndExited |
+ NSTrackingAreaOptions.EnabledDuringMouseDrag |
+ NSTrackingAreaOptions.ActiveWhenFirstResponder |
+ NSTrackingAreaOptions.InVisibleRect |
+ NSTrackingAreaOptions.CursorUpdate,
+ this, new NSDictionary());
+ AddTrackingArea(_trackingArea);
+
+ }
+
+ // These variables are to handle our custom cursor for when IsMouseVisible is false.
+ // Hiding and unhiding the cursor was such a pain that I decided to let the system
+ // take care of this with Cursor Rectangles
+ NSImage cursorImage = null; // Will be set to our custom image
+ NSCursor cursor = null; // Our custom cursor
+ public override void ResetCursorRects ()
+ {
+
+ // If we do not have a cursor then we create an image size 1 x 1
+ // and then create our custom cursor with clear colors
+ if (cursor == null) {
+ cursorImage = new NSImage(new SizeF(1,1));
+ cursor = new NSCursor(cursorImage, NSColor.Clear, NSColor.Clear, new PointF(0,0));
+ }
+
+ // if the cursor is not to be visible then we us our custom cursor.
+ if (!_game.IsMouseVisible)
+ AddCursorRect(Frame, cursor);
+ else
+ AddCursorRect(Frame, NSCursor.ArrowCursor);
+
+ }
+
+ public override void DiscardCursorRects ()
+ {
+ base.DiscardCursorRects ();
+ //Console.WriteLine("DiscardCursorRects");
+ }
+ private void UpdateKeyboardState ()
+ {
+ _keyStates.Clear ();
+ _keyStates.AddRange (_flags);
+ _keyStates.AddRange (_keys);
+ Keyboard.SetKeys(_keyStates);
+ }
+
+ // This method should only be called when necessary like when the Guide is displayed
+ internal void ClearKeyCacheState() {
+ _keys.Clear();
+ }
+
+ List _keys = new List ();
+ List _keyStates = new List ();
+
+ public override void KeyDown (NSEvent theEvent)
+ {
+ Keys kk = KeyUtil.GetKeys (theEvent);
+
+ if (!_keys.Contains (kk))
+ _keys.Add (kk);
+
+ UpdateKeyboardState ();
+ }
+
+ public override void KeyUp (NSEvent theEvent)
+ {
+ Keys kk = KeyUtil.GetKeys (theEvent);
+
+ _keys.Remove (kk);
+
+ UpdateKeyboardState ();
+ }
+
+ List _flags = new List ();
+
+ public override void FlagsChanged (NSEvent theEvent)
+ {
+
+ _flags.Clear ();
+ var modInt = (uint)theEvent.ModifierFlags & 0xFFFF0000;
+ var modifier = ((NSEventModifierMask)Enum.ToObject (typeof(NSEventModifierMask), modInt));
+
+ switch (modifier) {
+ //case NSEventModifierMask.AlphaShiftKeyMask:
+ // return Keys.None;
+ case NSEventModifierMask.AlternateKeyMask:
+ _flags.Add (Keys.LeftAlt);
+ _flags.Add (Keys.RightAlt);
+ break;
+
+ case NSEventModifierMask.CommandKeyMask:
+ _flags.Add (Keys.LeftWindows);
+ _flags.Add (Keys.RightWindows);
+ break;
+ case NSEventModifierMask.ControlKeyMask:
+ _flags.Add (Keys.LeftControl);
+ _flags.Add (Keys.RightControl);
+ break;
+ case NSEventModifierMask.HelpKeyMask:
+ _flags.Add (Keys.Help);
+ break;
+ case NSEventModifierMask.ShiftKeyMask:
+ _flags.Add (Keys.RightShift);
+ _flags.Add (Keys.LeftShift);
+ break;
+ }
+
+ UpdateKeyboardState ();
+ }
+
+ public override void MouseDown (NSEvent theEvent)
+ {
+ PointF loc = theEvent.LocationInWindow;
+ UpdateMousePosition (loc);
+ switch (theEvent.Type) {
+ case NSEventType.LeftMouseDown:
+ Mouse.State.LeftButton = ButtonState.Pressed;
+ break;
+ }
+ }
+
+ public override void MouseUp (NSEvent theEvent)
+ {
+ PointF loc = theEvent.LocationInWindow;
+ UpdateMousePosition (loc);
+ switch (theEvent.Type) {
+
+ case NSEventType.LeftMouseUp:
+ Mouse.State.LeftButton = ButtonState.Released;
+ break;
+ }
+ }
+
+ public override void MouseDragged (NSEvent theEvent)
+ {
+ PointF loc = theEvent.LocationInWindow;
+ UpdateMousePosition (loc);
+ }
+
+ public override void RightMouseDown (NSEvent theEvent)
+ {
+ PointF loc = theEvent.LocationInWindow;
+ UpdateMousePosition (loc);
+ switch (theEvent.Type) {
+ case NSEventType.RightMouseDown:
+ Mouse.State.RightButton = ButtonState.Pressed;
+ break;
+ }
+ }
+
+ public override void RightMouseUp (NSEvent theEvent)
+ {
+ PointF loc = theEvent.LocationInWindow;
+ UpdateMousePosition (loc);
+ switch (theEvent.Type) {
+ case NSEventType.RightMouseUp:
+ Mouse.State.RightButton = ButtonState.Released;
+ break;
+ }
+ }
+
+ public override void RightMouseDragged (NSEvent theEvent)
+ {
+ PointF loc = theEvent.LocationInWindow;
+ UpdateMousePosition (loc);
+ }
+
+ public override void OtherMouseDown (NSEvent theEvent)
+ {
+ PointF loc = theEvent.LocationInWindow;
+ UpdateMousePosition (loc);
+ switch (theEvent.Type) {
+ case NSEventType.OtherMouseDown:
+ Mouse.State.MiddleButton = ButtonState.Pressed;
+ break;
+ }
+ }
+
+ public override void OtherMouseUp (NSEvent theEvent)
+ {
+ PointF loc = theEvent.LocationInWindow;
+ UpdateMousePosition (loc);
+ switch (theEvent.Type) {
+ case NSEventType.OtherMouseUp:
+ Mouse.State.MiddleButton = ButtonState.Released;
+ break;
+ }
+ }
+
+ public override void OtherMouseDragged (NSEvent theEvent)
+ {
+ PointF loc = theEvent.LocationInWindow;
+ UpdateMousePosition (loc);
+ }
+
+ public override void ScrollWheel (NSEvent theEvent)
+ {
+ PointF loc = theEvent.LocationInWindow;
+ UpdateMousePosition(loc);
+
+ switch (theEvent.Type) {
+ case NSEventType.ScrollWheel:
+ if (theEvent.DeltaY > 0) {
+ Mouse.ScrollWheelValue += (theEvent.DeltaY*0.1f+0.09f)*1200;
+ } else {
+ Mouse.ScrollWheelValue += (theEvent.DeltaY*0.1f-0.09f)*1200;
+ }
+ break;
+ }
+ }
+
+ public override void MouseMoved (NSEvent theEvent)
+ {
+ PointF loc = theEvent.LocationInWindow;
+ UpdateMousePosition (loc);
+
+ switch (theEvent.Type) {
+ case NSEventType.MouseMoved:
+ //Mouse.Moved = true;
+ break;
+ }
+ }
+
+ private void UpdateMousePosition (PointF location)
+ {
+ Mouse.State.X = (int)location.X;
+ Mouse.State.Y = (int)(ClientBounds.Height - location.Y);
+ }
+
+ }
+}
+
diff --git a/MonoGame.Framework/iOS/OrientationConverter.cs b/MonoGame.Framework/iOS/OrientationConverter.cs
index a9f22a4fc80..9ad316f8fea 100644
--- a/MonoGame.Framework/iOS/OrientationConverter.cs
+++ b/MonoGame.Framework/iOS/OrientationConverter.cs
@@ -77,15 +77,15 @@ public static DisplayOrientation UIDeviceOrientationToDisplayOrientation(UIDevic
{
switch (orientation)
{
- case UIDeviceOrientation.FaceDown: return DisplayOrientation.FaceDown;
- case UIDeviceOrientation.FaceUp: return DisplayOrientation.FaceUp;
+ case UIDeviceOrientation.FaceDown: return DisplayOrientation.Unknown;
+ case UIDeviceOrientation.FaceUp: return DisplayOrientation.Unknown;
default:
// NOTE: in XNA, Orientation Left is a 90 degree rotation counterclockwise, while on iOS
// it is a 90 degree rotation CLOCKWISE. They are BACKWARDS!
case UIDeviceOrientation.LandscapeLeft: return DisplayOrientation.LandscapeRight;
case UIDeviceOrientation.LandscapeRight: return DisplayOrientation.LandscapeLeft;
case UIDeviceOrientation.Portrait: return DisplayOrientation.Portrait;
- case UIDeviceOrientation.PortraitUpsideDown: return DisplayOrientation.PortraitUpsideDown;
+ case UIDeviceOrientation.PortraitUpsideDown: return DisplayOrientation.PortraitDown;
}
}
@@ -99,7 +99,7 @@ public static DisplayOrientation ToDisplayOrientation(UIInterfaceOrientation ori
case UIInterfaceOrientation.LandscapeLeft: return DisplayOrientation.LandscapeRight;
case UIInterfaceOrientation.LandscapeRight: return DisplayOrientation.LandscapeLeft;
case UIInterfaceOrientation.Portrait: return DisplayOrientation.Portrait;
- case UIInterfaceOrientation.PortraitUpsideDown: return DisplayOrientation.PortraitUpsideDown;
+ case UIInterfaceOrientation.PortraitUpsideDown: return DisplayOrientation.PortraitDown;
}
}
@@ -107,18 +107,18 @@ public static UIInterfaceOrientationMask ToUIInterfaceOrientationMask (DisplayOr
{
switch (Normalize(orientation))
{
- case((DisplayOrientation)1):
- case((DisplayOrientation)6):
+ case((DisplayOrientation)0):
+ case((DisplayOrientation)3):
return UIInterfaceOrientationMask.Landscape;
- case((DisplayOrientation)2):
+ case((DisplayOrientation)1):
return UIInterfaceOrientationMask.LandscapeLeft;
- case((DisplayOrientation)4):
+ case((DisplayOrientation)2):
return UIInterfaceOrientationMask.LandscapeRight;
- case((DisplayOrientation)16):
+ case((DisplayOrientation)4):
return UIInterfaceOrientationMask.Portrait;
- case((DisplayOrientation)32):
+ case((DisplayOrientation)8):
return UIInterfaceOrientationMask.PortraitUpsideDown;
- case((DisplayOrientation)14):
+ case((DisplayOrientation)7):
return UIInterfaceOrientationMask.AllButUpsideDown;
default:
return UIInterfaceOrientationMask.All;