Added FSO.Files for use with the API server

Don't ask me. FreeSO is the prime example of dependency hell.
This commit is contained in:
Tony Bark 2024-05-01 04:38:12 -04:00
parent 4b5e584eeb
commit 8fec258215
104 changed files with 14653 additions and 163 deletions

View file

@ -0,0 +1,128 @@
using System;
using System.Globalization;
using System.IO;
using System.Linq;
namespace FSO.Files.Utils
{
public interface BCFReadProxy : IDisposable
{
byte ReadByte();
ushort ReadUInt16();
short ReadInt16();
int ReadInt32();
uint ReadUInt32();
float ReadFloat();
string ReadPascalString();
string ReadLongPascalString();
}
public interface BCFWriteProxy : IDisposable
{
void WriteByte(byte data);
void WriteUInt16(ushort data);
void WriteInt16(short data);
void WriteInt32(int data);
void WriteUInt32(uint data);
void WriteFloat(float data);
void WritePascalString(string data);
void WriteLongPascalString(string data);
void SetGrouping(int groupSize);
}
public class BCFReadString : BCFReadProxy
{
private StreamReader Reader;
public int Version;
private string[] NumBuf = new string[0];
private int NumInd = 1;
public BCFReadString(Stream input, bool version)
{
Reader = new StreamReader(input);
if (!version) return;
//skip to version
var line = "";
while (!line.StartsWith("version "))
line = Reader.ReadLine();
Version = int.Parse(line.Substring(8));
}
private string ReadNum()
{
//contrary to popular belief, this function that returns a string does indeed read a number
if (NumInd >= NumBuf.Length)
{
NumBuf = Reader.ReadLine().Trim().Split(' ').ToArray();
NumInd = 0;
}
return NumBuf[NumInd++];
}
public byte ReadByte() { return byte.Parse(ReadNum()); }
public ushort ReadUInt16() { return ushort.Parse(ReadNum()); }
public short ReadInt16() { return short.Parse(ReadNum()); }
public int ReadInt32() { return int.Parse(ReadNum()); }
public uint ReadUInt32() { return uint.Parse(ReadNum()); }
public float ReadFloat() { return float.Parse(ReadNum(), CultureInfo.InvariantCulture); }
public string ReadPascalString() { return Reader.ReadLine(); }
public string ReadLongPascalString() { return Reader.ReadLine(); }
public void Dispose()
{
Reader.Dispose();
}
}
public class BCFWriteString : BCFWriteProxy
{
private StreamWriter Writer;
public int Version;
private int GroupSize = 1;
private int GroupInd;
public BCFWriteString(Stream input, bool version)
{
Writer = new StreamWriter(input);
if (!version) return;
//write out default version
Writer.WriteLine("version 300");
}
public void SetGrouping(int groupSize)
{
if (GroupInd > 0) Writer.WriteLine();
GroupInd = 0;
GroupSize = groupSize;
}
private void WriteNum(string num)
{
if (GroupSize-1 >= GroupInd)
{
Writer.WriteLine(num);
GroupInd = 0;
} else
{
Writer.Write(num + " ");
}
}
public void WriteByte(byte data) { WriteNum(data.ToString()); }
public void WriteUInt16(ushort data) { WriteNum(data.ToString()); }
public void WriteInt16(short data) { WriteNum(data.ToString()); }
public void WriteInt32(int data) { WriteNum(data.ToString()); }
public void WriteUInt32(uint data) { WriteNum(data.ToString()); }
public void WriteFloat(float data) { WriteNum(data.ToString(CultureInfo.InvariantCulture)); }
public void WritePascalString(string data) { WriteNum(data); }
public void WriteLongPascalString(string data) { WriteNum(data); }
public void Dispose()
{
Writer.Dispose();
}
}
}

View file

