From a41472a4716ed7c6d7fb1b29500930117f52d81d Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 13 Jun 2012 21:09:13 +0100 Subject: [PATCH 01/22] some fixes to allow the Video to work on android. --- MonoGame.Framework/Android/Media/Video.cs | 62 ++++++++++++++----- .../Android/Media/VideoPlayer.cs | 25 ++++---- 2 files changed, 62 insertions(+), 25 deletions(-) diff --git a/MonoGame.Framework/Android/Media/Video.cs b/MonoGame.Framework/Android/Media/Video.cs index 81b38bedf43..b8e9b1c556c 100644 --- a/MonoGame.Framework/Android/Media/Video.cs +++ b/MonoGame.Framework/Android/Media/Video.cs @@ -36,6 +36,9 @@ // permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular // purpose and non-infringement. // */ +using Android.Widget; + + #endregion License using System; @@ -46,17 +49,18 @@ namespace Microsoft.Xna.Framework.Media { - public sealed class Video : IDisposable + public sealed class Video : Java.Lang.Object, IDisposable, Android.Media.MediaPlayer.IOnCompletionListener, + Android.Media.MediaPlayer.IOnVideoSizeChangedListener { - internal Android.Media.MediaPlayer Player; + internal VideoPlayer Player; + internal Android.Media.MediaPlayer media; private string _fileName; private Color _backColor = Color.Black; internal Video(string FileName) { - _fileName = FileName; - Prepare(); + _fileName = FileName; } public Color BackgroundColor @@ -116,25 +120,55 @@ private static bool Contains(string search, string[] arr) internal void Prepare() { - Player = new Android.Media.MediaPlayer(); - if (Player != null ) + + media = new Android.Media.MediaPlayer();//.Create(Game.Activity,Android.Net.Uri.Parse("file://android_asset/Content/sintel_trailer.mp4"), Game.Instance.Window.Holder); + if (media != null ) { - var afd = Game.Activity.Assets.OpenFd(_fileName); + var afd = Game.Activity.Assets.OpenFd(_fileName); if (afd != null) - { - Player.SetDataSource(afd.FileDescriptor, afd.StartOffset, afd.Length); - Player.Prepare(); + { + media.SetOnCompletionListener(this); + media.SetOnVideoSizeChangedListener(this); + VideoView vv = (VideoView)Game.Activity.FindViewById(MonoGame.Android.Media.VideoViewId); + if (vv == null) throw new InvalidOperationException("you must attach a VideoView in a framelayout with its Id set to MonoGame.Android.Media.VideoViewId"); + media.SetDisplay(vv.Holder); + media.SetDataSource(afd.FileDescriptor, afd.StartOffset, afd.Length); + media.Prepare(); } } } + public void Dispose() { - if (Player != null) - { - Player.Dispose(); - Player = null; + if (media != null) + { + media.Dispose(); + media = null; } } + + #region IOnCompletionListener implementation + public void OnCompletion (Android.Media.MediaPlayer mp) + { + if (Player != null) Player.Stop(); + } + #endregion + + #region IOnVideoSizeChangedListener implementation + public void OnVideoSizeChanged (Android.Media.MediaPlayer mp, int width, int height) + { +#if DEBUG + Android.Util.Log.Info("MonoGameInfo", string.Format("Video Size : {0}x{1}", width, height)); +#endif + } + #endregion } +} +namespace MonoGame.Android +{ + public class Media + { + public const int VideoViewId = 243252; + } } \ No newline at end of file diff --git a/MonoGame.Framework/Android/Media/VideoPlayer.cs b/MonoGame.Framework/Android/Media/VideoPlayer.cs index e108322b427..922ae66ab1d 100644 --- a/MonoGame.Framework/Android/Media/VideoPlayer.cs +++ b/MonoGame.Framework/Android/Media/VideoPlayer.cs @@ -65,12 +65,12 @@ public Texture2D GetTexture() public void Pause() { - _video.Player.Pause(); + _video.media.Pause(); } public void Resume() { - _video.Player.Start(); + _video.media.Start(); } public MediaState State @@ -83,21 +83,23 @@ public MediaState State public void Play(Microsoft.Xna.Framework.Media.Video video) { - _video = video; - - _video.Player.SetDisplay(_game.Window.Holder); - _video.Player.Start(); - + AndroidGamePlatform.IsPlayingVdeo = true; + _video = video; + _video.Player = this; + _video.Prepare(); + _video.media.Start(); _state = MediaState.Playing; - AndroidGamePlatform.IsPlayingVdeo = true; } public void Stop() - { - _video.Player.Stop(); + { + _video.media.Stop(); _state = MediaState.Stopped; AndroidGamePlatform.IsPlayingVdeo = false; - _video.Player.SetDisplay(null); + _video.media.SetOnCompletionListener(null); + _video.media.SetOnVideoSizeChangedListener(null); + _video.media.SetDisplay(null); + _video.Player = null; } public bool IsLooped @@ -119,5 +121,6 @@ public Microsoft.Xna.Framework.Media.Video Video return _video; } } + } } From 7d80899069c92bea4ac0005f5d1bfcd16c49fea4 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Wed, 13 Jun 2012 21:55:43 +0100 Subject: [PATCH 02/22] Create a pkg-config file for MonoGame. This assumes, that, for example, if the pkg-config prefix used is /usr/lib/pkgconfig then the MonoGame assemblies are installed to /usr/lib/monogame. This pkg-config file places a requirement on OpenTK and Tao.SDL packages to be provided by the distribution. The net result is that "mcs -pkg:monogame mygame.cs" will build against MonoGame. --- monogame.pc | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 monogame.pc diff --git a/monogame.pc b/monogame.pc new file mode 100644 index 00000000000..1e5ed4991d1 --- /dev/null +++ b/monogame.pc @@ -0,0 +1,9 @@ +prefix=${pcfiledir}/../.. +exec_prefix=${prefix} +libdir=${exec_prefix}/lib/monogame + +Name: MonoGame +Description: Free implementation of XNA +Version: 2.5 +Requires: opentk tao-sdl +Libs: -r:${libdir}/MonoGame.Framework.Linux.dll -r:${libdir}/Lidgren.Network.dll From f94e668f57d0d06fdd596a3e4f26ce4ee216e3e3 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Wed, 13 Jun 2012 21:59:17 +0100 Subject: [PATCH 03/22] Remove obsolete calls to closed-source gamepad bridge in template. The template tries to place requirements on the closed-source gamepad bridge no longer shipped with MonoGame. Remove it to prevent build failures. --- .../templates/MonoGameLinuxProject.xpt.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/ProjectTemplates/MonoDevelop.MonoGame.2.5/templates/MonoGameLinuxProject.xpt.xml b/ProjectTemplates/MonoDevelop.MonoGame.2.5/templates/MonoGameLinuxProject.xpt.xml index 63832cbab81..61c2538f73b 100644 --- a/ProjectTemplates/MonoDevelop.MonoGame.2.5/templates/MonoGameLinuxProject.xpt.xml +++ b/ProjectTemplates/MonoDevelop.MonoGame.2.5/templates/MonoGameLinuxProject.xpt.xml @@ -26,8 +26,6 @@ - - From e5d6d41a1099037865dcda88e9b322c173aa8802 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Fri, 15 Jun 2012 22:04:52 +0100 Subject: [PATCH 04/22] Work around "Copy Local" bug in MonoDevelop As detailed in MonoDevelop bug 4030, assembly references which resolve via pkg-config packages and are non-GAC are never copied locally to the assembly output folder, which means the app will not run if it relies upon one of these unstable libraries (MonoMac also suffers from this) Copy-paste a workaround from the MonoMac source code where any libraries resolved from monogame.pc should be forcefully copied to the output folder of the build, for all MonoGame project types. --- .../MonoDevelop.MonoGame/MonoGameProject.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ProjectTemplates/MonoDevelop.MonoGame.2.5/MonoDevelop.MonoGame/MonoDevelop.MonoGame/MonoGameProject.cs b/ProjectTemplates/MonoDevelop.MonoGame.2.5/MonoDevelop.MonoGame/MonoDevelop.MonoGame/MonoGameProject.cs index 55bd9e8723b..3b045cc92ff 100644 --- a/ProjectTemplates/MonoDevelop.MonoGame.2.5/MonoDevelop.MonoGame/MonoDevelop.MonoGame/MonoGameProject.cs +++ b/ProjectTemplates/MonoDevelop.MonoGame.2.5/MonoDevelop.MonoGame/MonoDevelop.MonoGame/MonoGameProject.cs @@ -52,6 +52,29 @@ public override bool SupportsFramework (MonoDevelop.Core.Assemblies.TargetFramew else return base.SupportsFramework (framework); } + + protected override void PopulateSupportFileList (MonoDevelop.Projects.FileCopySet list, ConfigurationSelector solutionConfiguration) + { + base.PopulateSupportFileList (list, solutionConfiguration); + + //HACK: workaround for MD not local-copying package references + foreach (var projectReference in References) { + if (projectReference.Package != null && projectReference.Package.Name == "monogame") { + if (projectReference.ReferenceType == ReferenceType.Gac) { + foreach (var assem in projectReference.Package.Assemblies) { + list.Add (assem.Location); + var cfg = (MonoGameProjectConfiguration)solutionConfiguration.GetConfiguration (this); + if (cfg.DebugMode) { + var mdbFile = TargetRuntime.GetAssemblyDebugInfoFile (assem.Location); + if (System.IO.File.Exists (mdbFile)) + list.Add (mdbFile); + } + } + } + break; + } + } + } } public class MonoGameProjectBinding : IProjectBinding From e23c977200de688a5852d625455b2e0eb29148f2 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Fri, 15 Jun 2012 22:07:15 +0100 Subject: [PATCH 05/22] Fix assembly reference in template to drop unneeded ".dll" extension MonoDevelop's assembly reference resolver doesn't work if you have "Gac" references with file extensions. Drop the .dll, and MonoDevelop will find Tao from a suitable location such as the GAC or a pkg-config package. --- .../templates/MonoGameLinuxProject.xpt.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProjectTemplates/MonoDevelop.MonoGame.2.5/templates/MonoGameLinuxProject.xpt.xml b/ProjectTemplates/MonoDevelop.MonoGame.2.5/templates/MonoGameLinuxProject.xpt.xml index 61c2538f73b..068eb336bae 100644 --- a/ProjectTemplates/MonoDevelop.MonoGame.2.5/templates/MonoGameLinuxProject.xpt.xml +++ b/ProjectTemplates/MonoDevelop.MonoGame.2.5/templates/MonoGameLinuxProject.xpt.xml @@ -26,7 +26,7 @@ - + From 3d09540645d84ef0a077f1e9c16160f88f0b4ffb Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Sun, 17 Jun 2012 16:38:37 +0100 Subject: [PATCH 06/22] Fixed http://monogame.codeplex.com/workitem/6680 --- MonoGame.Framework/Android/Content/ContentReaders/SongReader.cs | 2 +- .../Android/Content/ContentReaders/SoundEffectReader.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MonoGame.Framework/Android/Content/ContentReaders/SongReader.cs b/MonoGame.Framework/Android/Content/ContentReaders/SongReader.cs index b4a2009b8f5..b2d1a8580ec 100644 --- a/MonoGame.Framework/Android/Content/ContentReaders/SongReader.cs +++ b/MonoGame.Framework/Android/Content/ContentReaders/SongReader.cs @@ -43,7 +43,7 @@ using System.IO; using System.Linq; -namespace Microsoft.Xna.Framework +namespace Microsoft.Xna.Framework.Content { internal class SongReader { diff --git a/MonoGame.Framework/Android/Content/ContentReaders/SoundEffectReader.cs b/MonoGame.Framework/Android/Content/ContentReaders/SoundEffectReader.cs index 2fe5e1c41e2..bf097453bb0 100644 --- a/MonoGame.Framework/Android/Content/ContentReaders/SoundEffectReader.cs +++ b/MonoGame.Framework/Android/Content/ContentReaders/SoundEffectReader.cs @@ -43,7 +43,7 @@ using System.IO; using System.Linq; -namespace Microsoft.Xna.Framework +namespace Microsoft.Xna.Framework.Content { internal class SoundEffectReader { From 1c94cf42a46d68bfbf99620cbdfe5e5936585ccd Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Sun, 17 Jun 2012 17:54:45 +0100 Subject: [PATCH 07/22] Fixed texture order of the GetData in uint format to match xna ABGR rather than RGBA Updated all uses of DateTime.Now to DateTime.UtcNow to reduce consing.... --- MonoGame.Framework/Android/Graphics/Texture2D.cs | 8 ++++---- MonoGame.Framework/Game.cs | 6 +++--- MonoGame.Framework/MacOS/Graphics/Texture2D.cs | 8 ++++---- MonoGame.Framework/Net/MonoGamerPeer.cs | 4 ++-- MonoGame.Framework/PrimaryThreadLoader.cs | 6 +++--- MonoGame.Framework/iOS/Graphics/Texture2D.cs | 8 ++++---- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/MonoGame.Framework/Android/Graphics/Texture2D.cs b/MonoGame.Framework/Android/Graphics/Texture2D.cs index 8255e8839a5..2079e2b1280 100644 --- a/MonoGame.Framework/Android/Graphics/Texture2D.cs +++ b/MonoGame.Framework/Android/Graphics/Texture2D.cs @@ -620,10 +620,10 @@ public void GetData(int level, Rectangle? rect, T[] data, int startIndex, int { final[i] = (uint) ( - colors[i].R << 24 | - colors[i].G << 16 | - colors[i].B << 8 | - colors[i].A + colors[i].A << 24 | + colors[i].B << 16 | + colors[i].G << 8 | + colors[i].R ); } } diff --git a/MonoGame.Framework/Game.cs b/MonoGame.Framework/Game.cs index 4fb7f17b55f..5033d3d7a25 100644 --- a/MonoGame.Framework/Game.cs +++ b/MonoGame.Framework/Game.cs @@ -348,7 +348,7 @@ public void Run(GameRunBehavior runBehavior) } private DateTime _now; - private DateTime _lastUpdate = DateTime.Now; + private DateTime _lastUpdate = DateTime.UtcNow; private readonly GameTime _gameTime = new GameTime(); private readonly GameTime _fixedTimeStepTime = new GameTime(); private TimeSpan _totalTime = TimeSpan.Zero; @@ -357,7 +357,7 @@ public void Tick() { bool doDraw = false; - _now = DateTime.Now; + _now = DateTime.UtcNow; _gameTime.Update(_now - _lastUpdate); _lastUpdate = _now; @@ -398,7 +398,7 @@ public void Tick() if (IsFixedTimeStep) { - var currentTime = (DateTime.Now - _lastUpdate) + _totalTime; + var currentTime = (DateTime.UtcNow - _lastUpdate) + _totalTime; if (currentTime < TargetElapsedTime) { diff --git a/MonoGame.Framework/MacOS/Graphics/Texture2D.cs b/MonoGame.Framework/MacOS/Graphics/Texture2D.cs index bb63f94ff6a..561731a9423 100644 --- a/MonoGame.Framework/MacOS/Graphics/Texture2D.cs +++ b/MonoGame.Framework/MacOS/Graphics/Texture2D.cs @@ -610,10 +610,10 @@ public void GetData (int level, Rectangle? rect, T[] data, int startIndex, in { final[i] = (uint) ( - colors[i].R << 24 | - colors[i].G << 16 | - colors[i].B << 8 | - colors[i].A + colors[i].A << 24 | + colors[i].B << 16 | + colors[i].G << 8 | + colors[i].R ); } } diff --git a/MonoGame.Framework/Net/MonoGamerPeer.cs b/MonoGame.Framework/Net/MonoGamerPeer.cs index 29a2641d469..8079c620d96 100644 --- a/MonoGame.Framework/Net/MonoGamerPeer.cs +++ b/MonoGame.Framework/Net/MonoGamerPeer.cs @@ -646,7 +646,7 @@ internal static void Find (NetworkSessionType sessionType) netPeer.DiscoverLocalPeers (port); } - DateTime now = DateTime.Now; + DateTime now = DateTime.UtcNow; discoveryMsgs = new List (); @@ -682,7 +682,7 @@ internal static void Find (NetworkSessionType sessionType) break; } } - } while ((DateTime.Now - now).Seconds <= 2); + } while ((DateTime.UtcNow - now).Seconds <= 2); netPeer.Shutdown ("Find shutting down"); } diff --git a/MonoGame.Framework/PrimaryThreadLoader.cs b/MonoGame.Framework/PrimaryThreadLoader.cs index 7c2a175d538..3d45cc50972 100644 --- a/MonoGame.Framework/PrimaryThreadLoader.cs +++ b/MonoGame.Framework/PrimaryThreadLoader.cs @@ -19,7 +19,7 @@ internal static class PrimaryThreadLoader private static readonly object ListLockObject = new object(); private static readonly List NeedToLoad = new List(); private static readonly List RemoveList = new List(); - private static DateTime _lastUpdate = DateTime.Now; + private static DateTime _lastUpdate = DateTime.UtcNow; public static void AddToList(IPrimaryThreadLoaded primaryThreadLoaded) { @@ -61,9 +61,9 @@ public static void Clear() /// public static void DoLoads() { - if((DateTime.Now - _lastUpdate).Milliseconds < 250) return; + if((DateTime.UtcNow - _lastUpdate).Milliseconds < 250) return; - _lastUpdate = DateTime.Now; + _lastUpdate = DateTime.UtcNow; lock (ListLockObject) { for (int i = 0; i < NeedToLoad.Count; i++) diff --git a/MonoGame.Framework/iOS/Graphics/Texture2D.cs b/MonoGame.Framework/iOS/Graphics/Texture2D.cs index 6f1e779e157..8d1489073eb 100755 --- a/MonoGame.Framework/iOS/Graphics/Texture2D.cs +++ b/MonoGame.Framework/iOS/Graphics/Texture2D.cs @@ -445,10 +445,10 @@ public void GetData (int level, Rectangle? rect, T[] data, int startIndex, in { final[i] = (uint) ( - colors[i].R << 24 | - colors[i].G << 16 | - colors[i].B << 8 | - colors[i].A + colors[i].A << 24 | + colors[i].B << 16 | + colors[i].G << 8 | + colors[i].R ); } } From 529458fa4deac0da1161f97266f5a441b82a0f4e Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Sun, 17 Jun 2012 21:37:23 +0100 Subject: [PATCH 08/22] Updated version to 2.5.1.0 --- Installers/Windows/MonoGame.nsi | 2 +- MonoGame.Framework/Properties/AssemblyInfo.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Installers/Windows/MonoGame.nsi b/Installers/Windows/MonoGame.nsi index 5bb622c07db..ab0177ee547 100644 --- a/Installers/Windows/MonoGame.nsi +++ b/Installers/Windows/MonoGame.nsi @@ -2,7 +2,7 @@ SetCompressor /SOLID /FINAL lzma !define FrameworkPath "C:\Sandbox\MonoGame\" !define VERSION "2.5" -!define REVISION "0.0" +!define REVISION "1.0" !define INSTALLERFILENAME "MonoGame" !define APPNAME "MonoGame" diff --git a/MonoGame.Framework/Properties/AssemblyInfo.cs b/MonoGame.Framework/Properties/AssemblyInfo.cs index b41c8101466..e96897db071 100644 --- a/MonoGame.Framework/Properties/AssemblyInfo.cs +++ b/MonoGame.Framework/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.0")] +[assembly: AssemblyVersion("2.5.1.0")] +[assembly: AssemblyFileVersion("2.5.1.0")] From 829213be61f67f21e9594b61f314b8312152bd35 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Sun, 17 Jun 2012 21:58:05 +0100 Subject: [PATCH 09/22] Fixes to the Project Templates for the 2.5.1 release Fixed the installer to pick up the VS 2010 templates from the zip files --- Installers/Windows/MonoGame.nsi | 4 ++-- .../MonoDevelop.MonoGame/MonoDevelop.MonoGame.csproj | 5 ++--- .../templates/MonoGameWindowsProject.xpt.xml | 2 -- .../VS2010MGLinuxTemplate/MonoGameLinuxApplication.csproj | 2 -- .../MonoGameWindowsApplication.csproj | 2 -- 5 files changed, 4 insertions(+), 11 deletions(-) diff --git a/Installers/Windows/MonoGame.nsi b/Installers/Windows/MonoGame.nsi index ab0177ee547..05c698edfda 100644 --- a/Installers/Windows/MonoGame.nsi +++ b/Installers/Windows/MonoGame.nsi @@ -13,7 +13,7 @@ SetCompressor /SOLID /FINAL lzma !include "InstallOptions.nsh" Name '${APPNAME} ${VERSION} for MonoDevelop' -OutFile '${INSTALLERFILENAME}-${VERSION}.exe' +OutFile '${INSTALLERFILENAME}-${VERSION}.${REVISION}.exe' InstallDir '$PROGRAMFILES64\${APPNAME}' VIProductVersion "${VERSION}.${REVISION}" VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "${APPNAME} for MonoDevelop" @@ -124,7 +124,7 @@ Section "Visual Studio 2010 Templates" SetOutPath "$DOCUMENTS\Visual Studio 2010\Templates\ProjectTemplates\Visual C#\MonoGame" ; install the Templates for MonoDevelop - File /r '..\..\ProjectTemplates\VisualStudio2010.MonoGame.${VERSION}\*.*' + File /r '..\..\ProjectTemplates\VisualStudio2010.MonoGame.${VERSION}\*.zip' GOTO EndTemplates CannotInstallTemplates: diff --git a/ProjectTemplates/MonoDevelop.MonoGame.2.5/MonoDevelop.MonoGame/MonoDevelop.MonoGame/MonoDevelop.MonoGame.csproj b/ProjectTemplates/MonoDevelop.MonoGame.2.5/MonoDevelop.MonoGame/MonoDevelop.MonoGame/MonoDevelop.MonoGame.csproj index e55c61b4d85..7953607ea87 100644 --- a/ProjectTemplates/MonoDevelop.MonoGame.2.5/MonoDevelop.MonoGame/MonoDevelop.MonoGame/MonoDevelop.MonoGame.csproj +++ b/ProjectTemplates/MonoDevelop.MonoGame.2.5/MonoDevelop.MonoGame/MonoDevelop.MonoGame/MonoDevelop.MonoGame.csproj @@ -14,7 +14,7 @@ true full false - ..\..\ + bin\Release\ DEBUG; prompt 4 @@ -23,7 +23,7 @@ none false - ..\..\ + bin\Release\ prompt 4 false @@ -32,7 +32,6 @@ ..\..\..\..\..\..\Program Files %28x86%29\MonoDevelop\bin\MonoDevelop.Core.dll - monodevelop diff --git a/ProjectTemplates/MonoDevelop.MonoGame.2.5/templates/MonoGameWindowsProject.xpt.xml b/ProjectTemplates/MonoDevelop.MonoGame.2.5/templates/MonoGameWindowsProject.xpt.xml index cd60c8f581c..9e7d0630fdf 100644 --- a/ProjectTemplates/MonoDevelop.MonoGame.2.5/templates/MonoGameWindowsProject.xpt.xml +++ b/ProjectTemplates/MonoDevelop.MonoGame.2.5/templates/MonoGameWindowsProject.xpt.xml @@ -26,8 +26,6 @@ - - diff --git a/ProjectTemplates/VisualStudio2010.MonoGame.2.5/VS2010MGLinuxTemplate/MonoGameLinuxApplication.csproj b/ProjectTemplates/VisualStudio2010.MonoGame.2.5/VS2010MGLinuxTemplate/MonoGameLinuxApplication.csproj index 6e2321e5a0e..793db3fb91a 100644 --- a/ProjectTemplates/VisualStudio2010.MonoGame.2.5/VS2010MGLinuxTemplate/MonoGameLinuxApplication.csproj +++ b/ProjectTemplates/VisualStudio2010.MonoGame.2.5/VS2010MGLinuxTemplate/MonoGameLinuxApplication.csproj @@ -43,8 +43,6 @@ - - diff --git a/ProjectTemplates/VisualStudio2010.MonoGame.2.5/VS2010MGWindowsTemplate/MonoGameWindowsApplication.csproj b/ProjectTemplates/VisualStudio2010.MonoGame.2.5/VS2010MGWindowsTemplate/MonoGameWindowsApplication.csproj index b379878a27e..012a710dc12 100644 --- a/ProjectTemplates/VisualStudio2010.MonoGame.2.5/VS2010MGWindowsTemplate/MonoGameWindowsApplication.csproj +++ b/ProjectTemplates/VisualStudio2010.MonoGame.2.5/VS2010MGWindowsTemplate/MonoGameWindowsApplication.csproj @@ -43,8 +43,6 @@ - - From adf2a4de7c9ef00af5ecc897cd4d8856db0e93e3 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Mon, 18 Jun 2012 10:40:54 +0100 Subject: [PATCH 10/22] Reverted the RGBA -> ABGR change --- MonoGame.Framework/Android/Graphics/Texture2D.cs | 8 ++++---- MonoGame.Framework/MacOS/Graphics/Texture2D.cs | 8 ++++---- MonoGame.Framework/iOS/Graphics/Texture2D.cs | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/MonoGame.Framework/Android/Graphics/Texture2D.cs b/MonoGame.Framework/Android/Graphics/Texture2D.cs index 2079e2b1280..8255e8839a5 100644 --- a/MonoGame.Framework/Android/Graphics/Texture2D.cs +++ b/MonoGame.Framework/Android/Graphics/Texture2D.cs @@ -620,10 +620,10 @@ public void GetData(int level, Rectangle? rect, T[] data, int startIndex, int { final[i] = (uint) ( - colors[i].A << 24 | - colors[i].B << 16 | - colors[i].G << 8 | - colors[i].R + colors[i].R << 24 | + colors[i].G << 16 | + colors[i].B << 8 | + colors[i].A ); } } diff --git a/MonoGame.Framework/MacOS/Graphics/Texture2D.cs b/MonoGame.Framework/MacOS/Graphics/Texture2D.cs index 561731a9423..bb63f94ff6a 100644 --- a/MonoGame.Framework/MacOS/Graphics/Texture2D.cs +++ b/MonoGame.Framework/MacOS/Graphics/Texture2D.cs @@ -610,10 +610,10 @@ public void GetData (int level, Rectangle? rect, T[] data, int startIndex, in { final[i] = (uint) ( - colors[i].A << 24 | - colors[i].B << 16 | - colors[i].G << 8 | - colors[i].R + colors[i].R << 24 | + colors[i].G << 16 | + colors[i].B << 8 | + colors[i].A ); } } diff --git a/MonoGame.Framework/iOS/Graphics/Texture2D.cs b/MonoGame.Framework/iOS/Graphics/Texture2D.cs index 8d1489073eb..6f1e779e157 100755 --- a/MonoGame.Framework/iOS/Graphics/Texture2D.cs +++ b/MonoGame.Framework/iOS/Graphics/Texture2D.cs @@ -445,10 +445,10 @@ public void GetData (int level, Rectangle? rect, T[] data, int startIndex, in { final[i] = (uint) ( - colors[i].A << 24 | - colors[i].B << 16 | - colors[i].G << 8 | - colors[i].R + colors[i].R << 24 | + colors[i].G << 16 | + colors[i].B << 8 | + colors[i].A ); } } From 6db52ec64785387f0fffa0c3156161cbd2d950f5 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Mon, 18 Jun 2012 19:51:50 +0200 Subject: [PATCH 11/22] Update develop --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 84053e002ed..d9373b2ebfb 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ MonoGame is an OpenSource, OpenGL implementation of Microsoft's XNA 4 APIs that allows developers to build games that run on Android, iPhone, iPad, MacOS, Linux and soon PlayStation Suite and Windows Metro, all reusing their existing XNA code that runs on Xbox 360 or Windows Phone 7. # LATEST NEWS -v2.5 has been released and is now available for public consumption. +v2.5.1 has been released and is now available for public consumption. [Infinite Flight](http://itunes.apple.com/us/app/infinite-flight/id471341991?ls=1&mt=8), MonoGame's first 3D powered game, has been released. @@ -72,6 +72,8 @@ cadahl CircleOf14 vostok4 viyano +directhex +danzel [Team Xamarin](http://www.xamarin.com) for their support and continued great work on all things Mono and everyone else that submitted patches/fixes and enhancements. Without your contributions this release would not have been possible. From 165269a44676bcc1058751f8af3b5b5270d6e425 Mon Sep 17 00:00:00 2001 From: Jo Shields Date: Mon, 18 Jun 2012 20:00:54 +0100 Subject: [PATCH 12/22] Force build to use UTF-8 locale, otherwise build fails when it encounters UTF-8 characters when it hits UTF-8 characters in source. --- MonoGame.Framework/MonoGame.Framework.Linux.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/MonoGame.Framework/MonoGame.Framework.Linux.csproj b/MonoGame.Framework/MonoGame.Framework.Linux.csproj index 33a3e1a49f5..922ed8ef18a 100644 --- a/MonoGame.Framework/MonoGame.Framework.Linux.csproj +++ b/MonoGame.Framework/MonoGame.Framework.Linux.csproj @@ -7,6 +7,7 @@ 2.0 {35253CE1-C864-4CD3-8249-4D1319748E8F} Library + 65001 MonoGame.Framework.Linux MonoGame.Framework.Linux From 5365508771d846d589709d090b9d579d5098766c Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 20 Jun 2012 17:06:27 +0100 Subject: [PATCH 13/22] Updated the Android/AndroidGamePlatform.cs to take into account the emulator and use GL.Flush rather than swap buffers. --- .../Android/AndroidGamePlatform.cs | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/MonoGame.Framework/Android/AndroidGamePlatform.cs b/MonoGame.Framework/Android/AndroidGamePlatform.cs index ae02d6faae6..e9ab8c3e320 100644 --- a/MonoGame.Framework/Android/AndroidGamePlatform.cs +++ b/MonoGame.Framework/Android/AndroidGamePlatform.cs @@ -80,7 +80,9 @@ 1. Definitions using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Audio; -using Microsoft.Xna.Framework.Media; +using Microsoft.Xna.Framework.Media; + +using GL11 = OpenTK.Graphics.ES11.GL; namespace Microsoft.Xna.Framework { @@ -95,9 +97,13 @@ public AndroidGamePlatform(Game game) AndroidGameActivity.Resumed += Activity_Resumed; Window = new AndroidGameWindow(Game.Activity, game); + + string model = Android.OS.Build.Model; + runningOnEmulator = string.IsNullOrEmpty(model) ? false : model.Contains("sdk"); } private bool _initialized; + private bool runningOnEmulator = false; public static bool IsPlayingVdeo { get; set; } public override void Exit() @@ -230,8 +236,22 @@ public override void ResetElapsedTime () public override void Present() { try - { - Window.SwapBuffers(); + { + if (this.Window.GLContextVersion == OpenTK.Graphics.GLContextVersion.Gles2_0) + { + Window.SwapBuffers(); + } + else + { + if (!runningOnEmulator) + { + Window.SwapBuffers(); + } + else + { + GL11.Flush(); + } + } } catch (Exception ex) { From f8255dc90a21117ad91e9f87eba4c01ae6b398c6 Mon Sep 17 00:00:00 2001 From: Dominique Louis Date: Sat, 23 Jun 2012 19:16:08 +0100 Subject: [PATCH 14/22] back ported changes from develop3d's VertextBuffer changes to allow ParticleSample to build. --- .../Graphics/Vertices/DynamicVertexBuffer.cs | 12 ++-- .../Graphics/Vertices/VertexBuffer.cs | 70 ++++++++++--------- 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/MonoGame.Framework/Graphics/Vertices/DynamicVertexBuffer.cs b/MonoGame.Framework/Graphics/Vertices/DynamicVertexBuffer.cs index dd171cde143..5672c08406c 100644 --- a/MonoGame.Framework/Graphics/Vertices/DynamicVertexBuffer.cs +++ b/MonoGame.Framework/Graphics/Vertices/DynamicVertexBuffer.cs @@ -4,6 +4,10 @@ namespace Microsoft.Xna.Framework.Graphics { public class DynamicVertexBuffer : VertexBuffer { + internal int UserOffset; + + public bool IsContentLost { get { return false; } } + public DynamicVertexBuffer(GraphicsDevice graphics, Type type, int vertexCount, BufferUsage bufferUsage) : base(graphics, type, vertexCount, bufferUsage) { @@ -14,14 +18,14 @@ public DynamicVertexBuffer (GraphicsDevice graphics, VertexDeclaration vertexDec { } - public void SetData(T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct + public void SetData(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct { - throw new NotImplementedException(); + base.SetData(offsetInBytes, data, startIndex, elementCount, VertexDeclaration.VertexStride, options); } - public void SetData(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct + public void SetData(T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct { - throw new NotImplementedException(); + base.SetData(0, data, startIndex, elementCount, VertexDeclaration.VertexStride, options); } } } \ No newline at end of file diff --git a/MonoGame.Framework/Graphics/Vertices/VertexBuffer.cs b/MonoGame.Framework/Graphics/Vertices/VertexBuffer.cs index 0bf88dca751..6d4d9ec63ed 100644 --- a/MonoGame.Framework/Graphics/Vertices/VertexBuffer.cs +++ b/MonoGame.Framework/Graphics/Vertices/VertexBuffer.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Linq; +using System.Text; using System.Runtime.InteropServices; #if MONOMAC @@ -24,6 +26,7 @@ public class VertexBuffer : GraphicsResource internal uint _bufferStore; // TODO: Remove this VB limit! + internal uint vbo; internal static int _bufferCount; internal static VertexBuffer[] _allBuffers = new VertexBuffer[50]; internal static List _delayedBufferDelegates = new List(); @@ -95,46 +98,45 @@ internal static void CreateFrameBuffers () vertices[i] = tbuff[i]; } - public void SetData(T[] vertices) where T : struct + public void SetData(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride) where T : struct { - // TODO: This is fundimentally broken in that it is not - // assured that the incoming vertex array will exist unmodified - // long enough for the delayed buffer creation to occur. - // - // We either need to remove the concept of delayed buffer - // creation or copy the data here for safe keeping. - - //the creation of the buffer should mb be moved to the constructor and then glMapBuffer and Unmap should be used to update it - //glMapBuffer - sets data - //glUnmapBuffer - finished setting data - - _buffer = vertices; - _bufferPtr = GCHandle.Alloc(_buffer, GCHandleType.Pinned).AddrOfPinnedObject(); - - _bufferIndex = _bufferCount + 1; - _allBuffers[_bufferIndex] = this; - - _delayedBufferDelegates.Add(GenerateBuffer); - - _bufferCount++; - // TODO: Kill buffers in PhoneOSGameView.DestroyFrameBuffer() + SetData(0, data, startIndex, elementCount, VertexDeclaration.VertexStride, SetDataOptions.Discard); } + + public void SetData(T[] data, int startIndex, int elementCount) where T : struct + { + SetData(0, data, startIndex, elementCount, VertexDeclaration.VertexStride, SetDataOptions.Discard); + } - public void SetData (T[] data, int startIndex, int elementCount) where T : struct + public void SetData(T[] data) where T : struct { - throw new NotImplementedException(); + SetData(0, data, 0, data.Length, VertexDeclaration.VertexStride, SetDataOptions.Discard); } - public void SetData ( - int offsetInBytes, - T[] data, - int startIndex, - int elementCount, - int vertexStride - ) where T : struct - { - throw new NotImplementedException(); - } + protected void SetData(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options) where T : struct + { + if (data == null) + throw new ArgumentNullException("data is null"); + if (data.Length < (startIndex + elementCount)) + throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); + if ((vertexStride > (VertexCount * VertexDeclaration.VertexStride)) || (vertexStride < VertexDeclaration.VertexStride)) + throw new ArgumentOutOfRangeException("One of the following conditions is true:\nThe vertex stride is larger than the vertex buffer.\nThe vertex stride is too small for the type of data requested."); + + var elementSizeInBytes = Marshal.SizeOf(typeof(T)); + + //Threading.BlockOnUIThread(() => + //{ + var sizeInBytes = elementSizeInBytes * elementCount; +#if MONOMAC + GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); + GL.BufferSubData(BufferTarget.ArrayBuffer, new IntPtr(offsetInBytes), new IntPtr(sizeInBytes), data); +#else + GL11.BindBuffer(All11.ArrayBuffer, vbo); + GL11.BufferSubData(All11.ArrayBuffer, new IntPtr(offsetInBytes), new IntPtr(sizeInBytes), data); +#endif + + //}); + } public override void Dispose () { From 31cfc1a7e1f9045b8f50526b2ee8203c9dfe8ab8 Mon Sep 17 00:00:00 2001 From: Aranda Morrison Date: Tue, 3 Jul 2012 03:08:27 +0800 Subject: [PATCH 15/22] Much improved screen rotation support for Android. Works like Xna now. - OrientationListener improved and moved out of AndroidGameActivity.cs to it's own file to aid debugging. - Removed incorrect touch coordinate flipping for LandscapeRight - Support for rotating to reverse orientations when OS >= 2.3 - Correct handling of DisplayOrientation.Default (ie equivalent of LandscapeLeft | LandscapeRight) --- .../Android/AndroidGameActivity.cs | 56 +--- .../Android/AndroidGamePlatform.cs | 31 ++- .../Android/AndroidGameWindow.cs | 240 ++++++++---------- .../Android/OrientationListener.cs | 71 ++++++ MonoGame.Framework/DisplayOrientation.cs | 6 + MonoGame.Framework/GraphicsDeviceManager.cs | 1 + .../MonoGame.Framework.Android.csproj | 5 +- ThirdParty/Libs | 2 +- 8 files changed, 215 insertions(+), 197 deletions(-) create mode 100644 MonoGame.Framework/Android/OrientationListener.cs diff --git a/MonoGame.Framework/Android/AndroidGameActivity.cs b/MonoGame.Framework/Android/AndroidGameActivity.cs index 680d249506b..e69095218a9 100644 --- a/MonoGame.Framework/Android/AndroidGameActivity.cs +++ b/MonoGame.Framework/Android/AndroidGameActivity.cs @@ -45,7 +45,10 @@ protected override void OnPause() base.OnPause(); if (Paused != null) Paused(this, EventArgs.Empty); - Game.GraphicsDevice.ResourcesLost = true; + + if (Game.GraphicsDevice != null) + Game.GraphicsDevice.ResourcesLost = true; + if (Game.Window != null && Game.Window.Parent != null && (Game.Window.Parent is FrameLayout)) { ((FrameLayout)Game.Window.Parent).RemoveAllViews(); @@ -66,59 +69,8 @@ protected override void OnResume() Game.Window.RequestFocus(); Game.GraphicsDevice.Initialize(Game.Platform); } - } - internal class OrientationListener : OrientationEventListener - { - AndroidGameActivity activity; - - public OrientationListener(AndroidGameActivity activity) : base(activity, 1) - { - this.activity = activity; - } - - private bool inprogress = false; - - public override void OnOrientationChanged (int orientation) - { - if (!inprogress) - { - inprogress = true; - // Divide by 90 into an int to round, then multiply out to one of 5 positions, either 0,90,180,270,360. - int ort = (90*(int)Math.Round(orientation/90f)) % 360; - - // Convert 360 to 0 - if(ort == 360) - { - ort = 0; - } - - var disporientation = DisplayOrientation.Unknown; - - switch (ort) { - case 90 : disporientation = DisplayOrientation.LandscapeRight; - break; - case 270 : disporientation = DisplayOrientation.LandscapeLeft; - break; - case 0 : disporientation = DisplayOrientation.Portrait; - break; - default: - disporientation = DisplayOrientation.LandscapeLeft; - break; - } - - if (AndroidGameActivity.Game.Window.CurrentOrientation != disporientation) - { - AndroidGameActivity.Game.Window.SetOrientation(disporientation); - } - inprogress = false; - } - - - } - } - public static class ActivityExtensions { public static ActivityAttribute GetActivityAttribute(this AndroidGameActivity obj) diff --git a/MonoGame.Framework/Android/AndroidGamePlatform.cs b/MonoGame.Framework/Android/AndroidGamePlatform.cs index ae02d6faae6..f06ae3d8582 100644 --- a/MonoGame.Framework/Android/AndroidGamePlatform.cs +++ b/MonoGame.Framework/Android/AndroidGamePlatform.cs @@ -71,8 +71,8 @@ 1. Definitions using System.Linq; using System.Text; -using Android.App; -using Android.Content; +using Android.App; +using Android.Content; using Android.OS; using Android.Runtime; using Android.Views; @@ -140,18 +140,21 @@ public override bool BeforeDraw(GameTime gameTime) } public override void BeforeInitialize() - { - switch (Window.Context.Resources.Configuration.Orientation) - { - case Android.Content.Res.Orientation.Portrait: - Window.SetOrientation(DisplayOrientation.Portrait); - break; - case Android.Content.Res.Orientation.Landscape: - Window.SetOrientation(DisplayOrientation.LandscapeLeft); - break; - default: - Window.SetOrientation(DisplayOrientation.LandscapeLeft); - break; + { + // TODO: Determine whether device natural orientation is Portrait or Landscape for OrientationListener + //SurfaceOrientation currentOrient = Game.Activity.WindowManager.DefaultDisplay.Rotation; + + switch (Window.Context.Resources.Configuration.Orientation) + { + case Android.Content.Res.Orientation.Portrait: + Window.SetOrientation(DisplayOrientation.Portrait); + break; + case Android.Content.Res.Orientation.Landscape: + Window.SetOrientation(DisplayOrientation.LandscapeLeft); + break; + default: + Window.SetOrientation(DisplayOrientation.LandscapeLeft); + break; } base.BeforeInitialize(); } diff --git a/MonoGame.Framework/Android/AndroidGameWindow.cs b/MonoGame.Framework/Android/AndroidGameWindow.cs index 1758c52d89b..781586117f8 100644 --- a/MonoGame.Framework/Android/AndroidGameWindow.cs +++ b/MonoGame.Framework/Android/AndroidGameWindow.cs @@ -1,7 +1,7 @@ #region License /* Microsoft Public License (Ms-PL) -XnaTouch - Copyright © 2009 The XnaTouch Team +MonoGame - Copyright © 2009 The MonoGame Team All rights reserved. @@ -68,6 +68,7 @@ public class AndroidGameWindow : AndroidGameView , Android.Views.View.IOnTouchLi { private Rectangle clientBounds; private Game _game; + private DisplayOrientation supportedOrientations = DisplayOrientation.Default; private DisplayOrientation _currentOrientation; private GestureDetector gesture = null; @@ -196,120 +197,51 @@ protected override void OnRenderFrame(FrameEventArgs e) #endregion + internal void SetSupportedOrientations(DisplayOrientation orientations) + { + supportedOrientations = orientations; + } - internal void SetOrientation(DisplayOrientation currentorientation) + /// + /// In Xna, DisplayOrientation.Default has the same effect as (DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight) + /// + /// + internal DisplayOrientation GetEffectiveSupportedOrientations() { - var deviceManager = (GraphicsDeviceManager)_game.Services.GetService(typeof(IGraphicsDeviceManager)); - if (deviceManager == null) - return; + if (supportedOrientations == DisplayOrientation.Default) + { + return DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight; + } + else + { + return supportedOrientations; + } + } - // Calculate supported orientations if it has been left as "default" and only default - DisplayOrientation supportedOrientations = (deviceManager as GraphicsDeviceManager).SupportedOrientations; - var allowedOrientation = DisplayOrientation.LandscapeLeft; - if ((supportedOrientations == DisplayOrientation.Default)) - { - // if we have default only we only allow Landscape - allowedOrientation = allowedOrientation | DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight; - } - if ((supportedOrientations == DisplayOrientation.LandscapeLeft)) - { - // if we have default only we only allow Landscape - allowedOrientation = DisplayOrientation.LandscapeLeft; - } - if ((supportedOrientations & DisplayOrientation.LandscapeLeft) != 0) - { - // if we have default only we only allow Landscape - allowedOrientation = allowedOrientation | DisplayOrientation.LandscapeLeft; - } - if ((supportedOrientations == DisplayOrientation.LandscapeRight)) - { - // if we have default only we only allow Landscape - allowedOrientation = DisplayOrientation.LandscapeRight; - } - if ((supportedOrientations & DisplayOrientation.LandscapeRight) != 0) - { - // if we have default only we only allow Landscape - allowedOrientation = allowedOrientation | DisplayOrientation.LandscapeRight; - } - if ((supportedOrientations == DisplayOrientation.Portrait)) - { - // if we have Portrait only we only allow Landscape - allowedOrientation = DisplayOrientation.Portrait; - } - if ((supportedOrientations & DisplayOrientation.Portrait) != 0) - { - // if we have default only we only allow Landscape - allowedOrientation = allowedOrientation | DisplayOrientation.Portrait; - } + /// + /// Updates the screen orientation. Filters out requests for unsupported orientations. + /// + internal void SetOrientation(DisplayOrientation newOrientation) + { + DisplayOrientation supported = GetEffectiveSupportedOrientations(); - //What is this for? This does not allow the application to use landscapeleft. - //if (deviceManager.PreferredBackBufferSetByUser) - //{ - // if (_game.GraphicsDevice.PresentationParameters.BackBufferHeight < _game.GraphicsDevice.PresentationParameters.BackBufferWidth) - // { - // allowedOrientation = DisplayOrientation.LandscapeLeft; - // } - // if (_game.GraphicsDevice.PresentationParameters.BackBufferHeight > _game.GraphicsDevice.PresentationParameters.BackBufferWidth) - // { - // allowedOrientation = DisplayOrientation.Portrait; - // } - //} - - // ok we default to landscape left - var actualOrientation = DisplayOrientation.LandscapeLeft; - // now based on the orientation of the device we - // decide of we honour the device orientation or force our own - - // so if we are in Portrait but we allow only LandScape we stay in landscape - if (allowedOrientation == DisplayOrientation.Portrait) - { - actualOrientation = DisplayOrientation.Portrait; - } - else - if (allowedOrientation == DisplayOrientation.LandscapeLeft) - { - actualOrientation = DisplayOrientation.LandscapeLeft; - } - else - if (allowedOrientation == DisplayOrientation.LandscapeRight) - { - actualOrientation = DisplayOrientation.LandscapeRight; - } - else - if (_game.GraphicsDevice != null && _game.GraphicsDevice.PresentationParameters.BackBufferHeight < _game.GraphicsDevice.PresentationParameters.BackBufferWidth && deviceManager.PreferredBackBufferSetByUser) - { - actualOrientation = DisplayOrientation.LandscapeLeft; - } - else - if (_game.GraphicsDevice != null && _game.GraphicsDevice.PresentationParameters.BackBufferHeight > _game.GraphicsDevice.PresentationParameters.BackBufferWidth && deviceManager.PreferredBackBufferSetByUser) - { - actualOrientation = DisplayOrientation.Portrait; - } - - switch (currentorientation) { + // 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; + } - case DisplayOrientation.Portrait: - if ((allowedOrientation & DisplayOrientation.Portrait) != 0) { - actualOrientation = DisplayOrientation.Portrait; - } - break; - case DisplayOrientation.LandscapeRight: - if ((allowedOrientation & DisplayOrientation.LandscapeRight) != 0) { - actualOrientation = DisplayOrientation.LandscapeRight; - } - break; - case DisplayOrientation.LandscapeLeft: - default: - if ((allowedOrientation & DisplayOrientation.LandscapeLeft) != 0) { - actualOrientation = DisplayOrientation.LandscapeLeft; - } - break; + CurrentOrientation = newOrientation; + if (_game.GraphicsDevice != null) + { + _game.GraphicsDevice.PresentationParameters.DisplayOrientation = newOrientation; } - - - CurrentOrientation = actualOrientation; - _game.GraphicsDevice.PresentationParameters.DisplayOrientation = actualOrientation; - TouchPanel.DisplayOrientation = actualOrientation; + TouchPanel.DisplayOrientation = newOrientation; } private Dictionary _previousTouches = new Dictionary(); @@ -323,13 +255,6 @@ public bool OnTouch (View v, MotionEvent e) internal void UpdateTouchPosition(ref Vector2 position) { - if (this._game.Window.CurrentOrientation == DisplayOrientation.LandscapeRight) - { - // we need to fudge the position - position.X = this.Width - position.X; - position.Y = this.Height - position.Y; - } - //Fix for ClientBounds position.X -= ClientBounds.X; position.Y -= ClientBounds.Y; @@ -450,7 +375,26 @@ public bool AllowUserResizing // 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 @@ -461,18 +405,56 @@ private set { if (value != _currentOrientation) { - _currentOrientation = value; - - if (_currentOrientation == DisplayOrientation.Portrait || _currentOrientation == DisplayOrientation.PortraitUpsideDown) - { - Game.Activity.SetRequestedOrientation(ScreenOrientation.Portrait); - } - else if (_currentOrientation == DisplayOrientation.LandscapeLeft || _currentOrientation == DisplayOrientation.LandscapeRight) - { - Game.Activity.SetRequestedOrientation(ScreenOrientation.Landscape); - } - - if (OrientationChanged != null) + DisplayOrientation supported = GetEffectiveSupportedOrientations(); + + 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: + Game.Activity.RequestedOrientation = (ScreenOrientation)ScreenOrientationAll.Landscape; + break; + case DisplayOrientation.LandscapeRight: + Game.Activity.RequestedOrientation = (ScreenOrientation)ScreenOrientationAll.ReverseLandscape; + break; + case DisplayOrientation.Portrait: + Game.Activity.RequestedOrientation = (ScreenOrientation)ScreenOrientationAll.Portrait; + break; + case DisplayOrientation.PortraitUpsideDown: + Game.Activity.RequestedOrientation = (ScreenOrientation)ScreenOrientationAll.ReversePortrait; + 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; + Game.Activity.RequestedOrientation = ScreenOrientation.Landscape; + } + // 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; + Game.Activity.RequestedOrientation = ScreenOrientation.Portrait; + } + } + + if (didOrientationChange && OrientationChanged != null) { OrientationChanged(this, EventArgs.Empty); } diff --git a/MonoGame.Framework/Android/OrientationListener.cs b/MonoGame.Framework/Android/OrientationListener.cs new file mode 100644 index 00000000000..5197c0997e3 --- /dev/null +++ b/MonoGame.Framework/Android/OrientationListener.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.Hardware; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; + +namespace Microsoft.Xna.Framework +{ + internal class OrientationListener : OrientationEventListener + { + AndroidGameActivity activity; + private bool inprogress = false; + + /// + /// Constructor. SensorDelay.Ui is passed to the base class as this orientation listener + /// is just used for flipping the screen orientation, therefore high frequency data is not required. + /// + public OrientationListener(AndroidGameActivity activity) + : base(activity, SensorDelay.Ui) + { + this.activity = activity; + } + + public override void OnOrientationChanged(int orientation) + { + if (!inprogress) + { + inprogress = true; + // Divide by 90 into an int to round, then multiply out to one of 5 positions, either 0,90,180,270,360. + int ort = (90 * (int)Math.Round(orientation / 90f)) % 360; + + // Convert 360 to 0 + if (ort == 360) + { + ort = 0; + } + + var disporientation = DisplayOrientation.Unknown; + switch (ort) + { + case 90: disporientation = DisplayOrientation.LandscapeRight; + break; + case 270: disporientation = DisplayOrientation.LandscapeLeft; + break; + case 0: disporientation = DisplayOrientation.Portrait; + break; + case 180: disporientation = DisplayOrientation.PortraitUpsideDown; + break; + default: + disporientation = DisplayOrientation.LandscapeLeft; + break; + } + + // Only auto-rotate if target orientation is supported and not current + if ((AndroidGameActivity.Game.Window.GetEffectiveSupportedOrientations() & disporientation) != 0 && + disporientation != AndroidGameActivity.Game.Window.CurrentOrientation) + { + AndroidGameActivity.Game.Window.SetOrientation(disporientation); + } + inprogress = false; + } + } + } +} \ No newline at end of file diff --git a/MonoGame.Framework/DisplayOrientation.cs b/MonoGame.Framework/DisplayOrientation.cs index 1b75ea0c3ae..6321fa820da 100644 --- a/MonoGame.Framework/DisplayOrientation.cs +++ b/MonoGame.Framework/DisplayOrientation.cs @@ -45,6 +45,11 @@ namespace Microsoft.Xna.Framework [Flags] public enum DisplayOrientation { + /// + /// In Xna, this value is Default = 0. The effect of setting + /// GraphicsDeviceManager.SupportedOrientations = Default is the same as setting + /// GraphicsDeviceManager.SupportedOrientations = LandscapeLeft | LandscapeRight. + /// Default = 1, LandscapeLeft = 2, LandscapeRight = 4, @@ -52,6 +57,7 @@ public enum DisplayOrientation // iPhone specific Orientations FaceDown = 16, FaceUp = 32, + // Android can also use this orientation PortraitUpsideDown = 64, Unknown = 128, } diff --git a/MonoGame.Framework/GraphicsDeviceManager.cs b/MonoGame.Framework/GraphicsDeviceManager.cs index 21ff56458a1..4e820cd0330 100644 --- a/MonoGame.Framework/GraphicsDeviceManager.cs +++ b/MonoGame.Framework/GraphicsDeviceManager.cs @@ -286,6 +286,7 @@ public DisplayOrientation SupportedOrientations set { _supportedOrientations = value; + _game.Window.SetSupportedOrientations(_supportedOrientations); } } diff --git a/MonoGame.Framework/MonoGame.Framework.Android.csproj b/MonoGame.Framework/MonoGame.Framework.Android.csproj index d14a00cf5f7..fc68f901a5c 100644 --- a/MonoGame.Framework/MonoGame.Framework.Android.csproj +++ b/MonoGame.Framework/MonoGame.Framework.Android.csproj @@ -1,4 +1,4 @@ - + Debug @@ -56,6 +56,9 @@ + + + diff --git a/ThirdParty/Libs b/ThirdParty/Libs index 976e07a6179..8c008991bc0 160000 --- a/ThirdParty/Libs +++ b/ThirdParty/Libs @@ -1 +1 @@ -Subproject commit 976e07a617970ae80c24cb2533289a94b4f2788a +Subproject commit 8c008991bc01dd5db613c9b3a5b59713f1d1bb9f From bbd6a4e4f1675b074425d32f4cfa28fa53b4e210 Mon Sep 17 00:00:00 2001 From: Aranda Morrison Date: Wed, 4 Jul 2012 00:15:17 +0800 Subject: [PATCH 16/22] Remove unnecessary projection flip in SpriteBatch.cs and link SetSupportedOrientations --- MonoGame.Framework/Android/GraphicsDeviceManager.cs | 3 ++- MonoGame.Framework/Graphics/SpriteBatch.cs | 9 +-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/MonoGame.Framework/Android/GraphicsDeviceManager.cs b/MonoGame.Framework/Android/GraphicsDeviceManager.cs index 534ddad3eb5..4fc534d0974 100644 --- a/MonoGame.Framework/Android/GraphicsDeviceManager.cs +++ b/MonoGame.Framework/Android/GraphicsDeviceManager.cs @@ -353,7 +353,8 @@ public DisplayOrientation SupportedOrientations set { this._preferredBackBufferSetByUser = false; - _supportedOrientations = value; + _supportedOrientations = value; + _game.Window.SetSupportedOrientations(_supportedOrientations); } } diff --git a/MonoGame.Framework/Graphics/SpriteBatch.cs b/MonoGame.Framework/Graphics/SpriteBatch.cs index 84c24bbac81..95e4ac6bbac 100644 --- a/MonoGame.Framework/Graphics/SpriteBatch.cs +++ b/MonoGame.Framework/Graphics/SpriteBatch.cs @@ -507,14 +507,7 @@ private void UpdateWorldMatrixOrientation() matProjection = Matrix.CreateOrthographic(this.graphicsDevice.Viewport.Width, this.graphicsDevice.Viewport.Height, -1f,1f); - if (graphicsDevice.PresentationParameters.DisplayOrientation == DisplayOrientation.LandscapeRight) - { - // flip the viewport - matProjection = Matrix.CreateOrthographic(-this.graphicsDevice.Viewport.Width, - -this.graphicsDevice.Viewport.Height, - -1f,1f); - } - + matWVPScreen = _matrix * matViewScreen * matProjection; } From 3ac5120ead60c63a41998b319ff96b621429272d Mon Sep 17 00:00:00 2001 From: Aranda Morrison Date: Wed, 4 Jul 2012 00:15:17 +0800 Subject: [PATCH 17/22] Remove unnecessary projection flip in SpriteBatch.cs and link SetSupportedOrientations --- MonoGame.Framework/Android/GraphicsDeviceManager.cs | 3 ++- MonoGame.Framework/Graphics/SpriteBatch.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/MonoGame.Framework/Android/GraphicsDeviceManager.cs b/MonoGame.Framework/Android/GraphicsDeviceManager.cs index 534ddad3eb5..4fc534d0974 100644 --- a/MonoGame.Framework/Android/GraphicsDeviceManager.cs +++ b/MonoGame.Framework/Android/GraphicsDeviceManager.cs @@ -353,7 +353,8 @@ public DisplayOrientation SupportedOrientations set { this._preferredBackBufferSetByUser = false; - _supportedOrientations = value; + _supportedOrientations = value; + _game.Window.SetSupportedOrientations(_supportedOrientations); } } diff --git a/MonoGame.Framework/Graphics/SpriteBatch.cs b/MonoGame.Framework/Graphics/SpriteBatch.cs index 84c24bbac81..ffe8cdb6ff3 100644 --- a/MonoGame.Framework/Graphics/SpriteBatch.cs +++ b/MonoGame.Framework/Graphics/SpriteBatch.cs @@ -507,6 +507,7 @@ private void UpdateWorldMatrixOrientation() matProjection = Matrix.CreateOrthographic(this.graphicsDevice.Viewport.Width, this.graphicsDevice.Viewport.Height, -1f,1f); +#if !ANDROID if (graphicsDevice.PresentationParameters.DisplayOrientation == DisplayOrientation.LandscapeRight) { // flip the viewport @@ -514,7 +515,7 @@ private void UpdateWorldMatrixOrientation() -this.graphicsDevice.Viewport.Height, -1f,1f); } - +#endif matWVPScreen = _matrix * matViewScreen * matProjection; } From d217389009490e6a537c1bec458b05749633cea6 Mon Sep 17 00:00:00 2001 From: Aranda Morrison Date: Fri, 6 Jul 2012 22:39:30 +0800 Subject: [PATCH 18/22] Lock default orientation based on PreferredBackBuffer(Width/Height) GraphicsDeviceManager: - Set default preferred size to a landscape aspect ratio to cause it to default to landscape if the user does not set the preferred sizes - Removed calls to ResetClientBounds in setters for PreferredBackBuffer(Width/Height). Setting preferred buffer sizes should not have immediate effect. They are just stored for next device reset. AndroidGameWindow: - Use PreferredBackBuffer(Width/Height) to determine landscape vs portrait when handling SupportedOrientations == DisplayOrientation.Default. --- .../Android/AndroidGameWindow.cs | 17 ++++++- .../Android/GraphicsDeviceManager.cs | 45 ++++++++++--------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/MonoGame.Framework/Android/AndroidGameWindow.cs b/MonoGame.Framework/Android/AndroidGameWindow.cs index 980ca8d9312..f1d9856629e 100644 --- a/MonoGame.Framework/Android/AndroidGameWindow.cs +++ b/MonoGame.Framework/Android/AndroidGameWindow.cs @@ -203,14 +203,27 @@ internal void SetSupportedOrientations(DisplayOrientation orientations) } /// - /// In Xna, DisplayOrientation.Default has the same effect as (DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight) + /// In Xna, setting SupportedOrientations = DisplayOrientation.Default (which is the default value) + /// has the effect of setting SupporteOrientations to landscape only or portrait only, based on the + /// aspect ration of PreferredBackBufferWidth / PreferredBackBufferHeight /// /// internal DisplayOrientation GetEffectiveSupportedOrientations() { if (supportedOrientations == DisplayOrientation.Default) { - return DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight; + 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 { diff --git a/MonoGame.Framework/Android/GraphicsDeviceManager.cs b/MonoGame.Framework/Android/GraphicsDeviceManager.cs index 4fc534d0974..5719c329ee6 100644 --- a/MonoGame.Framework/Android/GraphicsDeviceManager.cs +++ b/MonoGame.Framework/Android/GraphicsDeviceManager.cs @@ -64,9 +64,12 @@ public GraphicsDeviceManager(Game game) throw new ArgumentNullException("Game Cannot Be Null"); } - _game = game; - _preferredBackBufferHeight = game.Window.ClientBounds.Height; - _preferredBackBufferWidth = game.Window.ClientBounds.Width; + _game = game; + + // Preferred buffer width/height is used to determine default supported orientations, + // so set the default values to match Xna behaviour of landscape only by default. + _preferredBackBufferWidth = Math.Max(game.Window.ClientBounds.Height, game.Window.ClientBounds.Width); + _preferredBackBufferHeight = Math.Min(game.Window.ClientBounds.Height, game.Window.ClientBounds.Width); _supportedOrientations = DisplayOrientation.Default; if (game.Services.GetService(typeof(IGraphicsDeviceManager)) != null) @@ -262,9 +265,8 @@ public int PreferredBackBufferHeight } set { - _preferredBackBufferSetByUser = true; - _preferredBackBufferHeight = value; - ResetClientBounds(); + _preferredBackBufferSetByUser = true; + _preferredBackBufferHeight = value; } } @@ -276,9 +278,8 @@ public int PreferredBackBufferWidth } set { - _preferredBackBufferSetByUser = true; - _preferredBackBufferWidth = value; - ResetClientBounds(); + _preferredBackBufferSetByUser = true; + _preferredBackBufferWidth = value; } } @@ -302,24 +303,24 @@ internal void ResetClientBounds() Game.Instance.Window.ClientBounds = newClientBounds; } else if (GraphicsDevice.DisplayMode.AspectRatio < aspectRatio) - { - var newClientBounds = new Rectangle(); - - newClientBounds.Width = GraphicsDevice.DisplayMode.Width; - newClientBounds.Height = (int)(newClientBounds.Width / aspectRatio); - newClientBounds.Y = (GraphicsDevice.DisplayMode.Height - newClientBounds.Height) / 2; - - Game.Instance.Window.ClientBounds = newClientBounds; - } + { + var newClientBounds = new Rectangle(); + + newClientBounds.Width = GraphicsDevice.DisplayMode.Width; + newClientBounds.Height = (int)(newClientBounds.Width / aspectRatio); + newClientBounds.Y = (GraphicsDevice.DisplayMode.Height - newClientBounds.Height) / 2; + + Game.Instance.Window.ClientBounds = newClientBounds; + } else { Game.Instance.Window.ClientBounds = new Rectangle(0, 0, _preferredBackBufferWidth, _preferredBackBufferHeight); - } + } } - else - { + else + { Game.Instance.Window.ClientBounds = new Rectangle(0, 0, GraphicsDevice.DisplayMode.Width, GraphicsDevice.DisplayMode.Height); - } + } } public DepthFormat PreferredDepthStencilFormat From ac0510948844fac2714606de4017e9a8a597ac77 Mon Sep 17 00:00:00 2001 From: Aranda Morrison Date: Sat, 7 Jul 2012 23:43:25 +0800 Subject: [PATCH 19/22] Fix interaction between screen orientation and manually specifying preferred back buffer size. - Fixed GraphicsDeviceManager.ResetClientBounds() to handle preferred back buffer size of different orientation to current display orientation - removed bool _preferredBackBufferSetByUser as GraphicsDeviceManager.ResetClientBounds() now correctly handles the case where it is not set by user --- .../Android/GraphicsDeviceManager.cs | 45 ++++++++----------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/MonoGame.Framework/Android/GraphicsDeviceManager.cs b/MonoGame.Framework/Android/GraphicsDeviceManager.cs index 5719c329ee6..438c4271453 100644 --- a/MonoGame.Framework/Android/GraphicsDeviceManager.cs +++ b/MonoGame.Framework/Android/GraphicsDeviceManager.cs @@ -54,8 +54,7 @@ public class GraphicsDeviceManager : IGraphicsDeviceService, IDisposable, IGraph private int _preferredBackBufferHeight; private int _preferredBackBufferWidth; private bool _preferMultiSampling; - private DisplayOrientation _supportedOrientations; - private bool _preferredBackBufferSetByUser = false; + private DisplayOrientation _supportedOrientations; public GraphicsDeviceManager(Game game) { @@ -190,11 +189,6 @@ public void ToggleFullScreen() IsFullScreen = !IsFullScreen; } - internal bool PreferredBackBufferSetByUser - { - get {return _preferredBackBufferSetByUser; } - } - public Microsoft.Xna.Framework.Graphics.GraphicsDevice GraphicsDevice { get @@ -265,7 +259,6 @@ public int PreferredBackBufferHeight } set { - _preferredBackBufferSetByUser = true; _preferredBackBufferHeight = value; } } @@ -278,49 +271,48 @@ public int PreferredBackBufferWidth } set { - _preferredBackBufferSetByUser = true; _preferredBackBufferWidth = value; } } internal void ResetClientBounds() - { - var clientBounds = Game.Instance.Window.ClientBounds; - - if (_preferredBackBufferSetByUser) - { + { + float preferredAspectRatio = (float)_preferredBackBufferWidth / (float)_preferredBackBufferHeight; + float displayAspectRatio = GraphicsDevice.DisplayMode.AspectRatio; - var aspectRatio = (float)_preferredBackBufferWidth/_preferredBackBufferHeight; + if ((preferredAspectRatio > 1.0f && displayAspectRatio < 1.0f) || + (preferredAspectRatio < 1.0f && displayAspectRatio > 1.0f)) + { + // Invert preferred aspect ratio if it's orientation differs from the display mode orientation. + // This occurs when user sets preferredBackBufferWidth/Height and also allows multiple supported orientations + preferredAspectRatio = 1.0f / preferredAspectRatio; + } - if (GraphicsDevice.DisplayMode.AspectRatio > aspectRatio) + const float EPSILON = 0.00001f; + if (displayAspectRatio > (preferredAspectRatio + EPSILON)) { var newClientBounds = new Rectangle(); newClientBounds.Height = GraphicsDevice.DisplayMode.Height; - newClientBounds.Width = (int) (newClientBounds.Height*aspectRatio); + newClientBounds.Width = (int) (newClientBounds.Height * preferredAspectRatio); newClientBounds.X = (GraphicsDevice.DisplayMode.Width - newClientBounds.Width)/2; Game.Instance.Window.ClientBounds = newClientBounds; } - else if (GraphicsDevice.DisplayMode.AspectRatio < aspectRatio) + else if (displayAspectRatio < (preferredAspectRatio - EPSILON)) { var newClientBounds = new Rectangle(); newClientBounds.Width = GraphicsDevice.DisplayMode.Width; - newClientBounds.Height = (int)(newClientBounds.Width / aspectRatio); + newClientBounds.Height = (int)(newClientBounds.Width / preferredAspectRatio); newClientBounds.Y = (GraphicsDevice.DisplayMode.Height - newClientBounds.Height) / 2; Game.Instance.Window.ClientBounds = newClientBounds; } else { - Game.Instance.Window.ClientBounds = new Rectangle(0, 0, _preferredBackBufferWidth, _preferredBackBufferHeight); - } - } - else - { - Game.Instance.Window.ClientBounds = new Rectangle(0, 0, GraphicsDevice.DisplayMode.Width, GraphicsDevice.DisplayMode.Height); - } + Game.Instance.Window.ClientBounds = new Rectangle(0, 0, GraphicsDevice.DisplayMode.Width, GraphicsDevice.DisplayMode.Height); + } } public DepthFormat PreferredDepthStencilFormat @@ -353,7 +345,6 @@ public DisplayOrientation SupportedOrientations } set { - this._preferredBackBufferSetByUser = false; _supportedOrientations = value; _game.Window.SetSupportedOrientations(_supportedOrientations); } From d8580704632486e8009ec77afd5bba8b8fcde6c0 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Mon, 9 Jul 2012 20:52:34 +0100 Subject: [PATCH 20/22] Added a DoExiting method to allow the Android Platform to raise the Exiting event Added ScreenReciever implementation --- .../Android/AndroidGameActivity.cs | 76 +++++++++++++++---- .../Android/AndroidGamePlatform.cs | 9 ++- .../Android/AndroidGameWindow.cs | 33 ++++++-- MonoGame.Framework/Android/ScreenReciever.cs | 33 ++++++++ MonoGame.Framework/Game.cs | 11 ++- .../MonoGame.Framework.Android.csproj | 3 +- .../Lidgren.Network.Android.csproj | 2 +- 7 files changed, 138 insertions(+), 29 deletions(-) create mode 100644 MonoGame.Framework/Android/ScreenReciever.cs diff --git a/MonoGame.Framework/Android/AndroidGameActivity.cs b/MonoGame.Framework/Android/AndroidGameActivity.cs index e69095218a9..bdc45d6b660 100644 --- a/MonoGame.Framework/Android/AndroidGameActivity.cs +++ b/MonoGame.Framework/Android/AndroidGameActivity.cs @@ -16,10 +16,18 @@ namespace Microsoft.Xna.Framework { public class AndroidGameActivity : Activity { - public static Game Game { get; set; } + public static Game Game { get; set; } private OrientationListener o; - + private ScreenReceiver screenReceiver; + + /// + /// OnCreate called when the activity is launched from cold or after the app + /// has been killed due to a higher priority app needing the memory + /// + /// + /// Saved instance state. + /// protected override void OnCreate (Bundle savedInstanceState) { base.OnCreate (savedInstanceState); @@ -27,7 +35,15 @@ protected override void OnCreate (Bundle savedInstanceState) if (o.CanDetectOrientation()) { o.Enable(); - } + } + + IntentFilter filter = new IntentFilter(); + filter.AddAction(Intent.ActionScreenOff); + filter.AddAction(Intent.ActionScreenOn); + filter.AddAction(Intent.ActionUserPresent); + + screenReceiver = new ScreenReceiver(); + RegisterReceiver(screenReceiver, filter); RequestWindowFeature(WindowFeatures.NoTitle); } @@ -39,36 +55,66 @@ public override void OnConfigurationChanged (Android.Content.Res.Configuration n // we need to refresh the viewport here. base.OnConfigurationChanged (newConfig); } - + + /// + /// Called when another app comes into the foreground or + /// if the screen is locked + /// protected override void OnPause() { - base.OnPause(); + base.OnPause(); if (Paused != null) Paused(this, EventArgs.Empty); - if (Game.GraphicsDevice != null) - Game.GraphicsDevice.ResourcesLost = true; + //if (Game.GraphicsDevice != null) + // Game.GraphicsDevice.ResourcesLost = true; - if (Game.Window != null && Game.Window.Parent != null && (Game.Window.Parent is FrameLayout)) - { - ((FrameLayout)Game.Window.Parent).RemoveAllViews(); - } + //if (Game.Window != null && Game.Window.Parent != null && (Game.Window.Parent is FrameLayout)) + //{ + // ((FrameLayout)Game.Window.Parent).RemoveAllViews(); + //} } public static event EventHandler Resumed; + + /// + /// Happens when the user returns to the activity + /// and when it first starts + /// protected override void OnResume() { - base.OnResume(); + base.OnResume(); if (Resumed != null) Resumed(this, EventArgs.Empty); var deviceManager = (IGraphicsDeviceManager)Game.Services.GetService(typeof(IGraphicsDeviceManager)); if (deviceManager == null) - return; + return; + (deviceManager as GraphicsDeviceManager).ForceSetFullScreen(); - Game.Window.RequestFocus(); - Game.GraphicsDevice.Initialize(Game.Platform); + //Game.Window.RequestFocus(); + //Game.GraphicsDevice.Initialize(Game.Platform); } + + protected override void OnStart () + { + base.OnStart (); + } + + protected override void OnStop () + { + base.OnStop (); + } + + protected override void OnDestroy () + { + base.OnDestroy (); + } + + protected override void OnRestart () + { + base.OnRestart (); + } } public static class ActivityExtensions diff --git a/MonoGame.Framework/Android/AndroidGamePlatform.cs b/MonoGame.Framework/Android/AndroidGamePlatform.cs index 032e0fd1518..f42c6b1ef4c 100644 --- a/MonoGame.Framework/Android/AndroidGamePlatform.cs +++ b/MonoGame.Framework/Android/AndroidGamePlatform.cs @@ -198,11 +198,13 @@ void Activity_Resumed(object sender, EventArgs e) { if (!IsActive) { - IsActive = true; + IsActive = true; Window.Resume(); Accelerometer.Resume(); Sound.ResumeAll(); MediaPlayer.Resume(); + if(!Window.IsFocused) + Window.RequestFocus(); } } @@ -211,8 +213,9 @@ void Activity_Paused(object sender, EventArgs e) { if (IsActive) { - IsActive = false; + IsActive = false; Window.Pause(); + Window.ClearFocus(); Accelerometer.Pause(); Sound.PauseAll(); MediaPlayer.Pause(); @@ -226,7 +229,7 @@ public override GameRunBehavior DefaultRunBehavior public override void Log(string Message) { -#if LOGGING +#if !LOGGING Android.Util.Log.Debug("MonoGameDebug", Message); #endif } diff --git a/MonoGame.Framework/Android/AndroidGameWindow.cs b/MonoGame.Framework/Android/AndroidGameWindow.cs index f1d9856629e..534affd8bf4 100644 --- a/MonoGame.Framework/Android/AndroidGameWindow.cs +++ b/MonoGame.Framework/Android/AndroidGameWindow.cs @@ -71,11 +71,12 @@ public class AndroidGameWindow : AndroidGameView , Android.Views.View.IOnTouchLi private DisplayOrientation supportedOrientations = DisplayOrientation.Default; private DisplayOrientation _currentOrientation; private GestureDetector gesture = null; + private bool exiting = false; public AndroidGameWindow(Context context, Game game) : base(context) { _game = game; - Initialize(); + Initialize(); } private void Initialize() @@ -97,15 +98,27 @@ public void ResetElapsedTime () } void GameWindow_Closed(object sender,EventArgs e) - { - try + { + if (!exiting) { - _game.Exit(); + exiting = true; + _game.DoExiting(); + } + try + { + _game.Exit(); } catch(NullReferenceException) { // just in case the game is null } + + } + + protected override void OnLoad (EventArgs e) + { + base.OnLoad (e); + MakeCurrent(); } public override bool OnKeyDown(Keycode keyCode, KeyEvent e) @@ -188,9 +201,17 @@ protected override void OnRenderFrame(FrameEventArgs e) if (!GraphicsContext.IsCurrent) MakeCurrent(); - if (_game != null ) //Only call draw if an update has occured + if (_game != null) { - _game.Tick(); + if ( _game.Platform.IsActive && !ScreenReceiver.ScreenLocked) //Only call draw if an update has occured + { + _game.Tick(); + } + else + { + _game.GraphicsDevice.Clear(Color.Black); + _game.GraphicsDevice.Present(); + } } } diff --git a/MonoGame.Framework/Android/ScreenReciever.cs b/MonoGame.Framework/Android/ScreenReciever.cs new file mode 100644 index 00000000000..27a4380bb76 --- /dev/null +++ b/MonoGame.Framework/Android/ScreenReciever.cs @@ -0,0 +1,33 @@ +using System; +using Android.Content; +using Microsoft.Xna.Framework.Media; + +namespace Microsoft.Xna.Framework +{ + internal class ScreenReceiver : BroadcastReceiver + { + public static bool ScreenLocked; + + public override void OnReceive(Context context, Intent intent) + { + Android.Util.Log.Info("MonoGameInfo", intent.Action.ToString()); + if(intent.Action == Intent.ActionScreenOff) + { + ScreenReceiver.ScreenLocked = true; + + MediaPlayer.IsMuted = true; + } + else if(intent.Action == Intent.ActionScreenOn) + { + MediaPlayer.IsMuted = true; + } + else if(intent.Action == Intent.ActionUserPresent) + { + ScreenReceiver.ScreenLocked = false; + + MediaPlayer.IsMuted = false; + } + } + } +} + diff --git a/MonoGame.Framework/Game.cs b/MonoGame.Framework/Game.cs index 5033d3d7a25..269a98bd63c 100644 --- a/MonoGame.Framework/Game.cs +++ b/MonoGame.Framework/Game.cs @@ -295,7 +295,7 @@ internal bool Initialized public void Exit() { - Platform.Exit(); + Platform.Exit(); } public void ResetElapsedTime() @@ -339,7 +339,7 @@ public void Run(GameRunBehavior runBehavior) case GameRunBehavior.Synchronous: Platform.RunLoop(); EndRun(); - OnExiting(this, EventArgs.Empty); + DoExiting(); break; default: throw new NotImplementedException(string.Format( @@ -512,7 +512,7 @@ private void Platform_AsyncRunLoopEnded(object sender, EventArgs e) var platform = (GamePlatform)sender; platform.AsyncRunLoopEnded -= Platform_AsyncRunLoopEnded; EndRun(); - OnExiting(this, EventArgs.Empty); + DoExiting(); } private void Platform_Activated(object sender, EventArgs e) @@ -588,6 +588,11 @@ internal void DoInitialize() Initialize(); } + internal void DoExiting() + { + OnExiting(this, EventArgs.Empty); + } + #if LINUX internal void ResizeWindow(bool changed) { diff --git a/MonoGame.Framework/MonoGame.Framework.Android.csproj b/MonoGame.Framework/MonoGame.Framework.Android.csproj index cc7895fe80f..8c05ef08056 100644 --- a/MonoGame.Framework/MonoGame.Framework.Android.csproj +++ b/MonoGame.Framework/MonoGame.Framework.Android.csproj @@ -41,7 +41,7 @@ false true SdkOnly - True + true @@ -368,6 +368,7 @@ + diff --git a/ThirdParty/Lidgren.Network/Lidgren.Network.Android.csproj b/ThirdParty/Lidgren.Network/Lidgren.Network.Android.csproj index 62b2371ff14..89be4e91708 100644 --- a/ThirdParty/Lidgren.Network/Lidgren.Network.Android.csproj +++ b/ThirdParty/Lidgren.Network/Lidgren.Network.Android.csproj @@ -37,7 +37,7 @@ false SdkOnly ANDROID - True + true From 5567f22ee6a2ff8b54668108e961f0075f8415f1 Mon Sep 17 00:00:00 2001 From: Timothy Parez Date: Sun, 29 Jul 2012 22:52:26 +0800 Subject: [PATCH 21/22] Added Texture2D.FromStream() as available in XNA4 http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.texture2d_members(v=xnagamestudio.40).aspx --- MonoGame.Framework/Linux/Graphics/Texture2D.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/MonoGame.Framework/Linux/Graphics/Texture2D.cs b/MonoGame.Framework/Linux/Graphics/Texture2D.cs index ae880469d51..3e71deb4164 100644 --- a/MonoGame.Framework/Linux/Graphics/Texture2D.cs +++ b/MonoGame.Framework/Linux/Graphics/Texture2D.cs @@ -258,6 +258,20 @@ public static Texture2D FromFile(GraphicsDevice graphicsDevice, string filename) return FromFile( graphicsDevice, filename, 0, 0 ); } + public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream) + { + var image = (Bitmap)Bitmap.FromStream(stream); + var theTexture = new ESImage(image, graphicsDevice.PreferedFilter); + var result = new Texture2D(theTexture); + return result; + } + + public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream, int width, int height, bool zoom) + { + // TODO resize + throw new NotImplementedException("Resizing not yet supported"); + } + private void generateOpenGLTexture () { // modeled after this From 3c3f8ba8fe69f7746eb1f829a04e3cd21632caba Mon Sep 17 00:00:00 2001 From: Timothy Parez Date: Mon, 30 Jul 2012 13:24:00 +0800 Subject: [PATCH 22/22] .FromStream now calls the .FromFile method I did not notice there was an overload with a stream already present. So now FromStream just calls that, for XNA 4 compatibility --- MonoGame.Framework/Linux/Graphics/Texture2D.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/MonoGame.Framework/Linux/Graphics/Texture2D.cs b/MonoGame.Framework/Linux/Graphics/Texture2D.cs index 3e71deb4164..623b291b793 100644 --- a/MonoGame.Framework/Linux/Graphics/Texture2D.cs +++ b/MonoGame.Framework/Linux/Graphics/Texture2D.cs @@ -260,10 +260,7 @@ public static Texture2D FromFile(GraphicsDevice graphicsDevice, string filename) public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream) { - var image = (Bitmap)Bitmap.FromStream(stream); - var theTexture = new ESImage(image, graphicsDevice.PreferedFilter); - var result = new Texture2D(theTexture); - return result; + return FromFile (graphicsDevice, stream); } public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream, int width, int height, bool zoom)