Example #1
0
 public override void EndScreenDeviceChange(
     string screenDeviceName,
     int clientWidth,
     int clientHeight
     )
 {
     FNAPlatform.ApplyWindowChanges(
         window,
         clientWidth,
         clientHeight,
         wantsFullscreen,
         screenDeviceName,
         ref deviceName
         );
 }
Example #2
0
        protected virtual void Dispose(bool disposing)
        {
            if (!_isDisposed)
            {
                if (disposing)
                {
                    // Dispose loaded game components.
                    for (int i = 0; i < _components.Count; i += 1)
                    {
                        IDisposable disposable = _components[i] as IDisposable;
                        if (disposable != null)
                        {
                            disposable.Dispose();
                        }
                    }
                    _components = null;

                    if (_content != null)
                    {
                        _content.Dispose();
                        _content = null;
                    }


                    if (_graphicsDeviceService != null)
                    {
                        // FIXME: Does XNA4 require the GDM to be disposable? -flibit
                        (_graphicsDeviceService as IDisposable).Dispose();
                        _graphicsDeviceService = null;
                    }

                    AudioDevice.Dispose();

                    if (Window != null)
                    {
                        FNAPlatform.DisposeWindow(Window);
                        Window = null;
                    }
                    Mouse.WindowHandle = IntPtr.Zero;

                    ContentTypeReaderManager.ClearTypeCreators();
                }

                AppDomain.CurrentDomain.UnhandledException -= OnUnhandledException;

                _isDisposed = true;
            }
        }
Example #3
0
        public Game()
        {
            AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;

            LaunchParameters = new LaunchParameters();
            _services        = new GameServiceContainer();
            _components      = new GameComponentCollection();
            _content         = new ContentManager(_services);

            Window = FNAPlatform.CreateWindow();

            AudioDevice.Initialize();

            // Ready to run the loop!
            RunApplication = true;
        }
Example #4
0
        internal static IntPtr ReadToPointer(string name, out IntPtr size)
        {
            string safeName = MonoGame.Utilities.FileHelpers.NormalizeFilePathSeparators(name);

#if CASE_SENSITIVITY_HACK
            if (Path.IsPathRooted(safeName))
            {
                safeName = GetCaseName(safeName);
            }
            safeName = GetCaseName(Path.Combine(TitleLocation.Path, safeName));
#endif
            if (Path.IsPathRooted(safeName))
            {
                return(FNAPlatform.ReadFileToPointer(safeName, out size));
            }
            return(FNAPlatform.ReadFileToPointer(Path.Combine(TitleLocation.Path, safeName), out size));
        }
Example #5
0
        public void RunOneFrame()
        {
            if (!hasInitialized)
            {
                DoInitialize();
                gameTimer      = Stopwatch.StartNew();
                hasInitialized = true;
            }

            FNAPlatform.PollEvents(
                this,
                ref currentAdapter,
                textInputControlDown,
                textInputControlRepeat,
                ref textInputSuppress
                );
            Tick();
        }
Example #6
0
        public void Run()
        {
            AssertNotDisposed();

            if (!hasInitialized)
            {
                DoInitialize();
                hasInitialized = true;
            }

            BeginRun();
            gameTimer = Stopwatch.StartNew();

            FNAPlatform.RunLoop(this);

            EndRun();

            OnExiting(this, EventArgs.Empty);
        }
Example #7
0
        private void INTERNAL_OnClientSizeChanged(object sender, EventArgs e)
        {
            GameWindow window = (sender as GameWindow);

            Rectangle size = window.ClientBounds;

            resizedBackBufferWidth  = size.Width;
            resizedBackBufferHeight = size.Height;

            FNAPlatform.ScaleForWindow(
                window.Handle,
                true,
                ref resizedBackBufferWidth,
                ref resizedBackBufferHeight
                );

            useResizedBackBuffer = true;
            ApplyChanges();
        }
