using System;
using System.Linq;
using Chernobyl.Collections.Generic.Event;
using Chernobyl.Config;
using Chernobyl.Dependency;
using Chernobyl.Graphics;
using Chernobyl.Plugin;
using Chernobyl.StateMachine;
using Chernobyl.Update;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Chernobyl.Xna
{
///
/// The plug-in that allows XNA to be used within Chernobyl.
///
public class XnaPlugin : Game, IPlugin
{
///
/// Initializes a new instance of the class.
///
/// The instance that gives out services for use
/// by this type and takes services from this type for use by other systems.
public XnaPlugin(IEventCollection services)
{
Graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "../../Content";
Services = services;
Core core = Services.OfType().First();
if (core == null)
throw new Exception("Failed to create the Chernobyl XNA plug-in. " +
"The Chernobyl core must be created before this plug-in can be created.");
core.Runner = Run;
// Note: IEventCollection.Inject(this) is invoked in XnaPlugin.Initialize().
}
///
/// The services provided by this plug-in or null if no services are
/// provided.
///
public new IEventCollection Services { get; set; }
///
/// The device that is used to create and manager graphics level services
/// such as rendering and creating graphics objects like shaders.
///
[Provide]
public new GraphicsDevice GraphicsDevice
{
get { return base.GraphicsDevice; }
}
///
/// The instance used by XNA to manage
/// content produced by the content pipeline.
///
[Provide]
public new ContentManager Content
{
get { return base.Content; }
set { base.Content = value; }
}
///
/// A instance which can be used to draw a
/// group of XNA sprites with the same settings.
///
[Provide]
public SpriteBatch SpriteBatch { get; private set; }
///
/// Gets the underlying operating system window for XNA.
///
[Provide]
public new GameWindow Window
{
get { return base.Window; }
}
///
/// The that manages the state of the entire
/// application.
///
[Inject]
public IState ApplicationState { get; set; }
///
/// An used as the default value for
/// the .
///
[Inject]
public ILoadingState LoadingState { get; set; }
///
/// The that represents the started running state
/// after the configuration state ( ).
///
[Inject]
public IRunningState RunningState { get; set; }
///
/// The that is responible
/// for updating Chernobyl.
///
[Inject(Type = typeof(IRootUpdateable))]
public Update.IUpdateable RootUpdateable { get; set; }
///
/// The primary that needs to be drawn.
///
[Inject]
public Scene MainScene { get; set; }
///
/// The that manages the configuration
/// and management of the graphics device for XNA.
///
GraphicsDeviceManager Graphics { get; set; }
///
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
///
protected override void Initialize()
{
SpriteBatch = new SpriteBatch(GraphicsDevice);
Services.Inject(this);
base.Initialize();
}
///
/// LoadContent will be called once per game and is the place to load
/// all of your content.
///
protected override void LoadContent()
{
ApplicationState.ChildState = LoadingState;
ApplicationState.ChildState = RunningState;
}
///
/// UnloadContent will be called once per game and is the place to unload
/// all content.
///
protected override void UnloadContent()
{
}
///
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
///
/// Provides a snapshot of timing values.
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();
RootUpdateable.Update(gameTime.ElapsedGameTime);
base.Update(gameTime);
}
///
/// This is called when the game should draw itself.
///
/// Provides a snapshot of timing values.
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue, 1, 0);
// This code ensures alpha blending works properly.
// TODO: remove this code and place it in an IDrawable that can be
// used where necessary.
GraphicsDevice.RenderState.AlphaBlendEnable = true;
GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
MainScene.Draw();
base.Draw(gameTime);
}
}
}