internal void Update(GameTime gameTime) { Game.Instance.Profiler.BeginSection("menu_update"); double at = gameTime.TotalGameTime.TotalMilliseconds; int i = 0; while (i < 3 && !GamePad.GetState((PlayerIndex)i).IsConnected) { i++; } GamePadState gamePadState = GamePad.GetState((PlayerIndex)i); KeyboardState keyboardState = Keyboard.GetState(); //StaticStringStrength.Update(gameTime.TotalRealTime.TotalMilliseconds); StaticStringStrength.Update(gameTime.TotalGameTime.TotalMilliseconds); if (active) { MenuScreen currentActiveScreen = activeScreen; activeScreen.Update(gameTime); if (at > buttonPressedAt + Menu.ButtonRepeatTimeout) { if ((gamePadState.Buttons.Start == ButtonState.Pressed && lastGPState.Buttons.Start == ButtonState.Released) || (keyboardState.IsKeyDown(Keys.Escape) && lastKBState.IsKeyUp(Keys.Escape))) { Close(); buttonPressedAt = at; } else if ((gamePadState.Buttons.B == ButtonState.Pressed && lastGPState.Buttons.B == ButtonState.Released) || (keyboardState.IsKeyDown(Keys.Back) && lastKBState.IsKeyUp(Keys.Back))) { CloseActiveMenuScreen(true); buttonPressedAt = at; } else if ((gamePadState.Buttons.Y == ButtonState.Pressed && lastGPState.Buttons.Y == ButtonState.Released)) { Hidden = true; } else if ((gamePadState.Buttons.Y == ButtonState.Released && lastGPState.Buttons.Y == ButtonState.Pressed)) { Hidden = false; } } if (currentActiveScreen != activeScreen) { activeScreen.Update(gameTime); } } else { if (at > buttonPressedAt + Menu.ButtonRepeatTimeout && ((gamePadState.Buttons.Start == ButtonState.Pressed && lastGPState.Buttons.Start == ButtonState.Released) || (keyboardState.IsKeyDown(Keys.Escape) && lastKBState.IsKeyUp(Keys.Escape)))) { Game.Instance.Pause(); Open(); buttonPressedAt = at; } else { // resume simulation as soon as button we used to close is released (so we don't accidentally fire) if (Game.Instance.Paused && waitForButtonRelease && gamePadState.Buttons.B == ButtonState.Released && gamePadState.Buttons.A == ButtonState.Released) { Game.Instance.Resume(); waitForButtonRelease = false; } } } lastGPState = gamePadState; Game.Instance.Profiler.EndSection("menu_update"); }
internal void Draw(GameTime gameTime) { if (Active && !Hidden) { int screenWidth = Game.Instance.GraphicsDevice.Viewport.Width; float screenscale = (float)screenWidth / 1280f; Matrix spriteScale = Matrix.CreateScale(screenscale, screenscale, 1); spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, spriteScale); spriteBatch.Draw(background, new Vector2(0, 0), new Color(125, 125, 125, 160)); // first traversal: sum up total width of all screens int totalWidth = 0; foreach (MenuScreen screen in screens) { if (screen is ItemizedMenuScreen) { totalWidth += (screen as ItemizedMenuScreen).Width; } } // second traversal (backwards): compute individual x offsets and draw the screens int offset = 0; LinkedListNode <MenuScreen> node = screens.Last; do { MenuScreen screen = node.Value; screen.DrawOffset.TargetValue = offset + totalWidth / 2; if (screen is ItemizedMenuScreen) { (screen as ItemizedMenuScreen).Active = (screen == screens.Last.Value); screen.DrawOffset.TargetValue -= (screens.Last.Value as ItemizedMenuScreen).Width / 2; } //screen.DrawOffset.TargetValue = offset + totalWidth/2 - (screens.Last.Value as ItemizedMenuScreen).Width/2; screen.Draw(gameTime, spriteBatch); if (screen is ItemizedMenuScreen) { offset -= (screen as ItemizedMenuScreen).Width; } node = node.Previous; if (!screen.DrawPrevious) { break; } }while (node != null); // HACK: retrospectively, this DrawPrevious thing was a stupid idea. whoever wants to // refactor this at some point, should get rid of this property and such ugly conditionals. if ((screens.Last.Value is ItemizedMenuScreen && (screens.Last.Value as ItemizedMenuScreen).DrawPrevious) || (screens.Last.Value is PlayerMenu)) { DrawStaticStrings(); } spriteBatch.End(); } }