Example #8
0
        public Game()
        {
            AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;

            LaunchParameters = new LaunchParameters();
            Components       = new GameComponentCollection();
            Services         = new GameServiceContainer();
            Content          = new ContentManager(Services);

            updateableComponents        = new List <IUpdateable>();
            currentlyUpdatingComponents = new List <IUpdateable>();
            drawableComponents          = new List <IDrawable>();
            currentlyDrawingComponents  = new List <IDrawable>();

            IsMouseVisible    = false;
            IsFixedTimeStep   = true;
            TargetElapsedTime = TimeSpan.FromTicks(166667);             // 60fps
            InactiveSleepTime = TimeSpan.FromSeconds(0.02);
            for (int i = 0; i < previousSleepTimes.Length; i += 1)
            {
                previousSleepTimes[i] = TimeSpan.FromMilliseconds(1);
            }

            textInputControlDown   = new bool[FNAPlatform.TextInputCharacters.Length];
            textInputControlRepeat = new int[FNAPlatform.TextInputCharacters.Length];

            hasInitialized = false;
            suppressDraw   = false;
            isDisposed     = false;

            gameTime = new GameTime();

            Window                  = FNAPlatform.CreateWindow();
            Mouse.WindowHandle      = Window.Handle;
            TouchPanel.WindowHandle = Window.Handle;

            FrameworkDispatcher.Update();

            // Ready to run the loop!
            RunApplication = true;
        }
Example #9
0
        public override void EndScreenDeviceChange(
            string screenDeviceName,
            int clientWidth,
            int clientHeight
            )
        {
            string prevName = deviceName;

            FNAPlatform.ApplyWindowChanges(
                window,
                clientWidth,
                clientHeight,
                wantsFullscreen,
                screenDeviceName,
                ref deviceName
                );
            if (deviceName != prevName)
            {
                OnScreenDeviceNameChanged();
            }
        }
Example #10
0
        protected virtual void Dispose(bool disposing)
        {
            if (!isDisposed)
            {
                if (disposing)
                {
                    // Dispose loaded game components.
                    for (int i = 0; i < Components.Count; i += 1)
                    {
                        IDisposable disposable = Components[i] as IDisposable;
                        if (disposable != null)
                        {
                            disposable.Dispose();
                        }
                    }

                    if (Content != null)
                    {
                        Content.Dispose();
                    }

                    if (graphicsDeviceService != null)
                    {
                        // FIXME: Does XNA4 require the GDM to be disposable? -flibit
                        (graphicsDeviceService as IDisposable).Dispose();
                    }

                    if (Window != null)
                    {
                        FNAPlatform.DisposeWindow(Window);
                    }

                    ContentTypeReaderManager.ClearTypeCreators();
                }

                AppDomain.CurrentDomain.UnhandledException -= OnUnhandledException;

                isDisposed = true;
            }
        }
Example #11
0
        private void RunLoop()
        {
            /* Some platforms (i.e. Emscripten) don't support
             * indefinite while loops, so instead we have to
             * surrender control to the platform's main loop.
             * -caleb
             */
            if (FNAPlatform.NeedsPlatformMainLoop())
            {
                /* This breaks control flow and jumps
                 * directly into the platform main loop.
                 * Nothing below this call will be executed.
                 */
                FNAPlatform.RunPlatformMainLoop(this);
            }

            while (RunApplication)
            {
                Tick();
            }
            OnExiting(this, EventArgs.Empty);
        }
Example #12
0
        public void Run()
        {
            AssertNotDisposed();

            if (!hasInitialized)
            {
                GameSubThread.Setup(this);
                GameSubThread.Instance.ScheduleWait(DoInitialize);
                hasInitialized = true;
            }

            BeginRun();
            gameTimer = Stopwatch.StartNew();

            FNAPlatform.RunLoop(this);

            GameSubThread.Abort();

            EndRun();

            OnExiting(this, EventArgs.Empty);
        }
Example #13
0
        public Game(string rootDir)
        {
            AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;

            RootDirectory = rootDir;

            LaunchParameters = new LaunchParameters();
            Components       = new GameComponentCollection();
            Services         = new GameServiceContainer();
            Content          = new ContentManager(Services);

            updateableComponents        = new List <IUpdateable>();
            currentlyUpdatingComponents = new List <IUpdateable>();
            drawableComponents          = new List <IDrawable>();
            currentlyDrawingComponents  = new List <IDrawable>();

            IsMouseVisible    = false;
            IsFixedTimeStep   = true;
            TargetElapsedTime = TimeSpan.FromTicks(166667);             // 60fps
            InactiveSleepTime = TimeSpan.FromSeconds(0.02);

            hasInitialized = false;
            suppressDraw   = false;
            isDisposed     = false;

            gameTime = new GameTime();

            Window                  = FNAPlatform.CreateWindow();
            Mouse.WindowHandle      = Window.Handle;
            TouchPanel.WindowHandle = Window.Handle;

            FrameworkDispatcher.Update();
            Renderer = new Renderer(this);

            // Ready to run the loop!
            RunApplication = true;
        }
