Updated to MonoGame 3.6 + Directory refactor
- Barotrauma's projects are in the Barotrauma directory - All libraries are in the Libraries directory - MonoGame is now managed by NuGet, rather than referenced from the installed files (TODO: consider using PCL for easier cross-platform development?) - NuGet libraries are not included in the repo, as getting the latest versions automatically should be preferred - Removed Content/effects.mgfx as it didn't seem to be used anywhere - Removed some references to Subsurface directory - Renamed Launcher2 to Launcher
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class CompareSegmentPointCW : IComparer<Lights.SegmentPoint>
|
||||
{
|
||||
private Vector2 center;
|
||||
|
||||
public CompareSegmentPointCW(Vector2 center)
|
||||
{
|
||||
this.center = center;
|
||||
}
|
||||
public int Compare(Lights.SegmentPoint a, Lights.SegmentPoint b)
|
||||
{
|
||||
return -CompareCCW.Compare(a.WorldPos, b.WorldPos, center);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public partial class SaveUtil
|
||||
{
|
||||
public static void SaveGame(string fileName)
|
||||
{
|
||||
fileName = Path.Combine(SaveFolder, fileName);
|
||||
|
||||
string tempPath = Path.Combine(SaveFolder, "temp");
|
||||
|
||||
Directory.CreateDirectory(tempPath);
|
||||
try
|
||||
{
|
||||
ClearFolder(tempPath, new string[] { GameMain.GameSession.Submarine.FilePath });
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Submarine.MainSub != null && Submarine.Loaded.Contains(Submarine.MainSub))
|
||||
{
|
||||
Submarine.MainSub.FilePath = Path.Combine(tempPath, Submarine.MainSub.Name + ".sub");
|
||||
Submarine.MainSub.SaveAs(Submarine.MainSub.FilePath);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error saving submarine", e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
GameMain.GameSession.Save(Path.Combine(tempPath, "gamesession.xml"));
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error saving gamesession", e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
CompressDirectory(tempPath, fileName+".save", null);
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error compressing save file", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadGame(string fileName)
|
||||
{
|
||||
string filePath = Path.Combine(SaveFolder, fileName+".save");
|
||||
|
||||
DecompressToDirectory(filePath, TempPath, null);
|
||||
|
||||
XDocument doc = ToolBox.TryLoadXml(Path.Combine(TempPath, "gamesession.xml"));
|
||||
|
||||
string subPath = Path.Combine(TempPath, ToolBox.GetAttributeString(doc.Root, "submarine", ""))+".sub";
|
||||
Submarine selectedMap = new Submarine(subPath, "");// Submarine.Load();
|
||||
GameMain.GameSession = new GameSession(selectedMap, fileName, doc);
|
||||
|
||||
//Directory.Delete(tempPath, true);
|
||||
}
|
||||
|
||||
public static XDocument LoadGameSessionDoc(string fileName)
|
||||
{
|
||||
string filePath = Path.Combine(SaveFolder, fileName + ".save");
|
||||
|
||||
string tempPath = Path.Combine(SaveFolder, "temp");
|
||||
|
||||
try
|
||||
{
|
||||
DecompressToDirectory(filePath, tempPath, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ToolBox.TryLoadXml(Path.Combine(tempPath, "gamesession.xml"));
|
||||
}
|
||||
|
||||
public static void DeleteSave(string fileName)
|
||||
{
|
||||
fileName = Path.Combine(SaveFolder, fileName + ".save");
|
||||
|
||||
try
|
||||
{
|
||||
File.Delete(fileName);
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("ERROR: deleting save file \""+fileName+" failed.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static string[] GetSaveFiles()
|
||||
{
|
||||
if (!Directory.Exists(SaveFolder))
|
||||
{
|
||||
DebugConsole.ThrowError("Save folder \"" + SaveFolder + " not found! Attempting to create a new folder");
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(SaveFolder);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to create the folder \"" + SaveFolder + "\"!", e);
|
||||
}
|
||||
}
|
||||
|
||||
string[] files = Directory.GetFiles(SaveFolder, "*.save");
|
||||
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
{
|
||||
files[i] = Path.GetFileNameWithoutExtension(files[i]);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
public static string CreateSavePath(string fileName="Save")
|
||||
{
|
||||
if (!Directory.Exists(SaveFolder))
|
||||
{
|
||||
DebugConsole.ThrowError("Save folder \""+SaveFolder+"\" not found. Created new folder");
|
||||
Directory.CreateDirectory(SaveFolder);
|
||||
}
|
||||
|
||||
string extension = ".save";
|
||||
string pathWithoutExtension = Path.Combine(SaveFolder, fileName);
|
||||
|
||||
int i = 0;
|
||||
while (File.Exists(pathWithoutExtension + " " + i + extension))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
return fileName + " " + i;
|
||||
}
|
||||
|
||||
public static void CompressStringToFile(string fileName, string value)
|
||||
{
|
||||
// A.
|
||||
// Write string to temporary file.
|
||||
string temp = Path.GetTempFileName();
|
||||
File.WriteAllText(temp, value);
|
||||
|
||||
// B.
|
||||
// Read file into byte array buffer.
|
||||
byte[] b;
|
||||
using (FileStream f = new FileStream(temp, FileMode.Open))
|
||||
{
|
||||
b = new byte[f.Length];
|
||||
f.Read(b, 0, (int)f.Length);
|
||||
}
|
||||
|
||||
// C.
|
||||
// Use GZipStream to write compressed bytes to target file.
|
||||
using (FileStream f2 = new FileStream(fileName, FileMode.Create))
|
||||
using (GZipStream gz = new GZipStream(f2, CompressionMode.Compress, false))
|
||||
{
|
||||
gz.Write(b, 0, b.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public static void CompressFile(string sDir, string sRelativePath, GZipStream zipStream)
|
||||
{
|
||||
//Compress file name
|
||||
char[] chars = sRelativePath.ToCharArray();
|
||||
zipStream.Write(BitConverter.GetBytes(chars.Length), 0, sizeof(int));
|
||||
foreach (char c in chars)
|
||||
zipStream.Write(BitConverter.GetBytes(c), 0, sizeof(char));
|
||||
|
||||
//Compress file content
|
||||
byte[] bytes = File.ReadAllBytes(Path.Combine(sDir, sRelativePath));
|
||||
zipStream.Write(BitConverter.GetBytes(bytes.Length), 0, sizeof(int));
|
||||
zipStream.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
public static void CompressDirectory(string sInDir, string sOutFile, ProgressDelegate progress)
|
||||
{
|
||||
string[] sFiles = Directory.GetFiles(sInDir, "*.*", SearchOption.AllDirectories);
|
||||
int iDirLen = sInDir[sInDir.Length - 1] == Path.DirectorySeparatorChar ? sInDir.Length : sInDir.Length + 1;
|
||||
|
||||
using (FileStream outFile = new FileStream(sOutFile, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
using (GZipStream str = new GZipStream(outFile, CompressionMode.Compress))
|
||||
foreach (string sFilePath in sFiles)
|
||||
{
|
||||
string sRelativePath = sFilePath.Substring(iDirLen);
|
||||
if (progress != null)
|
||||
progress(sRelativePath);
|
||||
CompressFile(sInDir, sRelativePath, str);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ClearFolder(string FolderName, string[] ignoredFiles = null)
|
||||
{
|
||||
DirectoryInfo dir = new DirectoryInfo(FolderName);
|
||||
|
||||
foreach (FileInfo fi in dir.GetFiles())
|
||||
{
|
||||
bool ignore = false;
|
||||
foreach (string ignoredFile in ignoredFiles)
|
||||
{
|
||||
if (Path.GetFullPath(fi.FullName).Equals(Path.GetFullPath(ignoredFile)))
|
||||
{
|
||||
ignore = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ignore) continue;
|
||||
|
||||
fi.IsReadOnly = false;
|
||||
fi.Delete();
|
||||
}
|
||||
|
||||
foreach (DirectoryInfo di in dir.GetDirectories())
|
||||
{
|
||||
ClearFolder(di.FullName, ignoredFiles);
|
||||
di.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using System.IO;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Color = Microsoft.Xna.Framework.Color;
|
||||
using System;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// Based on http://jakepoz.com/jake_poznanski__background_load_xna.html
|
||||
/// </summary>
|
||||
public static class TextureLoader
|
||||
{
|
||||
static TextureLoader()
|
||||
{
|
||||
|
||||
BlendColorBlendState = new BlendState
|
||||
{
|
||||
ColorDestinationBlend = Blend.Zero,
|
||||
ColorWriteChannels = ColorWriteChannels.Red | ColorWriteChannels.Green | ColorWriteChannels.Blue,
|
||||
AlphaDestinationBlend = Blend.Zero,
|
||||
AlphaSourceBlend = Blend.SourceAlpha,
|
||||
ColorSourceBlend = Blend.SourceAlpha
|
||||
};
|
||||
|
||||
BlendAlphaBlendState = new BlendState
|
||||
{
|
||||
ColorWriteChannels = ColorWriteChannels.Alpha,
|
||||
AlphaDestinationBlend = Blend.Zero,
|
||||
ColorDestinationBlend = Blend.Zero,
|
||||
AlphaSourceBlend = Blend.One,
|
||||
ColorSourceBlend = Blend.One
|
||||
};
|
||||
}
|
||||
|
||||
public static void Init(GraphicsDevice graphicsDevice, bool needsBmp = false)
|
||||
{
|
||||
_graphicsDevice = graphicsDevice;
|
||||
_needsBmp = needsBmp;
|
||||
_spriteBatch = new SpriteBatch(_graphicsDevice);
|
||||
}
|
||||
|
||||
public static Texture2D FromFile(string path, bool preMultiplyAlpha = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
using (Stream fileStream = File.OpenRead(path))
|
||||
{
|
||||
var texture = Texture2D.FromStream(_graphicsDevice, fileStream);
|
||||
texture = PreMultiplyAlpha(texture);
|
||||
return texture;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Loading texture \""+path+"\" failed!", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Texture2D PreMultiplyAlpha(Texture2D texture)
|
||||
{
|
||||
// Setup a render target to hold our final texture which will have premulitplied alpha values
|
||||
using (RenderTarget2D renderTarget = new RenderTarget2D(_graphicsDevice, texture.Width, texture.Height))
|
||||
{
|
||||
Viewport viewportBackup = _graphicsDevice.Viewport;
|
||||
_graphicsDevice.SetRenderTarget(renderTarget);
|
||||
_graphicsDevice.Clear(Color.Black);
|
||||
|
||||
// Multiply each color by the source alpha, and write in just the color values into the final texture
|
||||
_spriteBatch.Begin(SpriteSortMode.Immediate, BlendColorBlendState);
|
||||
_spriteBatch.Draw(texture, texture.Bounds, Color.White);
|
||||
_spriteBatch.End();
|
||||
|
||||
// Now copy over the alpha values from the source texture to the final one, without multiplying them
|
||||
_spriteBatch.Begin(SpriteSortMode.Immediate, BlendAlphaBlendState);
|
||||
_spriteBatch.Draw(texture, texture.Bounds, Color.White);
|
||||
_spriteBatch.End();
|
||||
|
||||
// Release the GPU back to drawing to the screen
|
||||
_graphicsDevice.SetRenderTarget(null);
|
||||
_graphicsDevice.Viewport = viewportBackup;
|
||||
|
||||
// Store data from render target because the RenderTarget2D is volatile
|
||||
Color[] data = new Color[texture.Width * texture.Height];
|
||||
renderTarget.GetData(data);
|
||||
|
||||
// Unset texture from graphic device and set modified data back to it
|
||||
_graphicsDevice.Textures[0] = null;
|
||||
texture.SetData(data);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
private static readonly BlendState BlendColorBlendState;
|
||||
private static readonly BlendState BlendAlphaBlendState;
|
||||
|
||||
private static GraphicsDevice _graphicsDevice;
|
||||
private static SpriteBatch _spriteBatch;
|
||||
private static bool _needsBmp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public static partial class ToolBox
|
||||
{
|
||||
public static string LimitString(string str, ScalableFont font, int maxWidth)
|
||||
{
|
||||
if (maxWidth <= 0 || string.IsNullOrWhiteSpace(str)) return "";
|
||||
|
||||
float currWidth = font.MeasureString("...").X;
|
||||
for (int i = 0; i < str.Length; i++)
|
||||
{
|
||||
currWidth += font.MeasureString(str[i].ToString()).X;
|
||||
|
||||
if (currWidth > maxWidth)
|
||||
{
|
||||
return str.Substring(0, Math.Max(i - 2, 1)) + "...";
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public static string WrapText(string text, float lineLength, ScalableFont font, float textScale = 1.0f) //TODO: could integrate this into the ScalableFont class directly
|
||||
{
|
||||
if (font.MeasureString(text).X < lineLength) return text;
|
||||
|
||||
text = text.Replace("\n", " \n ");
|
||||
|
||||
string[] words = text.Split(' ');
|
||||
|
||||
StringBuilder wrappedText = new StringBuilder();
|
||||
float linePos = 0f;
|
||||
float spaceWidth = font.MeasureString(" ").X * textScale;
|
||||
for (int i = 0; i < words.Length; ++i)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(words[i]) && words[i] != "\n") continue;
|
||||
|
||||
Vector2 size = font.MeasureString(words[i]) * textScale;
|
||||
if (size.X > lineLength)
|
||||
{
|
||||
if (linePos == 0.0f)
|
||||
{
|
||||
wrappedText.AppendLine(words[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
if (words[i].Length == 0) break;
|
||||
|
||||
wrappedText.Append(words[i][0]);
|
||||
words[i] = words[i].Remove(0, 1);
|
||||
|
||||
linePos += size.X;
|
||||
} while (words[i].Length > 0 && (size = font.MeasureString((words[i][0]).ToString()) * textScale).X + linePos < lineLength);
|
||||
|
||||
wrappedText.Append("\n");
|
||||
linePos = 0.0f;
|
||||
i--;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (linePos + size.X < lineLength)
|
||||
{
|
||||
wrappedText.Append(words[i]);
|
||||
if (words[i] == "\n")
|
||||
{
|
||||
linePos = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
linePos += size.X + spaceWidth;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wrappedText.Append("\n");
|
||||
wrappedText.Append(words[i]);
|
||||
|
||||
linePos = size.X + spaceWidth;
|
||||
}
|
||||
|
||||
if (i < words.Length - 1) wrappedText.Append(" ");
|
||||
}
|
||||
|
||||
return wrappedText.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user