//--------------------------------------------------------------------------------------------------------------------------------------------------- // // 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(); } } } }