Example #14
0
 protected virtual bool ShowMissingRequirementMessage(Exception exception)
 {
     if (exception is NoAudioHardwareException)
     {
         FNAPlatform.ShowRuntimeError(
             Window.Title,
             "Could not find a suitable audio device. " +
             " Verify that a sound card is\ninstalled," +
             " and check the driver properties to make" +
             " sure it is not disabled."
             );
         return(true);
     }
     if (exception is NoSuitableGraphicsDeviceException)
     {
         FNAPlatform.ShowRuntimeError(
             Window.Title,
             "Could not find a suitable graphics device." +
             " More information:\n\n" + exception.Message
             );
         return(true);
     }
     return(false);
 }
Example #15
0
        public void ApplyChanges()
        {
            // Calling ApplyChanges() before CreateDevice() should have no effect.
            if (graphicsDevice == null)
            {
                return;
            }

            // Recreate device information before resetting
            GraphicsDeviceInformation gdi = new GraphicsDeviceInformation();

            gdi.Adapter                = GraphicsDevice.Adapter;
            gdi.GraphicsProfile        = GraphicsDevice.GraphicsProfile;
            gdi.PresentationParameters = GraphicsDevice.PresentationParameters.Clone();

            /* Apply the GraphicsDevice changes to the new Parameters.
             * Note that PreparingDeviceSettings can override any of these!
             * -flibit
             */
            gdi.PresentationParameters.BackBufferFormat =
                PreferredBackBufferFormat;
            if (useResizedBackBuffer)
            {
                gdi.PresentationParameters.BackBufferWidth =
                    resizedBackBufferWidth;
                gdi.PresentationParameters.BackBufferHeight =
                    resizedBackBufferHeight;
                useResizedBackBuffer = false;
            }
            else
            {
                gdi.PresentationParameters.BackBufferWidth =
                    PreferredBackBufferWidth;
                gdi.PresentationParameters.BackBufferHeight =
                    PreferredBackBufferHeight;
            }
            gdi.PresentationParameters.DepthStencilFormat =
                PreferredDepthStencilFormat;
            gdi.PresentationParameters.IsFullScreen =
                IsFullScreen;
            if (!PreferMultiSampling)
            {
                gdi.PresentationParameters.MultiSampleCount = 0;
            }
            else if (gdi.PresentationParameters.MultiSampleCount == 0)
            {
                /* XNA4 seems to have an upper limit of 8, but I'm willing to
                 * limit this only in GraphicsDeviceManager's default setting.
                 * If you want even higher values, Reset() with a custom value.
                 * -flibit
                 */
                gdi.PresentationParameters.MultiSampleCount = Math.Min(
                    GraphicsDevice.GLDevice.MaxMultiSampleCount,
                    8
                    );
            }

            // Give the user a chance to override the above settings.
            OnPreparingDeviceSettings(
                this,
                new PreparingDeviceSettingsEventArgs(gdi)
                );

            // Reset!
            game.Window.BeginScreenDeviceChange(
                gdi.PresentationParameters.IsFullScreen
                );
            game.Window.EndScreenDeviceChange(
                gdi.Adapter.DeviceName,
                gdi.PresentationParameters.BackBufferWidth,
                gdi.PresentationParameters.BackBufferHeight
                );
            // FIXME: This should be before EndScreenDeviceChange! -flibit
            GraphicsDevice.Reset(
                gdi.PresentationParameters,
                gdi.Adapter
                );

            // Apply the PresentInterval.
            FNAPlatform.SetPresentationInterval(
                SynchronizeWithVerticalRetrace ?
                gdi.PresentationParameters.PresentationInterval :
                PresentInterval.Immediate
                );
        }