@ -0,0 +1,74 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.IO;
namespace FSO.Files.Utils
{
public static class CurLoader
{
public static MouseCursor LoadMonoCursor(GraphicsDevice gd, Stream stream)
{
var cur = LoadCursor(gd, stream);
return MouseCursor.FromTexture2D(cur.Item1, cur.Item2.X, cur.Item2.Y);
}
public static Tuple<Texture2D, Point> LoadCursor(GraphicsDevice gd, Stream stream)
{
using (var io = new BinaryReader(stream))
{
//little endian
var tempbmp = new MemoryStream();
var outIO = new BinaryWriter(tempbmp);
var reserved = io.ReadInt16();
var type = io.ReadInt16();
if (type != 2) throw new Exception("Not a cursor!");
var images = io.ReadInt16(); //currently discard extra images...
//read first image
var width = io.ReadByte();
var height = io.ReadByte();
var colors = io.ReadByte();
var reserved2 = io.ReadByte();
var xOffset = io.ReadInt16();
var yOffset = io.ReadInt16();
var size = io.ReadInt32();
var offset = io.ReadInt32();
stream.Seek(offset - 22, SeekOrigin.Current);
//ok... now write the bitmap data to a fake bitmap
outIO.Write(new char[] { 'B', 'M' });
outIO.Write(size + 14); //size, plus header
outIO.Write(0);
outIO.Write(14);
var data = new byte[size];
stream.Read(data, 0, size);
outIO.Write(data);
tempbmp.Seek(0, SeekOrigin.Begin);
var tex = ImageLoader.FromStream(gd, tempbmp);
//our mask is on top. the image is on bottom.
var odata = new byte[tex.Width * tex.Height * 4];
tex.GetData(odata);
var ndata = new byte[tex.Width * tex.Height * 2];
var limit = ndata.Length;
for (int i=0; i< limit; i+=4)
{
var j = i + limit;
ndata[i] = (byte)((~odata[i]) & odata[j]);
ndata[i+1] = ndata[i];
ndata[i+2] = ndata[i];
ndata[i+3] = (byte)(~odata[i]);
}
var oTex = new Texture2D(gd, width, height);
oTex.SetData(ndata);
tex.Dispose();
return new Tuple<Texture2D, Point>(oTex, new Point(xOffset, yOffset));
}
}
}
}

View file

@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.IO;
using xxHashSharp;
namespace FSO.Files.Utils
{
public class DiffGenerator
{
public HashSet<string> SourceFiles; //aka before
public HashSet<string> DestFiles; //aka after
public HashSet<string> AddFiles;
public HashSet<string> RemovedFiles;
public HashSet<string> SameFiles;
public string SourcePath;
public string DestPath;
public static List<FileDiff> GetDiffs(string sourcePath, string destPath)
{
var sourceFiles = new HashSet<string>();
RecursiveDirectoryScan(sourcePath, sourceFiles, sourcePath);
var destFiles = new HashSet<string>();
RecursiveDirectoryScan(destPath, destFiles, destPath);
var addFiles = new HashSet<string>(destFiles);
addFiles.ExceptWith(sourceFiles);
var removedFiles = new HashSet<string>(sourceFiles);
removedFiles.ExceptWith(destFiles);
var sameFiles = new HashSet<string>(sourceFiles);
sameFiles.IntersectWith(destFiles);
var diffs = new List<FileDiff>();
foreach (var removed in removedFiles)
{
var bytes = GetFileBytes(Path.Combine(sourcePath, removed));
var hash = xxHash.CalculateHash(bytes).ToString("x8");
diffs.Add(new FileDiff(FileDiffType.Remove, removed, hash, null));
}
foreach (var added in addFiles)
{
var bytes = GetFileBytes(Path.Combine(destPath, added));
var hash = xxHash.CalculateHash(bytes).ToString("x8");
diffs.Add(new FileDiff(FileDiffType.Add, added, null, hash));
}
foreach (var same in sameFiles)
{
var bytesBefore = GetFileBytes(Path.Combine(sourcePath, same));
var bytesAfter = GetFileBytes(Path.Combine(destPath, same));
var hashBefore = xxHash.CalculateHash(bytesBefore).ToString("x8");
var hashAfter = xxHash.CalculateHash(bytesAfter).ToString("x8");
diffs.Add(new FileDiff(
(hashBefore == hashAfter) ? FileDiffType.Unchanged : FileDiffType.Modify,
same, hashBefore, hashAfter));
}
return diffs;
}
private static byte[] GetFileBytes(string path)
{
using (var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var memory = new MemoryStream();
stream.CopyTo(memory);
var bytes = memory.ToArray();
return bytes;
}
}
private static void RecursiveDirectoryScan(string folder, HashSet<string> fileNames, string basePath)
{
var files = Directory.GetFiles(folder);
foreach (var file in files)
{
fileNames.Add(GetRelativePath(basePath, file));
}
var dirs = Directory.GetDirectories(folder);
foreach (var dir in dirs)
{
RecursiveDirectoryScan(dir, fileNames, basePath);
}
}
private static string GetRelativePath(string relativeTo, string path)
{
if (!(relativeTo.EndsWith("/") || relativeTo.EndsWith("\\"))) relativeTo += "/";
var uri = new Uri(relativeTo);
var rel = Uri.UnescapeDataString(uri.MakeRelativeUri(new Uri(path)).ToString()).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
if (rel.Contains(Path.DirectorySeparatorChar.ToString()) == false)
{
rel = $".{ Path.DirectorySeparatorChar }{ rel }";
}
return rel;
}
}
public class FileDiff
{
public FileDiffType DiffType;
public string Path;
public string BeforeHash;
public string AfterHash;
public FileDiff(FileDiffType type, string path, string beforeHash, string afterHash)
{
DiffType = type;
Path = path;
BeforeHash = beforeHash;
AfterHash = afterHash;
}
}
public enum FileDiffType
{
Add, //after hash only
Modify,
Remove, //before hash only
Unchanged
}
}

