//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
namespace ElementalGame
{
#region Using Statements
using System;
using System.Collections.Generic;
using System.Diagnostics;
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;
#endregion
public class ElementalGame : Microsoft.Xna.Framework.Game
{
// Graphics manager
public static GraphicsDeviceManager graphics;
public static ContentManager content;
// Window Size
public static int clientWidth, clientHeight;
public static float clientMinDepth, clientMaxDepth;
public static bool WINDOW_IN_FOCUS = true; // Disables mouse when window loses focus
// View Ports
public static Viewport defaultViewport = new Viewport(); // Default viewport that takes up the whole screen
public static List viewportList = new List(); // Window viewports (for multiplayer)
// Screen Saver
public static Stopwatch screenSaverTimer;
Effect aburn;
// Menu and Controller
SpriteBatch spriteBatch;
public static MenuSystem menuSystem;
GameController Player1Controller = new GameController();
// Global Timers
public static GameTime elementalGameTime;
TimeSpan elapsedTime = TimeSpan.Zero;
// Hardware Monitoring
public static bool SHADER3_NOT_SUPPORTED = false;
public static GraphicsDeviceCapabilities caps;
private FPS fpsScreen;
public static bool enableFPSDisplay;
int frameRate = 0;
int frameCounter = 0;
// -- SHOULD BE REMOVED
public static bool drewLoadScreen = false;
public static int playerThatPaused = -1;
public static int currentPlayerIndex = 0;
public static bool loadDarkMatter = false;
private ShaderParameters shaderParameters;
private Client chatClient;
// Keep track of menu and game modes
public enum GameState
{
NOT_SUPPORTED,
STORY_MODE,
TITLE_SCREEN,
CONTROL_SCREEN,
GAME_SETUP,
LEVEL_SETUP,
LOAD_LEVEL,
PLAYER_SETUP,
GAME_MODE,
GAME_PAUSE,
GAME_OVER,
CONFIRM_EXIT,
CREDITS,
EXIT
};
public static GameState gameState;
// Main Game Loop
GameFlow gameFlow;
public ElementalGame()
{
this.IsFixedTimeStep = false;
graphics = new GraphicsDeviceManager(this);
content = new ContentManager(Services);
// Check all available adapters on the system
for (int i = 0; i < GraphicsAdapter.Adapters.Count; i++)
{
// Get the capabilities of the hardware device
caps = GraphicsAdapter.Adapters[i].GetCapabilities(DeviceType.Hardware);
if (caps.MaxPixelShaderProfile < ShaderProfile.PS_3_0)
{
SHADER3_NOT_SUPPORTED = true;
System.Diagnostics.Debug.WriteLine("This adapter does not support Shader Model 3.0.");
}
}
//Components.Add(new FrameRateCounter(this));
}
// ------------------- Load -------------------
protected override void Initialize()
{
// Start screen-saver timer
ElementalGame.screenSaverTimer = Stopwatch.StartNew();
// Check the display mode to see how big the resolution
int displayWidth = graphics.GraphicsDevice.DisplayMode.Width;
int displayHeight = graphics.GraphicsDevice.DisplayMode.Height;
// Select best resolution for device
AutoDetectResolution(displayWidth, displayHeight);
graphics.PreferredBackBufferWidth = XML.SystemSettings.GAME_WINDOW_WIDTH;
graphics.PreferredBackBufferHeight = XML.SystemSettings.GAME_WINDOW_HEIGHT;
graphics.ApplyChanges();
// Set up window
clientWidth = Window.ClientBounds.Width;
clientHeight = Window.ClientBounds.Height;
clientMinDepth = graphics.GraphicsDevice.Viewport.MinDepth;
clientMaxDepth = graphics.GraphicsDevice.Viewport.MaxDepth;
// Set up the menu system components
spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
aburn = content.Load("Shaders/ElementalGPU");
aburn.CurrentTechnique = aburn.Techniques["AntiBurn"];
// Initialize the Font class
FontWriter.initFont(graphics.GraphicsDevice, content);
// Set the default viewport
defaultViewport.X = 0;
defaultViewport.Y = 0;
defaultViewport.Width = clientWidth;
defaultViewport.Height = clientHeight;
defaultViewport.MinDepth = clientMinDepth;
defaultViewport.MaxDepth = clientMaxDepth;
if (SHADER3_NOT_SUPPORTED == false)
{
//Yay! They can play
gameState = GameState.TITLE_SCREEN;
}
else
{
// :(
gameState = GameState.NOT_SUPPORTED;
}
menuSystem = new MenuSystem();
menuSystem.confirmExitScreen.SetBackground(content.Load("_textures/confirmquit"));
menuSystem.sorryScreen.SetBackground(content.Load("_textures/Sorry"));
// Check for widescreen first!
if ((1.0f * XML.SystemSettings.GAME_WINDOW_WIDTH) / XML.SystemSettings.GAME_WINDOW_HEIGHT > 1.5)
{
// Load the textures for the game screens
menuSystem.titleScreen.SetBackground(content.Load("_textures/TitleScreen_wide"));
}
else
{
// Load the textures for the game screens
menuSystem.titleScreen.SetBackground(content.Load("_textures/TitleScreen"));
}
menuSystem.controlsScreen.SetBackground(content.Load("_textures/Controls"));
menuSystem.gameOverScreen.SetBackground(content.Load("_textures/cutScenes/gameover"));
menuSystem.creditsScreen.SetBackground(content.Load("_textures/cutScenes/credits"));
menuSystem.storyModeTexture = content.Load("_textures/corner");
menuSystem.deathMatchTexture = content.Load("_textures/DMatch");
menuSystem.survivalTexture = content.Load("_textures/Survival");
menuSystem.lastmanTexture = content.Load("_textures/LMStanding");
GameMenu.sliderBackground = content.Load("_textures/SliderImproved");
menuSystem.levelSetup.SetBackground(content.Load("_textures/MenuScreen2"));
//setup the scrolling images
GameMenuImageScroller scroller = menuSystem.levelSetup.GetLevelSelection();
float scaleX = (XML.SystemSettings.GAME_WINDOW_WIDTH / 1280.0f);
float scaleY = (XML.SystemSettings.GAME_WINDOW_HEIGHT / 1024.0f);
//scroller.AddNewSlider("Selector bar", content.Load < Texture2D >("_textures/onSelectMS"));
scroller.AddNew("Earth", content.Load("_textures/GSEarthNeg"), null, (int)(76 * scaleX), (int)(38 * scaleY));
scroller.AddNew("Fire", content.Load("_textures/GSFireNeg"), null, (int)(76 * scaleX), (int)(278 * scaleY));
scroller.AddNew("Water", content.Load("_textures/GSAirNeg"), null, (int)(76 * scaleX), (int)(518 * scaleY));
scroller.AddNew("Air", content.Load("_textures/GSWaterNeg"), null, (int)(76 * scaleX), (int)(758 * scaleY));
menuSystem.playerSetup.SetBackground(content.Load("_textures/PlayerSelection"));
GameMenuRandomImageDisplay imageDisplay = menuSystem.playerSetup.GetDiagnosisDisplay();
for (int i = 1; i <= 8; i++)
{
imageDisplay.AddImage(content.Load("_textures/chart" + i));
}
imageDisplay.RandomIndex();
menuSystem.pauseScreen.SetBackground(content.Load("_textures/cutScenes/black"), 0.3f);
//menuSystem.pauseScreen.SetHintsTexture(content.Load("_textures/black"));
menuSystem.loadScreen.SetBackground(content.Load("_textures/Loading"));
menuSystem.loadScreen.SetGlyph(content.Load("GamePicture"));
// Create an empty game to initialize human
gameFlow = new GameFlow();
//gameFlow.LoadGame(graphics, content);
// Initialize the player1 controller for menus
Player1Controller = new GameController(GameController.ControllerType.PC_AND_XBOX, PlayerIndex.One, clientHeight, clientWidth);
// Init the audio engine
Audio.Initialize();
fpsScreen = new FPS();
//fps = new Queue(10);
//enableFPSDisplay = false; //off by default
//framesPerSecond = new Stopwatch();
//framesPerSecond.Start();
// Load System XML Settings
XML.LoadSystem();
shaderParameters = new ShaderParameters();
shaderParameters.LoadParameters();
base.Initialize();
}
public void AutoDetectResolution(int displayWidth, int displayHeight)
{
#if XBOX360
XML.SystemSettings.GAME_WINDOW_WIDTH = displayWidth;
XML.SystemSettings.GAME_WINDOW_HEIGHT = displayHeight;
#else
//Auto detect best resolution
if (displayWidth >= 1280)
{
// 720p
XML.SystemSettings.GAME_WINDOW_WIDTH = 1280;
if (displayHeight >= 1024)
{
// 4:3 resolution
XML.SystemSettings.GAME_WINDOW_HEIGHT = 1024;
}
else
{
// Widescreen
XML.SystemSettings.GAME_WINDOW_HEIGHT = 720;
}
}
else if (displayWidth >= 1024)
{
// something in between
XML.SystemSettings.GAME_WINDOW_WIDTH = 1024;
XML.SystemSettings.GAME_WINDOW_HEIGHT = 768;
}
else
{
// Default to 480p
if (displayWidth > 700)
{
XML.SystemSettings.GAME_WINDOW_WIDTH = 800;
}
else
{
XML.SystemSettings.GAME_WINDOW_WIDTH = 640;
}
if (displayHeight >= 600)
{
XML.SystemSettings.GAME_WINDOW_HEIGHT = 600;
}
else
{
XML.SystemSettings.GAME_WINDOW_HEIGHT = 480;
}
}
#endif
}
protected override void LoadGraphicsContent(bool loadAllContent)
{
Audio.PlayTitleSong();
//chatClient = new Client();
//chatClient.OpenConnection("amanda", 7777);
}
// ----------------- Update ------------------------------
protected override void Update(GameTime gameTime)
{
//chatClient.Write("Client 1 chat message");
//string s = chatClient.Read();
if (loadDarkMatter)
{
loadDarkMatter = false;
gameFlow.objectLibrary.LoadDarkMatter();
gameFlow.objectLibrary.LoadMatter();
}
if (gameState == GameState.GAME_MODE)
{
// Update the game
gameFlow.Update((float)gameTime.ElapsedGameTime.TotalSeconds, menuSystem, spriteBatch);
}
if (drewLoadScreen)
{
//Draw Load screen once and now we can do the load level stuff here
drewLoadScreen = false;
// Load Level Data
XML.LoadPlayerIndex(menuSystem);
menuSystem.LevelSetupCommit(gameFlow.objectLibrary);
gameFlow.Load();
gameFlow.objectLibrary.humans[0].LoadPlayer(XML.playerInfo[0]);
ElementalGame.gameState = ElementalGame.GameState.PLAYER_SETUP;
//finalize # players here
ElementalGame.CheckForControllers(GameFlow.numberOfHumansActive, gameFlow);
//block start input so we don't skip Player 1's setup
Player1Controller.SetBlockStartBackInput(true);
gameFlow.objectLibrary.humans[0].playerController.SetBlockStartBackInput(true);
}
// Update Frame Rate Counter
if (enableFPSDisplay){UpdateFPS(gameTime);}
// Update menu system
menuSystem.UpdateMenus(graphics, content, gameTime, Player1Controller, gameFlow);
// Check for user exit request
CheckExit();
// Crank the audio engine
Audio.Update();
base.Update(gameTime);
}
// --------------------- Draw -----------------------------------
protected override void Draw(GameTime gameTime)
{
// Clear the device
elementalGameTime = gameTime;
graphics.GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
// If in Game Mode (or paused) call game draw function
if (gameState == GameState.GAME_MODE || gameState == GameState.GAME_PAUSE)
{
// Draw GameFlow
gameFlow.Draw(graphics.GraphicsDevice, spriteBatch, viewportList, menuSystem);
}
if (gameState != GameState.GAME_MODE)
{
graphics.GraphicsDevice.Viewport = defaultViewport;
// Draw the appropriate Menu Screen
if (gameState == GameState.NOT_SUPPORTED)
{
menuSystem.sorryScreen.Draw(spriteBatch);
}
else if (gameState == GameState.STORY_MODE)
{
// Play appropriate cutscene
if (GameRules.cutSceneIndex == 0)
{
menuSystem.scene1.Draw(spriteBatch);
}
if (GameRules.cutSceneIndex == 1)
{
menuSystem.scene2.Draw(spriteBatch);
}
if (GameRules.cutSceneIndex == 2)
{
menuSystem.scene3.Draw(spriteBatch);
}
if (GameRules.cutSceneIndex == 3)
{
menuSystem.scene4.Draw(spriteBatch);
}
if (GameRules.cutSceneIndex == 4)
{
menuSystem.scene5.Draw(spriteBatch);
}
}
else if (gameState == GameState.CONTROL_SCREEN)
{
if (ElementalGame.screenSaverTimer.ElapsedMilliseconds > XML.SystemSettings.ANTI_BURN_TIMER)
{
AntiBurnScreenSaverBegin(gameTime);
menuSystem.controlsScreen.Draw(spriteBatch);
AntiBurnScreenSaverEnd(gameTime);
}
else
{
menuSystem.controlsScreen.Draw(spriteBatch);
}
}
else if (gameState == GameState.CONFIRM_EXIT)
{
if (ElementalGame.screenSaverTimer.ElapsedMilliseconds > XML.SystemSettings.ANTI_BURN_TIMER)
{
AntiBurnScreenSaverBegin(gameTime);
menuSystem.confirmExitScreen.Draw(spriteBatch);
AntiBurnScreenSaverEnd(gameTime);
}
else
{
menuSystem.confirmExitScreen.Draw(spriteBatch);
}
}
else if (gameState == GameState.CREDITS)
{
menuSystem.creditsScreen.Draw(spriteBatch);
}
else if (gameState == GameState.TITLE_SCREEN)
{
if (ElementalGame.screenSaverTimer.ElapsedMilliseconds > XML.SystemSettings.ANTI_BURN_TIMER)
{
AntiBurnScreenSaverBegin(gameTime);
menuSystem.titleScreen.Draw(spriteBatch);
AntiBurnScreenSaverEnd(gameTime);
}
else
{
menuSystem.titleScreen.Draw(spriteBatch);
}
}
else if (gameState == GameState.GAME_SETUP)
{
if (ElementalGame.screenSaverTimer.ElapsedMilliseconds > XML.SystemSettings.ANTI_BURN_TIMER)
{
AntiBurnScreenSaverBegin(gameTime);
menuSystem.gameSetup.Draw(spriteBatch);
AntiBurnScreenSaverEnd(gameTime);
}
else
{
menuSystem.gameSetup.Draw(spriteBatch);
}
}
else if (gameState == GameState.LEVEL_SETUP)
{
gameFlow.DrawTerrainDemo(graphics.GraphicsDevice, (float)gameTime.ElapsedGameTime.TotalSeconds);
graphics.GraphicsDevice.Viewport = defaultViewport;
menuSystem.levelSetup.Draw(spriteBatch);
}
else if (gameState == GameState.LOAD_LEVEL)
{
menuSystem.loadScreen.Draw(spriteBatch);
drewLoadScreen = true;
}
else if (gameState == GameState.PLAYER_SETUP)
{
gameFlow.DrawPlayerDemo(graphics.GraphicsDevice, (float)gameTime.ElapsedGameTime.TotalSeconds, currentPlayerIndex);
graphics.GraphicsDevice.Viewport = defaultViewport;
menuSystem.playerSetup.Draw(spriteBatch);
}
else if (gameState == GameState.GAME_OVER)
{
menuSystem.gameOverScreen.Draw(spriteBatch);
}
else if (gameState == GameState.GAME_PAUSE)
{
if (ElementalGame.screenSaverTimer.ElapsedMilliseconds > XML.SystemSettings.ANTI_BURN_TIMER)
{
AntiBurnScreenSaverBegin(gameTime);
menuSystem.pauseScreen.Draw(spriteBatch, graphics.GraphicsDevice);
AntiBurnScreenSaverEnd(gameTime);
}
else
{
menuSystem.pauseScreen.Draw(spriteBatch, graphics.GraphicsDevice);
}
}
}
DrawFPS();
spriteBatch.End();
DisableSpriteBatches(graphics.GraphicsDevice);
base.Draw(gameTime);
}
// --------------------- EXPORT CLASS : Screen Saver -----------------------------------
private void AntiBurnScreenSaverBegin(GameTime gameTime)
{
spriteBatch.End();
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
ShaderParameters.btime.SetValue(gameTime.TotalRealTime.Seconds);
aburn.Begin();
aburn.CurrentTechnique.Passes[0].Begin();
}
private void AntiBurnScreenSaverEnd(GameTime gameTime)
{
aburn.CurrentTechnique.Passes[0].End();
aburn.End();
spriteBatch.End();
DisableSpriteBatches(graphics.GraphicsDevice);
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
}
// --------------------- EXPORT CLASS : Frame Rate Counter -----------------------------------
public void UpdateFPS(GameTime gameTime)
{
elapsedTime += gameTime.ElapsedGameTime;
if (elapsedTime > TimeSpan.FromSeconds(1))
{
elapsedTime -= TimeSpan.FromSeconds(1);
frameRate = frameCounter;
frameCounter = 0;
}
}
private void DrawFPS()
{
if (enableFPSDisplay)
{
frameCounter++;
fpsScreen.SetFPS(frameRate);
graphics.GraphicsDevice.Viewport = defaultViewport;
fpsScreen.Draw(spriteBatch);
}
}
// ---------------- Windowing -----------------------
protected override void OnDeactivated(object sender, EventArgs args)
{
// Set flag to disable controllers when window looses focus
base.OnDeactivated(sender, args);
WINDOW_IN_FOCUS = false;
}
protected override void OnActivated(object sender, EventArgs args)
{
// Set flag to enable controllers when window gains focus
base.OnActivated(sender, args);
WINDOW_IN_FOCUS = true;
}
// ---------------- System Checks --------------------------------
private void CheckExit()
{
if (gameState == GameState.EXIT)
{
// XML.SaveSystem();
gameFlow.StopRumble();
Logging.genReport(System.DateTime.Now);
Logging.saveLog(System.DateTime.Now);
//chatClient.CloseConnection();
this.Exit();
}
}
public static void CheckForControllers(int maxPlayers, GameFlow gameFlow)
{
int index = -1;
XML.SystemSettings.TOTAL_PLAYERS = 0;
for (PlayerIndex i = PlayerIndex.One; i <= PlayerIndex.Four && index+1 < maxPlayers; i++)
{
index++;
// Check if our gamepad is connected
if (GamePad.GetState(i).IsConnected)
{
// This player has not been initialized so increment number of players and create the new player.
XML.SystemSettings.TOTAL_PLAYERS++;
ResetViewports(XML.SystemSettings.TOTAL_PLAYERS, gameFlow);
gameFlow.objectLibrary.humans[index].playerController = new GameController(GameController.ControllerType.XBOX_ONLY,
i,
clientHeight,
clientWidth);
// Initialize the player as alive
gameFlow.objectLibrary.humans[index].health = 100;
gameFlow.objectLibrary.humans[index].manna = 100;
if (GameFlow.gameType == GameFlow.GameType.STORY_MODE)
{
if (XML.SystemSettings.TOTAL_PLAYERS == 1)
{
break;
}
}
}
}
#if !XBOX360
// This part is to setup the default keyboard player in case there are no controllers connected
if (XML.SystemSettings.TOTAL_PLAYERS == 0)
{
// We have one player the keyboard player
XML.SystemSettings.TOTAL_PLAYERS++;
// Create the player, PlayerIndex.One is passed as a default value and not used
ResetViewports(XML.SystemSettings.TOTAL_PLAYERS, gameFlow);
// If we are player 1 then we also have pc controls
gameFlow.objectLibrary.humans[0].playerController = new GameController(GameController.ControllerType.PC_ONLY,
PlayerIndex.One,
clientHeight,
clientWidth);
// Initialize the player as alive
gameFlow.objectLibrary.humans[0].health = 100;
gameFlow.objectLibrary.humans[0].manna = 100;
}
// If Player 1 has a controller make sure they are given the keyboard too
else if (XML.SystemSettings.TOTAL_PLAYERS >= 1)
{
if (gameFlow.objectLibrary.humans[0].playerController.playerControllerType == GameController.ControllerType.XBOX_ONLY)
{
gameFlow.objectLibrary.humans[0].playerController = new GameController(GameController.ControllerType.PC_AND_XBOX,
PlayerIndex.One,
clientHeight,
clientWidth);
}
else if (gameFlow.objectLibrary.humans[0].playerController.playerControllerType == GameController.ControllerType.NONE)
{
// Create the player, PlayerIndex.One is passed as a default value and not used
ResetViewports(XML.SystemSettings.TOTAL_PLAYERS, gameFlow);
// If we are player 1 then we also have pc controls
gameFlow.objectLibrary.humans[0].playerController = new GameController(GameController.ControllerType.PC_ONLY,
PlayerIndex.One,
clientHeight,
clientWidth);
// Initialize the player as alive
gameFlow.objectLibrary.humans[0].health = 100;
gameFlow.objectLibrary.humans[0].manna = 100;
}
}
#endif
}
public static void ResetViewports(int numPlayers, GameFlow gameFlow)
{
viewportList.Clear();
// All viewports needed for the players
Viewport newViewport = new Viewport();
int viewportWidth, viewportHeight;
// Divide the viewport based on number of players
if (numPlayers > 2)
{
// Divide width
viewportWidth = clientWidth / 2;
}
else
{
viewportWidth = clientWidth;
}
if (numPlayers > 1)
{
// Divide height
viewportHeight = clientHeight / 2;
}
else
{
viewportHeight = clientHeight;
}
// Assign each viewport its screen space
for (int i = 0; i < numPlayers; i++)
{
if (numPlayers > 2)
{
newViewport.X = (i % 2) * viewportWidth;
newViewport.Y = (i / 2) * viewportHeight;
}
else
{
newViewport.X = 0;
newViewport.Y = (i % 2) * viewportHeight;
}
newViewport.Width = viewportWidth;
newViewport.Height = viewportHeight;
newViewport.MinDepth = clientMinDepth;
newViewport.MaxDepth = clientMaxDepth;
// Set the targeting reticle for the player based on this viewport
gameFlow.objectLibrary.humans[i].CreateHUD(newViewport, content);
// Add to the global viewport list
viewportList.Add(newViewport);
}
}
// ---------------- Shutting Down -----------------------
public static void DisableSpriteBatches(GraphicsDevice graphicsDevice)
{
// Make sure culling is off
graphicsDevice.RenderState.CullMode = CullMode.None;
// Fix the render state post drawing sprite batch
graphicsDevice.RenderState.DepthBufferEnable = true;
graphicsDevice.RenderState.AlphaBlendEnable = false;
graphicsDevice.RenderState.AlphaTestEnable = false;
// Set the Texture addressing mode
graphicsDevice.SamplerStates[0].AddressU =
graphicsDevice.SamplerStates[0].AddressV =
graphicsDevice.SamplerStates[0].AddressW =
TextureAddressMode.Wrap;
}
protected override void UnloadGraphicsContent(bool unloadAllContent)
{
if (unloadAllContent == true)
{
// Garbage collector
content.Unload();
}
}
}
}