using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System; using System.Collections.Generic; using System.Xml.Linq; using Barotrauma.Media; namespace Barotrauma { class LoadingScreen { private Texture2D backgroundTexture, monsterTexture, titleTexture; private RenderTarget2D renderTarget; private Video splashScreen; public Video SplashScreen { get { lock (loadMutex) { return splashScreen; } } set { lock (loadMutex) { splashScreen = value; } } } private float state; private string selectedTip; public Vector2 CenterPosition; public Vector2 TitlePosition; private object loadMutex = new object(); private float? loadState; public Vector2 TitleSize { get { return new Vector2(titleTexture.Width, titleTexture.Height); } } public float Scale { get; private set; } public float? LoadState { get { lock (loadMutex) { return loadState; } } set { lock (loadMutex) { loadState = value; DrawLoadingText = true; } } } public bool DrawLoadingText { get; set; } public LoadingScreen(GraphicsDevice graphics) { backgroundTexture = TextureLoader.FromFile("Content/UI/titleBackground.png"); monsterTexture = TextureLoader.FromFile("Content/UI/titleMonster.png"); titleTexture = TextureLoader.FromFile("Content/UI/titleText.png"); renderTarget = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); GameMain.Instance.OnResolutionChanged += () => { renderTarget?.Dispose(); renderTarget = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); }; DrawLoadingText = true; selectedTip = TextManager.Get("LoadingScreenTip", true); } public void Draw(SpriteBatch spriteBatch, GraphicsDevice graphics, float deltaTime) { if (GameMain.Config.EnableSplashScreen) { try { DrawSplashScreen(spriteBatch); if (SplashScreen!=null && SplashScreen.IsPlaying) return; } catch (Exception e) { DebugConsole.ThrowError("Playing splash screen video failed", e); GameMain.Config.EnableSplashScreen = false; } } drawn = true; graphics.SetRenderTarget(renderTarget); Scale = GameMain.GraphicsHeight / 1500.0f; state += deltaTime; if (DrawLoadingText) { CenterPosition = new Vector2(GameMain.GraphicsWidth * 0.3f, GameMain.GraphicsHeight / 2.0f); TitlePosition = CenterPosition + new Vector2(-0.0f + (float)Math.Sqrt(state) * 220.0f, 0.0f) * Scale; TitlePosition.X = Math.Min(TitlePosition.X, (float)GameMain.GraphicsWidth / 2.0f); } spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend); graphics.Clear(Color.Black); spriteBatch.Draw(backgroundTexture, CenterPosition, null, Color.White * Math.Min(state / 5.0f, 1.0f), 0.0f, new Vector2(backgroundTexture.Width / 2.0f, backgroundTexture.Height / 2.0f), Scale * 1.5f, SpriteEffects.None, 0.2f); spriteBatch.Draw(monsterTexture, CenterPosition + new Vector2((state % 40) * 100.0f - 1800.0f, (state % 40) * 30.0f - 200.0f) * Scale, null, Color.White, 0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0.1f); spriteBatch.Draw(titleTexture, TitlePosition, null, Color.White * Math.Min((state - 1.0f) / 5.0f, 1.0f), 0.0f, new Vector2(titleTexture.Width / 2.0f, titleTexture.Height / 2.0f), Scale, SpriteEffects.None, 0.0f); spriteBatch.End(); graphics.SetRenderTarget(null); if (WaterRenderer.Instance != null) { WaterRenderer.Instance.ScrollWater(Vector2.One * 10.0f, deltaTime); WaterRenderer.Instance.RenderWater(spriteBatch, renderTarget, null); } spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend); spriteBatch.Draw(titleTexture, TitlePosition, null, Color.White * Math.Min((state - 3.0f) / 5.0f, 1.0f), 0.0f, new Vector2(titleTexture.Width / 2.0f, titleTexture.Height / 2.0f), Scale, SpriteEffects.None, 0.0f); if (DrawLoadingText) { string loadText = ""; if (LoadState == 100.0f) { loadText = TextManager.Get("PressAnyKey"); } else { loadText = TextManager.Get("Loading"); if (LoadState != null) { loadText += " " + (int)LoadState + " %"; } } if (GUI.LargeFont != null) { GUI.LargeFont.DrawString(spriteBatch, loadText, new Vector2(GameMain.GraphicsWidth / 2.0f - GUI.LargeFont.MeasureString(loadText).X / 2.0f, GameMain.GraphicsHeight * 0.7f), Color.White); } if (GUI.Font != null && selectedTip != null) { string wrappedTip = ToolBox.WrapText(selectedTip, GameMain.GraphicsWidth * 0.5f, GUI.Font); string[] lines = wrappedTip.Split('\n'); for (int i = 0; i < lines.Length; i++) { GUI.Font.DrawString(spriteBatch, lines[i], new Vector2(GameMain.GraphicsWidth / 2.0f - GUI.Font.MeasureString(lines[i]).X / 2.0f, GameMain.GraphicsHeight * 0.78f + i * 15), Color.White); } } } spriteBatch.End(); } private void DrawSplashScreen(SpriteBatch spriteBatch) { if (SplashScreen != null) { if (SplashScreen.IsPlaying) { spriteBatch.Begin(); spriteBatch.Draw(SplashScreen.GetTexture(), new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White); spriteBatch.End(); if (PlayerInput.KeyHit(Keys.Space) || PlayerInput.KeyHit(Keys.Enter) || PlayerInput.LeftButtonDown()) { SplashScreen.Dispose(); SplashScreen = null; } } else { SplashScreen.Dispose(); SplashScreen = null; } } } bool drawn; public IEnumerable DoLoading(IEnumerable loader) { drawn = false; LoadState = null; selectedTip = TextManager.Get("LoadingScreenTip", true); while (!drawn) { yield return CoroutineStatus.Running; } CoroutineManager.StartCoroutine(loader); yield return CoroutineStatus.Running; while (CoroutineManager.IsCoroutineRunning(loader.ToString())) { yield return CoroutineStatus.Running; } LoadState = 100.0f; yield return CoroutineStatus.Success; } } }