(61d00a474) v0.9.7.1
This commit is contained in:
@@ -0,0 +1,387 @@
|
||||
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;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class LoadingScreen
|
||||
{
|
||||
private readonly Texture2D defaultBackgroundTexture, overlay;
|
||||
private readonly SpriteSheet decorativeGraph, decorativeMap;
|
||||
private Texture2D currentBackgroundTexture;
|
||||
private Sprite noiseSprite;
|
||||
|
||||
private string randText = "";
|
||||
|
||||
private Sprite languageSelectionCursor;
|
||||
private ScalableFont languageSelectionFont, languageSelectionFontCJK;
|
||||
|
||||
private Video currSplashScreen;
|
||||
private DateTime videoStartTime;
|
||||
|
||||
public struct PendingSplashScreen
|
||||
{
|
||||
public string Filename;
|
||||
public float Gain;
|
||||
public PendingSplashScreen(string filename, float gain)
|
||||
{
|
||||
Filename = filename;
|
||||
Gain = gain;
|
||||
}
|
||||
}
|
||||
|
||||
private Queue<PendingSplashScreen> pendingSplashScreens = new Queue<PendingSplashScreen>();
|
||||
/// <summary>
|
||||
/// Triplet.first = filepath, Triplet.second = resolution, Triplet.third = audio gain
|
||||
/// </summary>
|
||||
public Queue<PendingSplashScreen> PendingSplashScreens
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (loadMutex)
|
||||
{
|
||||
return pendingSplashScreens;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (loadMutex)
|
||||
{
|
||||
pendingSplashScreens = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool PlayingSplashScreen
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (loadMutex)
|
||||
{
|
||||
return currSplashScreen != null || pendingSplashScreens.Count > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string selectedTip;
|
||||
|
||||
private readonly object loadMutex = new object();
|
||||
private float? loadState;
|
||||
|
||||
public float? LoadState
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (loadMutex)
|
||||
{
|
||||
return loadState;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (loadMutex)
|
||||
{
|
||||
loadState = value;
|
||||
DrawLoadingText = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool DrawLoadingText
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool WaitForLanguageSelection
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public LoadingScreen(GraphicsDevice graphics)
|
||||
{
|
||||
defaultBackgroundTexture = TextureLoader.FromFile("Content/Map/LocationPortraits/AlienRuins.png");
|
||||
|
||||
decorativeMap = new SpriteSheet("Content/Map/MapHUD.png", 6, 5, Vector2.Zero, sourceRect: new Rectangle(0, 0, 2048, 640));
|
||||
decorativeGraph = new SpriteSheet("Content/Map/MapHUD.png", 4, 10, Vector2.Zero, sourceRect: new Rectangle(1025, 1259, 1024, 732));
|
||||
|
||||
overlay = TextureLoader.FromFile("Content/UI/LoadingScreenOverlay.png");
|
||||
noiseSprite = new Sprite("Content/UI/noise.png", Vector2.Zero);
|
||||
DrawLoadingText = true;
|
||||
selectedTip = TextManager.Get("LoadingScreenTip", true);
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, GraphicsDevice graphics, float deltaTime)
|
||||
{
|
||||
if (GameMain.Config.EnableSplashScreen)
|
||||
{
|
||||
try
|
||||
{
|
||||
DrawSplashScreen(spriteBatch, graphics);
|
||||
if (currSplashScreen != null || PendingSplashScreens.Count > 0) { return; }
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Playing splash screen video failed", e);
|
||||
GameMain.Config.EnableSplashScreen = false;
|
||||
}
|
||||
}
|
||||
|
||||
var titleStyle = GUI.Style?.GetComponentStyle("TitleText");
|
||||
Sprite titleSprite = null;
|
||||
if (!WaitForLanguageSelection && titleStyle != null && titleStyle.Sprites.ContainsKey(GUIComponent.ComponentState.None))
|
||||
{
|
||||
titleSprite = titleStyle.Sprites[GUIComponent.ComponentState.None].First()?.Sprite;
|
||||
}
|
||||
|
||||
drawn = true;
|
||||
|
||||
currentBackgroundTexture ??= defaultBackgroundTexture;
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, samplerState: GUI.SamplerState);
|
||||
|
||||
float scale = (GameMain.GraphicsWidth / (float)currentBackgroundTexture.Width) * 1.2f;
|
||||
float paddingX = currentBackgroundTexture.Width * scale - GameMain.GraphicsWidth;
|
||||
float paddingY = currentBackgroundTexture.Height * scale - GameMain.GraphicsHeight;
|
||||
|
||||
double noiseT = (Timing.TotalTime * 0.02f);
|
||||
Vector2 pos = new Vector2((float)PerlinNoise.CalculatePerlin(noiseT, noiseT, 0) - 0.5f, (float)PerlinNoise.CalculatePerlin(noiseT, noiseT, 0.5f) - 0.5f);
|
||||
pos = new Vector2(pos.X * paddingX, pos.Y * paddingY);
|
||||
|
||||
spriteBatch.Draw(currentBackgroundTexture,
|
||||
new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2 + pos,
|
||||
null, Color.White, 0.0f, new Vector2(currentBackgroundTexture.Width / 2, currentBackgroundTexture.Height / 2),
|
||||
scale, SpriteEffects.None, 0.0f);
|
||||
|
||||
spriteBatch.Draw(overlay, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), null, Color.White, 0.0f, Vector2.Zero, SpriteEffects.None, 0.0f);
|
||||
|
||||
float noiseStrength = (float)PerlinNoise.CalculatePerlin(noiseT, noiseT, 0);
|
||||
float noiseScale = (float)PerlinNoise.CalculatePerlin(noiseT * 5.0f, noiseT * 2.0f, 0) * 4.0f;
|
||||
noiseSprite.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight),
|
||||
startOffset: new Point(Rand.Range(0, noiseSprite.SourceRect.Width), Rand.Range(0, noiseSprite.SourceRect.Height)),
|
||||
color: Color.White * noiseStrength * 0.1f,
|
||||
textureScale: Vector2.One * noiseScale);
|
||||
|
||||
titleSprite?.Draw(spriteBatch, new Vector2(GameMain.GraphicsWidth * 0.05f, GameMain.GraphicsHeight * 0.125f),
|
||||
Color.White, origin: new Vector2(0.0f, titleSprite.SourceRect.Height / 2.0f),
|
||||
scale: GameMain.GraphicsHeight / 2000.0f);
|
||||
|
||||
if (WaitForLanguageSelection)
|
||||
{
|
||||
DrawLanguageSelectionPrompt(spriteBatch, graphics);
|
||||
}
|
||||
else if (DrawLoadingText)
|
||||
{
|
||||
if (TextManager.Initialized)
|
||||
{
|
||||
string loadText;
|
||||
if (LoadState == 100.0f)
|
||||
{
|
||||
#if DEBUG
|
||||
if (GameMain.Config.AutomaticQuickStartEnabled && GameMain.FirstLoad)
|
||||
{
|
||||
loadText = "QUICKSTARTING ...";
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
loadText = TextManager.Get("PressAnyKey");
|
||||
#if DEBUG
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
loadText = TextManager.Get("Loading");
|
||||
if (LoadState != null)
|
||||
{
|
||||
loadText += " " + (int)LoadState + " %";
|
||||
}
|
||||
}
|
||||
if (GUI.LargeFont != null)
|
||||
{
|
||||
GUI.LargeFont.DrawString(spriteBatch, loadText.ToUpper(),
|
||||
new Vector2(GameMain.GraphicsWidth / 2.0f - GUI.LargeFont.MeasureString(loadText.ToUpper()).X / 2.0f, GameMain.GraphicsHeight * 0.75f),
|
||||
Color.White);
|
||||
}
|
||||
}
|
||||
|
||||
if (GUI.Font != null && selectedTip != null)
|
||||
{
|
||||
string wrappedTip = ToolBox.WrapText(selectedTip, GameMain.GraphicsWidth * 0.5f, GUI.Font);
|
||||
string[] lines = wrappedTip.Split('\n');
|
||||
float lineHeight = GUI.Font.MeasureString(selectedTip).Y;
|
||||
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
GUI.Font.DrawString(spriteBatch, lines[i],
|
||||
new Vector2((int)(GameMain.GraphicsWidth / 2.0f - GUI.Font.MeasureString(lines[i]).X / 2.0f), (int)(GameMain.GraphicsHeight * 0.8f + i * lineHeight)), Color.White);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
spriteBatch.End();
|
||||
|
||||
spriteBatch.Begin(blendState: BlendState.Additive);
|
||||
|
||||
Vector2 decorativeScale = new Vector2(GameMain.GraphicsHeight / 1080.0f);
|
||||
|
||||
float noiseVal = (float)PerlinNoise.CalculatePerlin(Timing.TotalTime * 0.25f, Timing.TotalTime * 0.5f, 0);
|
||||
decorativeGraph.Draw(spriteBatch, (int)(decorativeGraph.FrameCount * noiseVal),
|
||||
new Vector2(GameMain.GraphicsWidth * 0.001f, GameMain.GraphicsHeight * 0.24f),
|
||||
Color.White, Vector2.Zero, 0.0f, decorativeScale, SpriteEffects.FlipVertically);
|
||||
|
||||
decorativeMap.Draw(spriteBatch, (int)(decorativeMap.FrameCount * noiseVal),
|
||||
new Vector2(GameMain.GraphicsWidth * 0.99f, GameMain.GraphicsHeight * 0.66f),
|
||||
Color.White, decorativeMap.FrameSize.ToVector2(), 0.0f, decorativeScale);
|
||||
|
||||
if (noiseVal < 0.2f)
|
||||
{
|
||||
//SCP-CB reference
|
||||
randText = (new string[] { "NIL", "black white gray", "Sometimes we would have had time to scream", "e8m106]af", "NO" }).GetRandom();
|
||||
}
|
||||
else if (noiseVal < 0.3f)
|
||||
{
|
||||
randText = ToolBox.RandomSeed(9);
|
||||
}
|
||||
else if (noiseVal < 0.5f)
|
||||
{
|
||||
randText =
|
||||
Rand.Int(100).ToString().PadLeft(2, '0') + " " +
|
||||
Rand.Int(100).ToString().PadLeft(2, '0') + " " +
|
||||
Rand.Int(100).ToString().PadLeft(2, '0') + " " +
|
||||
Rand.Int(100).ToString().PadLeft(2, '0');
|
||||
}
|
||||
|
||||
GUI.LargeFont?.DrawString(spriteBatch, randText,
|
||||
new Vector2(GameMain.GraphicsWidth - decorativeMap.FrameSize.X * decorativeScale.X * 0.8f, GameMain.GraphicsHeight * 0.57f),
|
||||
Color.White * (1.0f - noiseVal));
|
||||
|
||||
spriteBatch.End();
|
||||
}
|
||||
|
||||
private void DrawLanguageSelectionPrompt(SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
|
||||
{
|
||||
if (languageSelectionFont == null)
|
||||
{
|
||||
languageSelectionFont = new ScalableFont("Content/Fonts/NotoSans/NotoSans-Bold.ttf",
|
||||
(uint)(30 * (GameMain.GraphicsHeight / 1080.0f)), graphicsDevice);
|
||||
}
|
||||
if (languageSelectionFontCJK == null)
|
||||
{
|
||||
languageSelectionFontCJK = new ScalableFont("Content/Fonts/NotoSans/NotoSansCJKsc-Bold.otf",
|
||||
(uint)(30 * (GameMain.GraphicsHeight / 1080.0f)), graphicsDevice, dynamicLoading: true);
|
||||
}
|
||||
if (languageSelectionCursor == null)
|
||||
{
|
||||
languageSelectionCursor = new Sprite("Content/UI/cursor.png", Vector2.Zero);
|
||||
}
|
||||
|
||||
Vector2 textPos = new Vector2(GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight * 0.3f);
|
||||
Vector2 textSpacing = new Vector2(0.0f, (GameMain.GraphicsHeight * 0.5f) / TextManager.AvailableLanguages.Count());
|
||||
foreach (string language in TextManager.AvailableLanguages)
|
||||
{
|
||||
string localizedLanguageName = TextManager.GetTranslatedLanguageName(language);
|
||||
var font = TextManager.IsCJK(localizedLanguageName) ? languageSelectionFontCJK : languageSelectionFont;
|
||||
|
||||
Vector2 textSize = font.MeasureString(localizedLanguageName);
|
||||
bool hover =
|
||||
Math.Abs(PlayerInput.MousePosition.X - textPos.X) < textSize.X / 2 &&
|
||||
Math.Abs(PlayerInput.MousePosition.Y - textPos.Y) < textSpacing.Y / 2;
|
||||
|
||||
font.DrawString(spriteBatch, localizedLanguageName, textPos - textSize / 2,
|
||||
hover ? Color.White : Color.White * 0.6f);
|
||||
if (hover && PlayerInput.PrimaryMouseButtonClicked())
|
||||
{
|
||||
GameMain.Config.Language = language;
|
||||
//reload tip in the selected language
|
||||
selectedTip = TextManager.Get("LoadingScreenTip", true);
|
||||
GameMain.Config.SetDefaultBindings(legacy: false);
|
||||
GameMain.Config.CheckBindings(useDefaults: true);
|
||||
WaitForLanguageSelection = false;
|
||||
languageSelectionFont?.Dispose(); languageSelectionFont = null;
|
||||
languageSelectionFontCJK?.Dispose(); languageSelectionFontCJK = null;
|
||||
break;
|
||||
}
|
||||
|
||||
textPos += textSpacing;
|
||||
}
|
||||
|
||||
languageSelectionCursor.Draw(spriteBatch, PlayerInput.LatestMousePosition, scale: 0.5f);
|
||||
}
|
||||
|
||||
private void DrawSplashScreen(SpriteBatch spriteBatch, GraphicsDevice graphics)
|
||||
{
|
||||
if (currSplashScreen == null && PendingSplashScreens.Count == 0) { return; }
|
||||
|
||||
if (currSplashScreen == null)
|
||||
{
|
||||
var newSplashScreen = PendingSplashScreens.Dequeue();
|
||||
string fileName = newSplashScreen.Filename;
|
||||
try
|
||||
{
|
||||
currSplashScreen = Video.Load(graphics, GameMain.SoundManager, fileName);
|
||||
currSplashScreen.AudioGain = newSplashScreen.Gain;
|
||||
videoStartTime = DateTime.Now;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
GameMain.Config.EnableSplashScreen = false;
|
||||
DebugConsole.ThrowError("Playing the splash screen \"" + fileName + "\" failed.", e);
|
||||
PendingSplashScreens.Clear();
|
||||
currSplashScreen = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (currSplashScreen.IsPlaying)
|
||||
{
|
||||
spriteBatch.Begin();
|
||||
spriteBatch.Draw(currSplashScreen.GetTexture(), new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
|
||||
spriteBatch.End();
|
||||
|
||||
if (DateTime.Now > videoStartTime + new TimeSpan(0, 0, 0, 0, milliseconds: 500) && GameMain.WindowActive && (PlayerInput.KeyHit(Keys.Space) || PlayerInput.KeyHit(Keys.Enter) || PlayerInput.PrimaryMouseButtonDown()))
|
||||
{
|
||||
currSplashScreen.Dispose(); currSplashScreen = null;
|
||||
}
|
||||
}
|
||||
else if (DateTime.Now > videoStartTime + new TimeSpan(0, 0, 0, 0, milliseconds: 1500))
|
||||
{
|
||||
currSplashScreen.Dispose(); currSplashScreen = null;
|
||||
}
|
||||
}
|
||||
|
||||
bool drawn;
|
||||
public IEnumerable<object> DoLoading(IEnumerable<object> loader)
|
||||
{
|
||||
drawn = false;
|
||||
LoadState = null;
|
||||
selectedTip = TextManager.Get("LoadingScreenTip", true);
|
||||
currentBackgroundTexture = LocationType.List.GetRandom()?.GetPortrait(Rand.Int(int.MaxValue))?.Texture;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user