View file

@ -0,0 +1,7 @@
namespace FSO.Files.Utils
{
public interface IFileInfoUtilizer
{
void SetFilename(string filename);
}
}

View file

@ -0,0 +1,9 @@
using Microsoft.Xna.Framework.Graphics;
namespace FSO.Files.Utils
{
public interface ITextureProvider
{
Texture2D GetTexture(GraphicsDevice device);
}
}

View file

@ -0,0 +1,9 @@
using Microsoft.Xna.Framework.Graphics;
namespace FSO.Files.Utils
{
public interface IWorldTextureProvider
{
WorldTexture GetWorldTexture(GraphicsDevice device);
}
}

View file

@ -0,0 +1,357 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace FSO.Files.Utils
{
/// <summary>
/// The order to read bytes in.
/// </summary>
public enum ByteOrder
{
BIG_ENDIAN,
LITTLE_ENDIAN
}
/// <summary>
/// IOBuffer is a very basic wrapper over System.BinaryReader that inherits from IDisposable.
/// </summary>
public class IoBuffer : IDisposable, BCFReadProxy
{
private Stream Stream;
private BinaryReader Reader;
public ByteOrder ByteOrder = ByteOrder.BIG_ENDIAN;
/// <summary>
/// Creates a new IOBuffer instance from a stream.
/// </summary>
/// <param name="stream"></param>
public IoBuffer(Stream stream)
{
this.Stream = stream;
this.Reader = new BinaryReader(stream);
}
/// <summary>
/// More to read in this stream?
/// </summary>
public bool HasMore
{
get
{
return Stream.Position < Stream.Length - 1;
}
}
/// <summary>
/// Skips a number of bytes in the current stream, starting from the current position.
/// </summary>
/// <param name="numBytes">Number of bytes to skip.</param>
public void Skip(long numBytes)
{
Reader.BaseStream.Seek(numBytes, SeekOrigin.Current);
}
/// <summary>
/// Seeks in the current stream.
/// </summary>
/// <param name="origin">Where to start from.</param>
/// <param name="offset">The offset to seek to.</param>
public void Seek(SeekOrigin origin, long offset)
{
Reader.BaseStream.Seek(offset, origin);
}
public long Position => Stream.Position;
/// <summary>
/// Reads a variable length unsigned integer from the current stream.
/// </summary>
/// <returns>A uint.</returns>
public uint ReadVarLen()
{
uint result = 0;
int shift = 0;
byte read = 0x80;
while ((read&0x80) > 0)
{
read = ReadByte();
result |= (uint)((read & 0x7F) << shift);
shift += 7;
}
return result;
}
/// <summary>
/// Reads an unsigned 16bit integer from the current stream.
/// </summary>
/// <returns>A ushort.</returns>
public ushort ReadUInt16()
{
var value = Reader.ReadUInt16();
if (ByteOrder == ByteOrder.BIG_ENDIAN)
{
value = Endian.SwapUInt16(value);
}
return value;
}
/// <summary>
/// Reads a 16bit integer from the current stream.
/// </summary>
/// <returns>A short.</returns>
public short ReadInt16()
{
var value = Reader.ReadInt16();
if (ByteOrder == ByteOrder.BIG_ENDIAN)
{
value = Endian.SwapInt16(value);
}
return value;
}
/// <summary>
/// Reads a 32bit integer from the current stream.
/// </summary>
/// <returns>An int.</returns>
public int ReadInt32()
{
var value = Reader.ReadInt32();
if (ByteOrder == ByteOrder.BIG_ENDIAN)
{
value = Endian.SwapInt32(value);
}
return value;
}
/// <summary>
/// Reads a 64bit integer from the current stream.
/// </summary>
/// <returns>An int.</returns>
public long ReadInt64()
{
var value = Reader.ReadInt64();
if (ByteOrder == ByteOrder.BIG_ENDIAN)
{
value = Endian.SwapInt64(value);
}
return value;
}
/// <summary>
/// Reads an unsigned 32bit integer from the current stream.
/// </summary>
/// <returns>A uint.</returns>
public uint ReadUInt32()
{
var value = Reader.ReadUInt32();
if (ByteOrder == ByteOrder.BIG_ENDIAN)
{
value = Endian.SwapUInt32(value);
}
return value;
}
/// <summary>
/// Reads a number of ASCII characters from the current stream.
/// </summary>
/// <param name="num">The number of characters to read.</param>
/// <returns>A string, INCLUDING the trailing 0.</returns>
public string ReadCString(int num)
{
return ReadCString(num, false);
}
/// <summary>
/// Reads a number of ASCII characters from the current stream.
/// </summary>
/// <param name="num">The number of characters to read.</param>
/// <param name="trimNull">Trim the trailing 0?</param>
/// <returns>A string, with or without the trailing 0.</returns>
public string ReadCString(int num, bool trimNull)
{
var result = ASCIIEncoding.ASCII.GetString(Reader.ReadBytes(num));
if (trimNull)
{
/** Trim on \0 **/
var io = result.IndexOf('\0');
if (io != -1)
{
result = result.Substring(0, io);
}
}
return result;
}
/// <summary>
/// Reads a byte from the current stream.
/// </summary>
/// <returns>A byte.</returns>
public byte ReadByte()
{
return Reader.ReadByte();
}
/// <summary>
/// Reads a number of bytes from the current stream.
/// </summary>
/// <param name="num">Number of bytes to read.</param>
/// <returns>An byte array.</returns>
public byte[] ReadBytes(uint num)
{
return Reader.ReadBytes((int)num);
}
/// <summary>
/// Reads a number of bytes from the current stream.
/// </summary>
/// <param name="num">Number of bytes to read.</param>
/// <returns>An byte array.</returns>
public byte[] ReadBytes(int num)
{
return Reader.ReadBytes(num);
}
/// <summary>
/// Reads a pascal string from the current stream, which is prefixed by a 16bit short.
/// </summary>
/// <returns>A string.</returns>
public string ReadLongPascalString()
{
var length = ReadInt16();
return Encoding.ASCII.GetString(Reader.ReadBytes(length));
}
/// <summary>
/// Reads a C string from the current stream.
/// </summary>
/// <returns>A string.</returns>
public string ReadNullTerminatedString()
{
var sb = new StringBuilder();
while (true){
char ch = (char)Reader.ReadByte();
if (ch == '\0'){
break;
}
sb.Append(ch);
}
return sb.ToString();
}
public string ReadNullTerminatedUTF8()
{
var sb = new List<byte>();
while (true)
{
var b = Reader.ReadByte();
if (b == 0) break;
sb.Add(b);
}
return Encoding.UTF8.GetString(sb.ToArray());
}
/// <summary>
/// Reads a pascal string from the current stream.
/// </summary>
/// <returns>A string.</returns>
public string ReadVariableLengthPascalString()
{
return Reader.ReadString();
}
/// <summary>
/// Reads a pascal string from the current stream, prefixed by a byte.
/// </summary>
/// <returns>A string.</returns>
public string ReadPascalString()
{
var length = ReadByte();
return Encoding.ASCII.GetString(Reader.ReadBytes(length));
}
/// <summary>
/// Reads a float from the current stream.
/// </summary>
/// <returns>A float.</returns>
[System.Security.SecuritySafeCritical] // auto-generated
public virtual unsafe float ReadFloat()
{
return Reader.ReadSingle();
}
/// <summary>
/// Sets a mark at the current position in the stream.
/// </summary>
private long _Mark;
public void Mark()
{
_Mark = Reader.BaseStream.Position;
}
/// <summary>
/// Seeks in the current stream from the current mark plus the number of bytes.
/// </summary>
/// <param name="numBytes">The number of bytes to add to the offset (mark).</param>
public void SeekFromMark(long numBytes)
{
Reader.BaseStream.Seek(_Mark + numBytes, SeekOrigin.Begin);
}
#region IDisposable Members
public void Dispose()
{
}
#endregion
/// <summary>
/// Creates a new IOBuffer instance from a stream.
/// </summary>
/// <param name="stream">A stream.</param>
/// <returns>A new IOBuffer instance.</returns>
public static IoBuffer FromStream(Stream stream)
{
return new IoBuffer(stream);
}
/// <summary>
/// Creates a new IOBuffer instance from a stream, using a specified byte order.
/// </summary>
/// <param name="stream">A stream.</param>
/// <param name="order">Byte order to use.</param>
/// <returns>A new IOBuffer instance.</returns>
public static IoBuffer FromStream(Stream stream, ByteOrder order)
{
var item = FromStream(stream);
item.ByteOrder = order;
return item;
}
/// <summary>
/// Creates a new IOBuffer instance from a byte array.
/// </summary>
/// <param name="bytes">The byte array to use.</param>
/// <returns>A new IOBuffer instance.</returns>
public static IoBuffer FromBytes(byte[] bytes)
{
return FromStream(new MemoryStream(bytes));
}
/// <summary>
/// Creates a new IOBuffer instance from a byte array, using a specified byte order.
/// </summary>
/// <param name="bytes">The byte array to use.</param>
/// <param name="order">Byte order to use.</param>
/// <returns>A new IOBuffer instance.</returns>
public static IoBuffer FromBytes(byte[] bytes, ByteOrder order)
{
return FromStream(new MemoryStream(bytes), order);
}
}
}

