153 lines
5.7 KiB
C#
153 lines
5.7 KiB
C#
using Microsoft.Win32.SafeHandles;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using RecrownedAthenaeum.Camera;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace RecrownedAthenaeum.ScreenSystem
|
|
{
|
|
public delegate void FirstScreenChange(Screen screen);
|
|
|
|
public class ScreenManager : IDisposable
|
|
{
|
|
bool disposed = false;
|
|
|
|
public event FirstScreenChange RequireNextScreenEvent;
|
|
private GraphicsDeviceManager graphics;
|
|
private Screen previousScreen;
|
|
private RenderTarget2D previousScreenRenderTarget;
|
|
private Screen currentScreen;
|
|
private Camera2D camera;
|
|
private bool firstScreenChangeComplete;
|
|
public Screen Screen
|
|
{
|
|
get
|
|
{
|
|
return currentScreen;
|
|
}
|
|
set
|
|
{
|
|
previousScreen = currentScreen;
|
|
currentScreen = value;
|
|
if (!Screen.Initiated)
|
|
{
|
|
Screen.Initiate(graphics.GraphicsDevice, new Rectangle(0, 0, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight), camera);
|
|
}
|
|
if (previousScreen != null && previousScreenRenderTarget == null && previousScreen.UseRenderTargetForExitTransition)
|
|
{
|
|
previousScreenRenderTarget = new RenderTarget2D(graphics.GraphicsDevice, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);
|
|
}
|
|
graphics.GraphicsDevice.SetRenderTarget(previousScreenRenderTarget);
|
|
graphics.GraphicsDevice.Clear(Color.Black);
|
|
|
|
Debug.WriteLine("Showing " + value.GetType().Name);
|
|
Screen.Show();
|
|
previousScreen?.Hide();
|
|
}
|
|
}
|
|
|
|
public ScreenManager(GraphicsDeviceManager graphicsDeviceManager, Camera2D camera)
|
|
{
|
|
this.graphics = graphicsDeviceManager;
|
|
this.camera = camera;
|
|
}
|
|
|
|
public void UpdateCurrentScreen(GameTime gameTime, bool assetsDone)
|
|
{
|
|
switch (Screen.State)
|
|
{
|
|
case ScreenState.EnterTransition:
|
|
if (previousScreen != null && previousScreen.UseRenderTargetForExitTransition)
|
|
{
|
|
previousScreen.UpdateTransition(gameTime.ElapsedGameTime.TotalSeconds, assetsDone);
|
|
}
|
|
Screen.UpdateTransition(gameTime.ElapsedGameTime.TotalSeconds, assetsDone);
|
|
break;
|
|
case ScreenState.ExitTransition:
|
|
if (Screen.UseRenderTargetForExitTransition || Screen.UpdateTransition(gameTime.ElapsedGameTime.TotalSeconds, assetsDone))
|
|
{
|
|
if (!firstScreenChangeComplete)
|
|
{
|
|
firstScreenChangeComplete = true;
|
|
OnFirstScreenChange(Screen);
|
|
}
|
|
if (Screen.NextScreen != null)
|
|
{
|
|
Debug.WriteLine("Changing to the next given screen.");
|
|
Screen = Screen.NextScreen;
|
|
}
|
|
else if (previousScreen != null)
|
|
{
|
|
Debug.WriteLine("Changing to previous screen.");
|
|
Screen = previousScreen;
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidOperationException("No next screen provided and no previous screen to return to.");
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
Screen.Update(gameTime);
|
|
}
|
|
|
|
public void DrawCurrentScreen(SpriteBatch spriteBatch)
|
|
{
|
|
graphics.GraphicsDevice.Clear(Screen.BackgroundColor);
|
|
if (Screen.State == ScreenState.EnterTransition && previousScreen != null && previousScreen.UseRenderTargetForExitTransition)
|
|
{
|
|
graphics.GraphicsDevice.SetRenderTarget(previousScreenRenderTarget);
|
|
graphics.GraphicsDevice.Clear(previousScreen.BackgroundColor);
|
|
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, camera.TransformMatrix);
|
|
previousScreen.Draw(spriteBatch);
|
|
spriteBatch.End();
|
|
graphics.GraphicsDevice.SetRenderTarget(null);
|
|
Screen.UpdatePreviousScreenFrame(previousScreenRenderTarget);
|
|
}
|
|
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, camera.TransformMatrix);
|
|
Screen.Draw(spriteBatch);
|
|
spriteBatch.End();
|
|
}
|
|
|
|
public void Resize(LoadingScreen loadingScreen)
|
|
{
|
|
Screen.AssetLoadStateChange(true);
|
|
Screen = loadingScreen;
|
|
previousScreenRenderTarget.Dispose();
|
|
previousScreenRenderTarget = null;
|
|
}
|
|
|
|
public void PostResize()
|
|
{
|
|
Screen.AssetLoadStateChange(false);
|
|
}
|
|
|
|
public void OnFirstScreenChange(Screen screen)
|
|
{
|
|
RequireNextScreenEvent?.Invoke(screen);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
public virtual void Dispose(bool disposing)
|
|
{
|
|
if (disposed) return;
|
|
if (disposing)
|
|
{
|
|
previousScreenRenderTarget?.Dispose();
|
|
}
|
|
disposing = true;
|
|
}
|
|
}
|
|
}
|