Example #16
0
        public void Tick()
        {
            /* NOTE: This code is very sensitive and can break very badly,
             * even with what looks like a safe change. Be sure to test
             * any change fully in both the fixed and variable timestep
             * modes across multiple devices and platforms.
             */

            AdvanceElapsedTime();

            if (IsFixedTimeStep)
            {
                /* If we are in fixed timestep, we want to wait until the next frame,
                 * but we don't want to oversleep. Requesting repeated 1ms sleeps and
                 * seeing how long we actually slept for lets us estimate the worst case
                 * sleep precision so we don't oversleep the next frame.
                 */
                while (accumulatedElapsedTime + worstCaseSleepPrecision < TargetElapsedTime)
                {
                    System.Threading.Thread.Sleep(1);
                    TimeSpan timeAdvancedSinceSleeping = AdvanceElapsedTime();
                    UpdateEstimatedSleepPrecision(timeAdvancedSinceSleeping);
                }

                /* Now that we have slept into the sleep precision threshold, we need to wait
                 * for just a little bit longer until the target elapsed time has been reached.
                 * SpinWait(1) works by pausing the thread for very short intervals, so it is
                 * an efficient and time-accurate way to wait out the rest of the time.
                 */
                while (accumulatedElapsedTime < TargetElapsedTime)
                {
                    System.Threading.Thread.SpinWait(1);
                    AdvanceElapsedTime();
                }
            }

            // Now that we are going to perform an update, let's poll events.
            FNAPlatform.PollEvents(
                this,
                ref currentAdapter,
                textInputControlDown,
                textInputControlRepeat,
                ref textInputSuppress
                );

            // Do not allow any update to take longer than our maximum.
            if (accumulatedElapsedTime > MaxElapsedTime)
            {
                accumulatedElapsedTime = MaxElapsedTime;
            }

            if (IsFixedTimeStep)
            {
                gameTime.ElapsedGameTime = TargetElapsedTime;
                int stepCount = 0;

                // Perform as many full fixed length time steps as we can.
                while (accumulatedElapsedTime >= TargetElapsedTime)
                {
                    gameTime.TotalGameTime += TargetElapsedTime;
                    accumulatedElapsedTime -= TargetElapsedTime;
                    stepCount += 1;

                    AssertNotDisposed();
                    Update(gameTime);
                }

                // Every update after the first accumulates lag
                updateFrameLag += Math.Max(0, stepCount - 1);

                /* If we think we are running slowly, wait
                 * until the lag clears before resetting it
                 */
                if (gameTime.IsRunningSlowly)
                {
                    if (updateFrameLag == 0)
                    {
                        gameTime.IsRunningSlowly = false;
                    }
                }
                else if (updateFrameLag >= 5)
                {
                    /* If we lag more than 5 frames,
                     * start thinking we are running slowly.
                     */
                    gameTime.IsRunningSlowly = true;
                }

                /* Every time we just do one update and one draw,
                 * then we are not running slowly, so decrease the lag.
                 */
                if (stepCount == 1 && updateFrameLag > 0)
                {
                    updateFrameLag -= 1;
                }

                /* Draw needs to know the total elapsed time
                 * that occured for the fixed length updates.
                 */
                gameTime.ElapsedGameTime = TimeSpan.FromTicks(TargetElapsedTime.Ticks * stepCount);
            }
            else
            {
                // Perform a single variable length update.
                if (forceElapsedTimeToZero)
                {
                    /* When ResetElapsedTime is called,
                     * Elapsed is forced to zero and
                     * Total is ignored entirely.
                     * -flibit
                     */
                    gameTime.ElapsedGameTime = TimeSpan.Zero;
                    forceElapsedTimeToZero   = false;
                }
                else
                {
                    gameTime.ElapsedGameTime = accumulatedElapsedTime;
                    gameTime.TotalGameTime  += gameTime.ElapsedGameTime;
                }

                accumulatedElapsedTime = TimeSpan.Zero;
                AssertNotDisposed();
                Update(gameTime);
            }

            // Draw unless the update suppressed it.
            if (suppressDraw)
            {
                suppressDraw = false;
            }
            else
            {
                /* Draw/EndDraw should not be called if BeginDraw returns false.
                 * http://stackoverflow.com/questions/4054936/manual-control-over-when-to-redraw-the-screen/4057180#4057180
                 * http://stackoverflow.com/questions/4235439/xna-3-1-to-4-0-requires-constant-redraw-or-will-display-a-purple-screen
                 */
                if (BeginDraw())
                {
                    Draw(gameTime);
                    EndDraw();
                }
            }
        }
Example #17
0
 static TitleLocation()
 {
     Path = FNAPlatform.GetBaseDirectory();
 }
Example #18
0
 private void AfterLoop()
 {
     FNAPlatform.UnregisterGame(this);
 }
