public override void EndScreenDeviceChange( string screenDeviceName, int clientWidth, int clientHeight ) { FNAPlatform.ApplyWindowChanges( window, clientWidth, clientHeight, wantsFullscreen, screenDeviceName, ref deviceName ); }
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; } }
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; }
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)); }
public void RunOneFrame() { if (!hasInitialized) { DoInitialize(); gameTimer = Stopwatch.StartNew(); hasInitialized = true; } FNAPlatform.PollEvents( this, ref currentAdapter, textInputControlDown, textInputControlRepeat, ref textInputSuppress ); Tick(); }
public void Run() { AssertNotDisposed(); if (!hasInitialized) { DoInitialize(); hasInitialized = true; } BeginRun(); gameTimer = Stopwatch.StartNew(); FNAPlatform.RunLoop(this); EndRun(); OnExiting(this, EventArgs.Empty); }
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(); }
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; }
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(); } }
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; } }
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); }
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); }
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; }
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); }
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 ); }
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(); } } }
static TitleLocation() { Path = FNAPlatform.GetBaseDirectory(); }
private void AfterLoop() { FNAPlatform.UnregisterGame(this); }
protected override void SetTitle(string title) { FNAPlatform.SetWindowTitle(window, title); }
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; }