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