//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
namespace DarkWynter.Engine
{
#region Using Statements
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Net;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using System.Xml;
using System.Windows.Forms;
using Audio;
using Init;
using Menus;
using Globals;
using Utilities;
using Controllers;
using ObjectLib;
using GameObjects;
using Physics;
using DarkWynter.Stream;
using DarkWynter.Engine.UserInterface;
#endregion
using Nuclex;
// Once we mix XNA with the System.Windows.Forms namespace, some ambiguities will
// arise. The following lines create some shortcuts so the can conveniently address
// the classes we actually want to use.
using XnaColor = Microsoft.Xna.Framework.Graphics.Color;
using XnaRectangle = Microsoft.Xna.Framework.Rectangle;
using DarkWynter.Engine.EventControl;
///
/// Base class for creating a game using the DarkWynter Engine.
/// DarkWynterEngine extends object modification to the user through XML.
/// DakrWynterEngine extends functionality to the user through overridable objects.
///
public class DarkWynterEngine : Nuclex.GameControl
{
#region Properties
///
/// Main User's Heads Up Display
///
public static HeadsUpDisplay HUD;
///
/// Manage scoring, respawn, and gameover
///
private GameLogicController gameRules;
///
/// Game Controller
///
public static List gameControllers;
///
/// Menu Controller
///
public static List menuControllers;
///
/// List of user-defined game objects
///
protected List gameObjectTypes;
///
/// A scenegraph/collections class, contains all GameObject instants
///
public static ObjectLibrary objectLibrary;
///
/// Handles collision detection.
///
protected Collision collision;
///
/// Renders the scene once for each viewport.
///
protected Renderer renderer;
///
/// Menu System Componenets
///
protected MenuSystem menuSystem;
///
/// Interface to GPU Uniform variables
///
private ShaderParameters shaderParameters;
///
/// FPS - Frames Per Second
///
public FPSCounter fps;
/////
//// Controller
////
//public static Controller playerController;
////
//// Controller for the MenuSystem
////
//public static Controller menuController;
///
/// Screen Saver Shader
///
private ScreenSaver screenSaver;
///
/// Terrain Mod Singleton
///
public static MajikWand majikWand = new MajikWand();
///
/// Supplied from upper layer components that require notification whenever a new Level is loaded.
///
/// Controller boolean event arguments
public delegate void OnLevelChange(EventArgs args);
public static event OnLevelChange onLevelChange;
///
/// Supplied from upper layer components that require notification whenever a new Level is loaded.
///
/// Controller boolean event arguments
public delegate void OnSurveyPretest(object sender, EventArgs args);
public static event OnSurveyPretest onSurveyPretest;
public static bool launchPreTest = false;
///
/// Supplied from upper layer components that require notification whenever a new Level is loaded.
///
/// Controller boolean event arguments
public delegate void OnSurveyPosttest(object sender, EventArgs args);
public static event OnSurveyPosttest onSurveyPosttest;
public static bool launchPostTest = false;
#endregion
#region Methods
// --------------- Constructor -----------------
///
/// Main Engine Class.
/// Check for Hardware Capabilities.
/// Create GraphicsDeviceManager and ContentManager.
///
public DarkWynterEngine():base()
{
// Draw is called as many times as the hardware can handle.
// If(IsFixedTimeStep), then Update is called 30x per second.
// If(!IsFixedTimeStep), then Update is called as many times as the hardware can handle.
// The differrence affects both controller inputs and physics responses in the Virtual Environment.
this.IsFixedTimeStep = true;
// Set up Global Graphics Device and Content Loader
Statics_Stream.RenderSettings.graphics = this.graphics;
Statics_Engine.SystemSettings.content = new ContentManager(Services);
Statics_Stream.RenderSettings.graphics.SynchronizeWithVerticalRetrace = false;
// Check all available adapters on the system
for (int i = 0; i < GraphicsAdapter.Adapters.Count; i++)
{
// Get the capabilities of the hardware device
GraphicsDeviceCapabilities caps = GraphicsAdapter.Adapters[i].GetCapabilities(DeviceType.Hardware);
if (caps.MaxPixelShaderProfile < ShaderProfile.PS_3_0)
{
System.Diagnostics.Debug.WriteLine("This adapter does not support Shader Model 3.0.");
Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.NOT_SUPPORTED;
}
else
{
//Yay! They can play
Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.CREDIT_SCREEN;
}
}
// Initialize Control Docking
this.Dock = DockStyle.Fill;
this.Focus();
// Set up Mouse to Activate and Deactivate, using Left and Right mouse clicks respectively.
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OnMouseDown);
// Drag/Drop Level Creation
this.AllowDrop = true;
this.DragEnter += new DragEventHandler(terrain_DragEnter);
this.DragDrop += new DragEventHandler(terrain_DragDrop);
}
// ----------------- Load ----------------------
///
/// Set Up Display Window.
/// Create Logging, XML, GameFlow, Renderer, SpriteBatch,
/// FontWriter, MenuSystem, Audio, ShaderParameters, ChatClient,
/// Frames Per Second Counter, and Screensaver
///
protected virtual void Initialize(GameObjectTypes userDefinedTypes)
{
try
{
// Load System XML Settings
XML.LoadUserPreferences();
DarkWynterEngine.Load_LevelIndex();
DarkWynterEngine.Load_EventIndex();
XML.LoadQuestInfo();
// Load GameObjectTypes - Xml/GameObject Equivalency List
XML.gameObjectTypes = new List();
XML.gameObjectTypes.Add(new GameObjectTypes());
XML.gameObjectTypes.Add(userDefinedTypes);
if (!XML.contentInstalled)
{
this.SuspendLayout();
Label installContentLabel = new Label();
installContentLabel.AutoSize = true;
installContentLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.00F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold))), System.Drawing.GraphicsUnit.Point, ((byte)(0)));
installContentLabel.Location = new System.Drawing.Point(10, 10);
installContentLabel.Text = "Content Project could not be found... ";
installContentLabel.ForeColor = System.Drawing.Color.Silver;
Label installContentLabel2 = new Label();
installContentLabel2.AutoSize = true;
installContentLabel2.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.00F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold))), System.Drawing.GraphicsUnit.Point, ((byte)(0)));
installContentLabel2.Location = new System.Drawing.Point(10, 50);
installContentLabel2.Text = "Please select \"Download Package\" below, to install content from web.";
installContentLabel2.ForeColor = System.Drawing.Color.Silver;
Panel panel = new Panel();
panel.SuspendLayout();
panel.Dock = DockStyle.Fill;
panel.Controls.Add(installContentLabel);
panel.Controls.Add(installContentLabel2);
panel.ResumeLayout(false);
panel.PerformLayout();
this.Controls.Clear();
this.Controls.Add(panel);
this.ResumeLayout(false);
this.PerformLayout();
}
// Menu System
menuSystem = new MenuSystem();
XML.LoadAssembly("DWGame.dll");
objectLibrary = new ObjectLibrary();
collision = new Collision();
// Set up display
renderer = new Renderer(Statics_Engine.SystemSettings.content);
UpdateRendererSettings();
// Set up the renderer draw delegates
renderer.drawObjectLibrary = new Renderer.DrawObjectLibrary(objectLibrary.Draw);
renderer.drawSprites = new Renderer.DrawSprites(objectLibrary.Draw_Billboards);
renderer.drawHUD = new Renderer.DrawHUD(objectLibrary.PostDraw_HUD);
renderer.drawObjectOverhead = new Renderer.DrawObjectOverhead(objectLibrary.DrawOverhead);
//PUT AN IMPORTANT METHOD CALL HERE
// Set up Gpu Shader Handles
shaderParameters = new ShaderParameters(Statics_Engine.SystemSettings.content);
// Init the audio engine
Audio.Audio.Initialize();
Audio.Audio.PlayLevelSong("Theme4");
// ScreenSaver for menuSystem
screenSaver = new ScreenSaver();
Statics_Engine.SystemSettings.screenSaverTimer = Stopwatch.StartNew();
// Load the Font class
Statics_Stream.Fonts.Arial = Statics_Engine.SystemSettings.content.Load("Content/_fonts/Arial");
Statics_Stream.Fonts.ComicSans = Statics_Engine.SystemSettings.content.Load("Content/_fonts/ComicSansMS");
Statics_Stream.Fonts.ComicSansSmall = Statics_Engine.SystemSettings.content.Load("Content/_fonts/ComicSansSmall");
// Start Logging
Logging.setStart(System.DateTime.Now);
Logging.G2LLogList.Add(System.DateTime.Now.ToString());
// Create new FPS class
fps = new FPSCounter();
// DarkWynterEngine.Deactivate();
// Set up the Game Rules
gameRules = new GameLogicController();
// Controller Setup
gameControllers = new List();
menuControllers = new List();
ControllerManager.CheckForControllers(objectLibrary);
base.Initialize();
}
// Catch all loading exceptions and print message to user.
catch (Exception e)
{
Label installContentLabel2 = new Label();
installContentLabel2.AutoSize = true;
installContentLabel2.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.00F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold))), System.Drawing.GraphicsUnit.Point, ((byte)(0)));
installContentLabel2.Location = new System.Drawing.Point(10, 50);
installContentLabel2.Text = "Error Initializing, Prob Due to Content. \n" + e.Message;
installContentLabel2.ForeColor = System.Drawing.Color.Silver;
Panel panel = new Panel();
panel.SuspendLayout();
panel.Dock = DockStyle.Fill;
panel.Controls.Add(installContentLabel2);
panel.ResumeLayout(false);
panel.PerformLayout();
this.Controls.Clear();
this.Controls.Add(panel);
this.ResumeLayout(false);
this.PerformLayout();
}
}
///
/// Loads availible Levels from _Levels.xml and stores them in the LevelInfo list.
///
public static void Load_LevelIndex()
{
string LevelXMLFile = "_xml/LevelEdit/_Levels.xml";
Statics_Engine.levelInfo = new List();
try
{
// Load physics, music, and fog
XmlDocument reader = new XmlDocument();
reader.Load(LevelXMLFile);
XmlNodeList allNodes = reader.ChildNodes;
foreach (XmlNode levelNode in allNodes)
{
if (levelNode.Name == "levels")
{
XmlNodeList levelNodes = levelNode.ChildNodes;
foreach (XmlNode node in levelNodes)
{
if (node.Name == "level")
{
Statics_Engine.LevelInfo level = new Statics_Engine.LevelInfo();
level.name = node.Attributes["name"].Value;
level.filepath = node.Attributes["xmlFile"].Value;
level.description = node.Attributes["description"].Value;
level.cameraModeEnum_XML = (DarkWynter.Stream.Camera.CameraMode)Enum.Parse(typeof(DarkWynter.Stream.Camera.CameraMode), node.Attributes["CameraModeEnum"].Value, true);
Statics_Engine.levelInfo.Add(level);
}
}
}
}
}
catch
{
XML.contentInstalled = false;
System.Diagnostics.Debug.WriteLine("Error reading xml");
//throw new Exception("Error reading XML");
}
}
public static void Load_EventIndex()
{
string EventsXMLFile = "_xml/QuestSettings/_Levels.xml";
Statics_Engine.eventsInfo = new List();
try
{
// Load physics, music, and fog
XmlDocument reader = new XmlDocument();
reader.Load(EventsXMLFile);
XmlNodeList allNodes = reader.ChildNodes;
foreach (XmlNode eventsNode in allNodes)
{
if (eventsNode.Name == "levels")
{
XmlNodeList levelNodes = eventsNode.ChildNodes;
foreach (XmlNode node in levelNodes)
{
if (node.Name == "events")
{
Statics_Engine.EventsInfo eventsInfo = new Statics_Engine.EventsInfo();
eventsInfo.name = node.Attributes["name"].Value;
eventsInfo.filepath = node.Attributes["xmlFile"].Value;
eventsInfo.description = node.Attributes["description"].Value;
Statics_Engine.eventsInfo.Add(eventsInfo);
}
}
}
}
}
catch
{
XML.contentInstalled = false;
System.Diagnostics.Debug.WriteLine("Error reading xml");
//throw new Exception("Error reading XML");
}
}
///
///
///
public static void Save_LevelIndex()
{
// Output xml level index to file
}
///
///
///
public static void Load_Level(string LevelXml_FilePath, string ScriptXml_FilePath)
{
// Reset load level flag
Statics_Engine.GameSettings.LoadLevel = false;
if (HUD == null)
{
HUD = new HeadsUpDisplay();
}
// Call Load Sequence
objectLibrary.LoadLevel(LevelXml_FilePath);
GameEventHandler.LoadEventsXml(ScriptXml_FilePath);
// XML.LoadPlayerIndex();
//Statics_Engine.LevelSettings.ViewportSize = new Vector2(
// Statics_Stream.RenderSettings.cameraList[0].viewport.Width,
// Statics_Stream.RenderSettings.cameraList[0].viewport.Height);
Statics_Stream.RenderSettings.cameraList[0].mode = Stream.Camera.CameraMode.FirstPerson;
Statics_Stream.RenderSettings.cameraList[0].fixedPosition = new Microsoft.Xna.Framework.Vector3(8000, 6000, 8000);
Statics_Stream.RenderSettings.cameraList[0].mode = Statics_Engine.levelInfo[Statics_Engine.levelIndex].cameraModeEnum_XML;
// If we only have one player, add a terrain camera for the mini map
if (Statics_Stream.RenderSettings.cameraList.Count == 1)
{
Camera HUDCamera = new Camera();
Statics_Stream.RenderSettings.cameraList.Add(HUDCamera);
HUDCamera.mode = Camera.CameraMode.FixedPosition;
HUDCamera.lookAtPosition = Vector3.Zero;
HUDCamera.cameraPosition = new Vector3(0, 5000, 0);
//position
HUDCamera.viewport.X = 100;
HUDCamera.viewport.Y = 100;
//size
HUDCamera.viewport.Width = 50;
HUDCamera.viewport.Height = 50;
}
// Switch into Game Mode processing
Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.GAME_MODE;
// Call Level-Loaded Callback delegate to notify upper layers of change.
onLevelChange(new EventArgs());
}
// --------------- Update ---------------------
///
/// Update MenuSystemGame, Audio, FPS.
/// Check For Level Loading Request.
/// Check For Exit.
///
/// XNA GameTime
protected override void Update(GameTime gameTime)
{
// Set current change in time
Statics_Engine.SystemSettings.dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
// Update renderer settings if changed
UpdateRendererSettings();
Statics_Engine.GameSettings.viewport = Statics_Stream.RenderSettings.cameraList[0].viewport;
// GameEventHandler.CurrentGameConditions._triggerCoins = 1;
// If requested via flag
if (Statics_Engine.GameSettings.LoadLevel)
{
// Load new Level
Load_Level(
Statics_Engine.levelInfo[Statics_Engine.levelIndex].filepath,
Statics_Engine.eventsInfo[Statics_Engine.levelIndex].filepath
);
}
// If Window is active...
if (Statics_Engine.SystemSettings.WINDOW_IN_FOCUS)
{
// Update all Engine Controllers
UpdateControllers();
}
// If compiler disabled
if (Statics_Engine.SystemSettings.enableCompilerConsole == false)
{
// If in 3D GameMode
if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_MODE)
{
// Update ObjectLibrary
objectLibrary.Update(ref objectLibrary, collision);
// Update TerrainMod Caps
majikWand.Update(objectLibrary);
}
else
{
if (Statics_Engine.SystemSettings.WINDOW_IN_FOCUS)
{
// Update menu system
menuSystem.Update(objectLibrary);
}
}
}
// Update Frame Rate Counter
if (Statics_Engine.SystemSettings.enableFPSDisplay)
{ fps.Update(); }
// Crank the audio engine
Audio.Audio.Update();
// Crank the video engine
//video.Update();
if (launchPreTest)
{
if (DarkWynterEngine.onSurveyPretest != null)
{
DarkWynterEngine.onSurveyPretest(this, new EventArgs());
launchPreTest = false;
}
}
if (launchPostTest)
{
Logging.writeG2LLog(
DarkWynter.Engine.Globals.Statics_Engine.PlayerSettings.studentIDNumber + "-G2Llog.txt",
DarkWynter.Engine.Utilities.Logging.G2LLogList
);
Logging.writeG2LLog(
DarkWynter.Engine.Globals.Statics_Engine.PlayerSettings.studentIDNumber + "-G2LPositionalLog.txt",
DarkWynter.Engine.Utilities.Logging.G2LPositionalLog
);
if (DarkWynterEngine.onSurveyPosttest != null)
{
DarkWynterEngine.onSurveyPosttest(this, new EventArgs());
launchPostTest = false;
}
}
// Call XNA Update
base.Update(gameTime);
}
private void UpdateRendererSettings()
{
// Update renderer settings if changed
if (Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.Height != Statics_Stream.RenderSettings.GAME_WINDOW_HEIGHT ||
Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.Width != Statics_Stream.RenderSettings.GAME_WINDOW_WIDTH)
{
renderer.AutoDetectResolution();
renderer.AutoDetectWindowAndDefaultViewport(/*Window*/);
Renderer.ResetViewports(Statics_Engine.SystemSettings.TOTAL_PLAYERS);
}
}
private void UpdateControllers()
{
// Update Game Mode Controllers
if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_MODE)
{
// Update Controllers
foreach (GameController gameController in gameControllers)
{
// Check that the human is alive and hence active in the game
if (objectLibrary.humans[gameController.playerNumber].IsAlive())
{
gameController.Update(ref objectLibrary, ref menuSystem);
}
}
// Update GameRules
gameRules.Update(ref objectLibrary);
}
// Update Menu Mode Controllers
else
{
// Update all menu controllers
foreach (MenuController menuController in menuControllers)
{
menuController.Update(ref objectLibrary, ref menuSystem);
}
}
}
// ----------------- Draw ----------------------
///
/// Draw Game or MenuSystem Screen
///
/// XNA GameTime
protected override void Draw(GameTime gameTime)
{
// Clear the device
Statics_Engine.SystemSettings.elementalGameTime = gameTime;
// If in Game Mode (or paused) call game draw function
if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_MODE || Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_PAUSE)
{
renderer.Draw(Statics_Engine.SystemSettings.TOTAL_PLAYERS);
//renderer.DrawOverhead(Statics_Stream.RenderSettings.cameraList[1]);
}
if (Statics_Engine.SystemSettings.gameState != Enums_Engine.EngineState.GAME_MODE)
{
menuSystem.Draw(renderer.spriteBatch, screenSaver);
}
fps.Draw(renderer.spriteBatch);
// Call XNA Draw
base.Draw(gameTime);
}
// ---------------- Exit -----------------------
///
/// Check to see if user has requested to exit the application.
///
protected virtual void CheckExit()
{
XML.SaveUserPreferences();
//Logging.genReport(System.DateTime.Now);
//Logging.saveLog(System.DateTime.Now);
Statics_Engine.SystemSettings.enableFPSDisplay = false;
//chatClient.CloseConnection();
this.Exit();
}
///
/// Unload resources loaded using the content manager
///
protected override void UnloadContent()
{
base.UnloadContent();
Statics_Engine.SystemSettings.content.Unload();
Statics_Engine.SystemSettings.content.Dispose();
}
#endregion
#region Events
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
//if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_MODE)
{
if (HUD != null)
{
//// Resize based on percentage of FULL screen viewport size
HUD.Resize(new Vector2(this.Size.Width, this.Size.Height));
}
}
}
///
/// Copy the new image
///
///
///
void terrain_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Bitmap))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
///
/// Create the new bitmap onto the terrain and add the csobject to the list
///
///
///
void terrain_DragDrop(object sender, DragEventArgs e)
{
//objectLibrary.humans[0].holdingObject = ObjectLibrary.soloObjects[3];
objectLibrary.humans[0].holdingObject.mass.scale = new Vector3(100);
//// Create the object and attach to Player
//if (tempObj != null)
//{
// //if (tempObj is Waypoint)
// //{
// //}
// //if (tempObj is Actor)
// //{
// //}
// //if (tempObj is Prop)
// //{
// //}
//}
}
///
/// Override XNA function
/// Activate Mouse when window gains focus.
///
///
///
protected override void OnActivated(object sender, EventArgs args)
{
//base.OnActivated(sender, args);
Statics_Engine.SystemSettings.WINDOW_IN_FOCUS = true;
}
///
/// Override XNA function.
/// Deactivate Mouse when window looses focus.
///
///
///
protected override void OnDeactivated(object sender, EventArgs args)
{
//base.OnDeactivated(sender, args);
Statics_Engine.SystemSettings.WINDOW_IN_FOCUS = false;
}
///
/// Toggle game controllers on/off
///
public static void Activate()
{
Statics_Engine.SystemSettings.WINDOW_IN_FOCUS = true;
}
///
/// Deactivate Mouse, Controls, and most of the Update Loop.
///
public static void Deactivate()
{
Statics_Engine.SystemSettings.WINDOW_IN_FOCUS = false;
}
///
/// Activates Mouse, Controller, and unpauses Game when Left-Clicked.
/// Deactivates Mouse, Controller and pauses Game when Right-Clicked.
///
///
///
protected void OnMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
DarkWynterEngine.Activate();
}
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
DarkWynterEngine.Deactivate();
}
}
///
/// Initiate exit procedure
///
public static void DoExit(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Would you like to close the application?", "Allow Close?", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
== DialogResult.No)
{
e.Cancel = true;
}
else if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_MODE)
{
Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.FINALIZE_G2LSTUFF;
}
else if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.FINALIZE_G2LSTUFF)
{
Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.GAME_OVER;
}
else if (Statics_Engine.SystemSettings.gameState == Enums_Engine.EngineState.GAME_OVER)
{
Statics_Engine.SystemSettings.gameState = Enums_Engine.EngineState.EXIT;
}
}
#endregion
}
}