Example #19
0
 protected override void SetTitle(string title)
 {
     FNAPlatform.SetWindowTitle(window, title);
 }
Example #20
0
        public void ApplyChanges()
        {
            /* Calling ApplyChanges() before CreateDevice() forces CreateDevice.
             * We can then return early since CreateDevice will call this again!
             * -flibit
             */
            if (graphicsDevice == null)
            {
                (this as IGraphicsDeviceManager).CreateDevice();
                return;
            }

            // ApplyChanges() calls with no actual changes should be ignored.
            if (!prefsChanged && !useResizedBackBuffer)
            {
                return;
            }

            // Recreate device information before resetting
            GraphicsDeviceInformation gdi = new GraphicsDeviceInformation();

            gdi.Adapter                = graphicsDevice.Adapter;
            gdi.GraphicsProfile        = graphicsDevice.GraphicsProfile;
            gdi.PresentationParameters = graphicsDevice.PresentationParameters.Clone();

            bool supportsOrientations = FNAPlatform.SupportsOrientationChanges();

            /* Apply the GraphicsDevice changes to the new Parameters.
             * Note that PreparingDeviceSettings can override any of these!
             * -flibit
             */
            gdi.PresentationParameters.BackBufferFormat =
                PreferredBackBufferFormat;
            if (useResizedBackBuffer)
            {
                gdi.PresentationParameters.BackBufferWidth =
                    resizedBackBufferWidth;
                gdi.PresentationParameters.BackBufferHeight =
                    resizedBackBufferHeight;
                useResizedBackBuffer = false;
            }
            else
            {
                if (!supportsOrientations)
                {
                    gdi.PresentationParameters.BackBufferWidth =
                        PreferredBackBufferWidth;
                    gdi.PresentationParameters.BackBufferHeight =
                        PreferredBackBufferHeight;
                }
                else
                {
                    /* Flip the backbuffer dimensions to scale
                     * appropriately to the current orientation.
                     */
                    int min = Math.Min(PreferredBackBufferWidth, PreferredBackBufferHeight);
                    int max = Math.Max(PreferredBackBufferWidth, PreferredBackBufferHeight);

                    if (gdi.PresentationParameters.DisplayOrientation == DisplayOrientation.Portrait)
                    {
                        gdi.PresentationParameters.BackBufferWidth  = min;
                        gdi.PresentationParameters.BackBufferHeight = max;
                    }
                    else
                    {
                        gdi.PresentationParameters.BackBufferWidth  = max;
                        gdi.PresentationParameters.BackBufferHeight = min;
                    }
                }
            }
            gdi.PresentationParameters.DepthStencilFormat =
                PreferredDepthStencilFormat;
            gdi.PresentationParameters.IsFullScreen =
                IsFullScreen;
            gdi.PresentationParameters.PresentationInterval =
                SynchronizeWithVerticalRetrace ?
                PresentInterval.One :
                PresentInterval.Immediate;
            if (!PreferMultiSampling)
            {
                gdi.PresentationParameters.MultiSampleCount = 0;
            }
            else if (gdi.PresentationParameters.MultiSampleCount == 0)
            {
                /* XNA4 seems to have an upper limit of 8, but I'm willing to
                 * limit this only in GraphicsDeviceManager's default setting.
                 * If you want even higher values, Reset() with a custom value.
                 * -flibit
                 */
                gdi.PresentationParameters.MultiSampleCount = Math.Min(
                    graphicsDevice.GLDevice.MaxMultiSampleCount,
                    8
                    );
            }

            // Give the user a chance to override the above settings.
            OnPreparingDeviceSettings(
                this,
                new PreparingDeviceSettingsEventArgs(gdi)
                );

            // Reset!
            if (supportsOrientations)
            {
                game.Window.SetSupportedOrientations(
                    INTERNAL_supportedOrientations
                    );
            }
            game.Window.BeginScreenDeviceChange(
                gdi.PresentationParameters.IsFullScreen
                );
            game.Window.EndScreenDeviceChange(
                gdi.Adapter.DeviceName,
                gdi.PresentationParameters.BackBufferWidth,
                gdi.PresentationParameters.BackBufferHeight
                );
            // FIXME: This should be before EndScreenDeviceChange! -flibit
            graphicsDevice.Reset(
                gdi.PresentationParameters,
                gdi.Adapter
                );
            prefsChanged = false;
        }