//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {License Information: Creative Commons}
//---------------------------------------------------------------------------------------------------------------------------------------------------
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
///
/// This is the main type for your game
///
///
public class ElementalGame : Microsoft.Xna.Framework.Game
{
// Graphics manager
public static GraphicsDeviceManager graphics;
public static ContentManager content;
public static SpriteBatch spriteBatch;
public static Stopwatch jiggler;
// Fullscreen toggle switch
public static bool SHADER3_NOT_SUPPORTED = false; // No compatible graphics card
public static bool WINDOW_IN_FOCUS = true; // Disable mouse on window losing focus
public static Viewport defaultViewport = new Viewport(); // Default viewport that takes up the whole screen
public static List viewportList = new List(); // Window viewports (for multiplayer)
// Window Size
public static int clientWidth, clientHeight;
public static float clientMinDepth, clientMaxDepth;
public static float dt;
public static MenuSystem menuSystem;
public static bool drewLoadScreen = false;
public static GameTime elementalGameTime;
public static GraphicsDeviceCapabilities caps;
public static bool enableFPSDisplay;
public static int currentPlayerIndex = 0;
public static bool loadDarkMatter = false;
// Keep track of menu and game modes
public enum GameState
{
NOT_SUPPORTED,
INTRO_SCREEN,
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;
public static int playerThatPaused = -1;
// Main Game Loop
GameFlow gameFlow;
private ShaderParameters shaderParameters;
private Effect aburn;
private FPS fpsScreen;
private int frameRate = 0;
private int frameCounter = 0;
private TimeSpan elapsedTime = TimeSpan.Zero;
private GameController Player1Controller = new GameController();
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));
}
// ------------------- Loading Up Procedures -------------------
protected override void Initialize()
{
// Check the display mode to see how big the resolution
int displayWidth = graphics.GraphicsDevice.DisplayMode.Width;
int displayHeight = graphics.GraphicsDevice.DisplayMode.Height;
ElementalGame.jiggler = Stopwatch.StartNew();
#if XBOX360
//if (displayWidth > 1280)
//{
// displayWidth = 1280;
// float ratio = (1.0f * displayWidth) / (1.0f * displayHeight);
// if (ratio > 1.5)
// {
// //widescreen
// displayHeight = 720;
// }
// else
// {
// //non-widescreen
// displayHeight = 1024;
// }
//}
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;
}
}
//hijack resolution
//XML.SystemSettings.GAME_WINDOW_WIDTH = 1024;
//XML.SystemSettings.GAME_WINDOW_HEIGHT = 768;
#endif
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();
}
protected override void LoadGraphicsContent(bool loadAllContent)
{
Audio.PlayTitleSong();
}
public void LoadGame(bool loadAllContent)
{
}
// ----------------- Update Functions ------------------------------
protected override void Update(GameTime gameTime)
{
dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
if (loadDarkMatter)
{
loadDarkMatter = false;
gameFlow.objectLibrary.LoadDarkMatter();
gameFlow.objectLibrary.LoadMatter();
}
if (gameState == GameState.GAME_MODE)
{
// Update the game
gameFlow.Update(menuSystem);
}
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);
//block player one too
gameFlow.objectLibrary.humans[0].playerController.SetBlockStartBackInput(true);
}
// Get controller input and update the menu system
menuSystem.CheckMenuChange(graphics, content, Player1Controller, gameFlow);
// Check for user exit request
CheckExit();
// Crank the audio engine
Audio.Update();
base.Update(gameTime);
}
// --------------------- Draw -----------------------------------
protected override void Draw(GameTime gameTime)
{
if (enableFPSDisplay)
{
UpdateFPS(gameTime);
}
elementalGameTime = gameTime; // Needed for animation
// Clear the device
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, viewportList, menuSystem);
}
if (gameState != GameState.GAME_MODE)
{
graphics.GraphicsDevice.Viewport = defaultViewport;
// Draw the appropriate Menu Screen
if (gameState == GameState.NOT_SUPPORTED)
{
//Can't play game :(
menuSystem.sorryScreen.Draw();
}
else if (gameState == GameState.INTRO_SCREEN)
{
// Play appropriate cutscene
if (GameRules.cutSceneIndex == 0)
{
//Audio.PlayLevelSong("cutScene1");
menuSystem.scene1.Draw();
}
if (GameRules.cutSceneIndex == 1)
{
//Audio.PlayLevelSong("cutScene2");
menuSystem.scene2.Draw();
}
if (GameRules.cutSceneIndex == 2)
{
//Audio.PlayLevelSong("cutScene3");
menuSystem.scene3.Draw();
}
if (GameRules.cutSceneIndex == 3)
{
//Audio.PlayLevelSong("cutScene4");
menuSystem.scene4.Draw();
}
if (GameRules.cutSceneIndex == 4)
{
//Audio.PlayLevelSong("cutScene5");
menuSystem.scene5.Draw();
}
}
else if (gameState == GameState.CONTROL_SCREEN)
{
if (ElementalGame.jiggler.ElapsedMilliseconds > XML.SystemSettings.ANTI_BURN_TIMER)
{
AntiBurnScreenSaverBegin(gameTime);
menuSystem.controlsScreen.Draw();
AntiBurnScreenSaverEnd(gameTime);
}
else
{
menuSystem.controlsScreen.Draw();
}
}
else if (gameState == GameState.CONFIRM_EXIT)
{
if (ElementalGame.jiggler.ElapsedMilliseconds > XML.SystemSettings.ANTI_BURN_TIMER)
{
AntiBurnScreenSaverBegin(gameTime);
menuSystem.confirmExitScreen.Draw();
AntiBurnScreenSaverEnd(gameTime);
}
else
{
menuSystem.confirmExitScreen.Draw();
}
}
else if (gameState == GameState.CREDITS)
{
menuSystem.creditsScreen.Draw();
}
else if (gameState == GameState.TITLE_SCREEN)
{
if (ElementalGame.jiggler.ElapsedMilliseconds > XML.SystemSettings.ANTI_BURN_TIMER)
{
AntiBurnScreenSaverBegin(gameTime);
menuSystem.titleScreen.Draw();
AntiBurnScreenSaverEnd(gameTime);
}
else
{
menuSystem.titleScreen.Draw();
}
}
else if (gameState == GameState.GAME_SETUP)
{
if (ElementalGame.jiggler.ElapsedMilliseconds > XML.SystemSettings.ANTI_BURN_TIMER)
{
AntiBurnScreenSaverBegin(gameTime);
menuSystem.gameSetup.Draw();
AntiBurnScreenSaverEnd(gameTime);
}
else
{
menuSystem.gameSetup.Draw();
}
}
else if (gameState == GameState.LEVEL_SETUP)
{
gameFlow.DrawTerrainDemo(graphics.GraphicsDevice);
graphics.GraphicsDevice.Viewport = defaultViewport;
menuSystem.levelSetup.Draw();
}
else if (gameState == GameState.LOAD_LEVEL)
{
menuSystem.loadScreen.Draw();
drewLoadScreen = true;
}
else if (gameState == GameState.PLAYER_SETUP)
{
gameFlow.DrawPlayerDemo(graphics.GraphicsDevice, currentPlayerIndex);
graphics.GraphicsDevice.Viewport = defaultViewport;
menuSystem.playerSetup.Draw();
}
else if (gameState == GameState.GAME_OVER)
{
menuSystem.gameOverScreen.Draw();
}
else if (gameState == GameState.GAME_PAUSE)
{
if (ElementalGame.jiggler.ElapsedMilliseconds > XML.SystemSettings.ANTI_BURN_TIMER)
{
AntiBurnScreenSaverBegin(gameTime);
menuSystem.pauseScreen.Draw();
AntiBurnScreenSaverEnd(gameTime);
}
else
{
menuSystem.pauseScreen.Draw();
}
}
}
DrawFPS();
spriteBatch.End();
DisableSpriteBatches(graphics.GraphicsDevice);
base.Draw(gameTime);
}
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);
}
// Required to disable all the stuff that using a sprite batch resets
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;
}
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();
}
}
// ---------------- Shutting Down Procedures -----------------------
protected override void UnloadGraphicsContent(bool unloadAllContent)
{
if (unloadAllContent == true)
{
// Two words.... garbage collector
content.Unload();
}
}
// ---------------- System Checks --------------------------------
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)
{
/*
// Check if we have already initialized this player and controller
if (gameFlow.objectLibrary.humans[index].playerController.playerControllerType != GameController.ControllerType.NONE)
{
if (index == 0)
{
// If we are player 1 we may already be initialized but the controller may not be setup
// If playerControllerType == 0 the controller has not been initialized
if (gameFlow.objectLibrary.humans[index].playerController.playerControllerType == GameController.ControllerType.PC_ONLY)
{
gameFlow.objectLibrary.humans[index].playerController = new GameController(GameController.ControllerType.PC_AND_XBOX, i,
* clientHeight, clientWidth);
}
}
// Check next controller
// Continue to the next PlayerIndex in the for loop
continue;
}*/
// 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)
{
// PROBLEM the others are initialized but player 1 is not
// We have one player the keyboard player
//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;
}
}
#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);
}
}
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;
}
private void CheckExit()
{
if (gameState == GameState.EXIT)
{
XML.SaveSystem();
gameFlow.StopAllSoundsAndRumble();
Logging.genReport(System.DateTime.Now);
Logging.saveLog(System.DateTime.Now);
this.Exit();
}
}
}
}