View file

@ -0,0 +1,284 @@
using System;
using System.Text;
using System.IO;
namespace FSO.Files.Utils
{
/// <summary>
/// IOBuffer is a very basic wrapper over System.BinaryReader that inherits from IDisposable.
/// </summary>
public class IoWriter : IDisposable, BCFWriteProxy
{
private Stream Stream;
private BinaryWriter Writer;
private bool FloatSwap = false;
public ByteOrder ByteOrder = ByteOrder.BIG_ENDIAN;
/// <summary>
/// Creates a new IOBuffer instance from a stream.
/// </summary>
/// <param name="stream"></param>
public IoWriter(Stream stream)
{
this.Stream = stream;
this.Writer = new BinaryWriter(stream);
}
/// <summary>
/// More to read in this stream?
/// </summary>
public bool HasMore
{
get
{
return Stream.Position < Stream.Length - 1;
}
}
/// <summary>
/// Skips a number of bytes in the current stream, starting from the current position.
/// </summary>
/// <param name="numBytes">Number of bytes to skip.</param>
public void Skip(long numBytes)
{
Writer.BaseStream.Seek(numBytes, SeekOrigin.Current);
}
/// <summary>
/// Seeks in the current stream.
/// </summary>
/// <param name="origin">Where to start from.</param>
/// <param name="offset">The offset to seek to.</param>
public void Seek(SeekOrigin origin, long offset)
{
Writer.BaseStream.Seek(offset, origin);
}
/// <summary>
/// Writes a variable length unsigned integer to the current stream
/// </summary>
/// <param name="value">Value to write.</param>
public void WriteVarLen(uint value)
{
bool first = true;
while (value > 0 || first)
{
WriteByte((byte)(((value > 127)?(uint)128:0) | (value & 127)));
value >>= 7;
first = false;
}
}
/// <summary>
/// Writes an unsigned 16bit integer to the current stream.
/// </summary>
/// <returns>A ushort.</returns>
public void WriteUInt16(ushort value)
{
if (ByteOrder == ByteOrder.BIG_ENDIAN)
{
value = Endian.SwapUInt16(value);
}
Writer.Write(value);
}
/// <summary>
/// Writes a 16bit integer to the current stream.
/// </summary>
/// <returns>A short.</returns>
public void WriteInt16(short value)
{
if (ByteOrder == ByteOrder.BIG_ENDIAN)
{
value = Endian.SwapInt16(value);
}
Writer.Write(value);
}
/// <summary>
/// Writes a 32bit integer to the current stream.
/// </summary>
/// <returns>An int.</returns>
public void WriteInt32(int value)
{
if (ByteOrder == ByteOrder.BIG_ENDIAN)
{
value = Endian.SwapInt32(value);
}
Writer.Write(value);
}
/// <summary>
/// Writes a 32bit integer to the current stream.
/// </summary>
/// <returns>An int.</returns>
public void WriteInt64(long value)
{
if (ByteOrder == ByteOrder.BIG_ENDIAN)
{
value = Endian.SwapInt64(value);
}
Writer.Write(value);
}
/// <summary>
/// Writes an unsigned 32bit integer from to current stream.
/// </summary>
/// <returns>A uint.</returns>
public void WriteUInt32(uint value)
{
if (ByteOrder == ByteOrder.BIG_ENDIAN)
{
value = Endian.SwapUInt32(value);
}
Writer.Write(value);
}
/// <summary>
/// Writes a number of ASCII characters to the current stream.
/// </summary>
/// <param name="value">The string to write.</param>
/// <param name="num">The number of bytes to write into.</param>
public void WriteCString(string value, int num)
{
value = value.PadRight(num, '\0');
Writer.Write(ASCIIEncoding.ASCII.GetBytes(value));
}
public void WriteCString(string value)
{
WriteCString(value, value.Length + 1);
}
/// <summary>
/// Writes a byte to the current stream.
/// </summary>
public void WriteByte(byte value)
{
Writer.Write(value);
}
/// <summary>
/// Writes a number of bytes to the current stream.
/// </summary>
/// <param name="bytes">Bytes to write out.</param>
public void WriteBytes(byte[] bytes)
{
Writer.Write(bytes);
}
/// <summary>
/// Writes a pascal string to the current stream, which is prefixed by a 16bit short.
/// </summary>
public void WriteLongPascalString(string value)
{
WriteInt16((short)value.Length);
WriteBytes(Encoding.ASCII.GetBytes(value));
}
/// <summary>
/// Writes a C string to the current stream.
/// </summary>
public void WriteNullTerminatedString(string value)
{
if (value != null) WriteBytes(Encoding.ASCII.GetBytes(value));
WriteByte(0);
}
/// <summary>
/// Writes a pascal string to the current stream.
/// </summary>
public void WriteVariableLengthPascalString(string value)
{
Writer.Write((value == null)?"":value);
}
/// <summary>
/// Writes a pascal string to the current stream, prefixed by a byte.
/// </summary>
public void WritePascalString(string value)
{
WriteByte((byte)value.Length);
WriteBytes(Encoding.ASCII.GetBytes(value));
}
/// <summary>
/// Writes a float to the current stream.
/// </summary>
public void WriteFloat(float value)
{
var bytes = BitConverter.GetBytes(value);
if (ByteOrder == ByteOrder.BIG_ENDIAN && FloatSwap)
{
Array.Reverse(bytes);
}
Writer.Write(bytes);
}
#region IDisposable Members
public void Dispose()
{
}
#endregion
/// <summary>
/// Creates a new IoWriter instance from a stream.
/// </summary>
/// <param name="stream">A stream.</param>
/// <returns>A new IoWriter instance.</returns>
public static IoWriter FromStream(Stream stream)
{
return new IoWriter(stream);
}
/// <summary>
/// Creates a new IoWriter instance from a stream, using a specified byte order.
/// </summary>
/// <param name="stream">A stream.</param>
/// <param name="order">Byte order to use.</param>
/// <returns>A new IoWriter instance.</returns>
public static IoWriter FromStream(Stream stream, ByteOrder order)
{
var item = FromStream(stream);
item.ByteOrder = order;
return item;
}
/// <summary>
/// Creates a new IOBuffer instance from a byte array.
/// </summary>
/// <param name="bytes">The byte array to use.</param>
/// <returns>A new IOBuffer instance.</returns>
public static IoWriter FromBytes(byte[] bytes)
{
return FromStream(new MemoryStream(bytes));
}
/// <summary>
/// Creates a new IOBuffer instance from a byte array, using a specified byte order.
/// </summary>
/// <param name="bytes">The byte array to use.</param>
/// <param name="order">Byte order to use.</param>
/// <returns>A new IOBuffer instance.</returns>
public static IoWriter FromBytes(byte[] bytes, ByteOrder order)
{
return FromStream(new MemoryStream(bytes), order);
}
/// <summary>
/// Used by BCFWriteProxy's string mode, but does not do anything here.
/// </summary>
/// <param name="groupSize">The size of value groups</param>
public void SetGrouping(int groupSize)
{
}
}
}

View file

@ -0,0 +1,13 @@
using Microsoft.Xna.Framework.Graphics;
namespace FSO.Files.Utils
{
/// <summary>
/// A texture used in the game world.
/// </summary>
public class WorldTexture
{
public Texture2D Pixel;
public Texture2D ZBuffer;
}
}