Skip to content

Commit

Permalink
Add support for writing LSFv6 headers
Browse files Browse the repository at this point in the history
  • Loading branch information
Norbyte committed Jul 11, 2022
1 parent 0d8ae30 commit fb0ca06
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 26 deletions.
9 changes: 7 additions & 2 deletions LSLib/LS/Enums/LSFVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@ public enum LSFVersion
VerBG3AdditionalBlob = 0x06,

/// <summary>
/// Latest version supported by this library
/// Latest input version supported by this library
/// </summary>
MaxVersion = 0x06
MaxReadVersion = 0x06,

/// <summary>
/// Latest output version supported by this library
/// </summary>
MaxWriteVersion = 0x06
}

public enum LSXVersion
Expand Down
2 changes: 1 addition & 1 deletion LSLib/LS/ResourceUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class ResourceConversionParameters
/// <summary>
/// Format of generated LSF files
/// </summary>
public LSFVersion LSF = LSFVersion.MaxVersion;
public LSFVersion LSF = LSFVersion.MaxWriteVersion;

/// <summary>
/// Store sibling/neighbour node data in LSF files (usually done by savegames only)
Expand Down
2 changes: 1 addition & 1 deletion LSLib/LS/Resources/LSF/LSFReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ private void ReadHeaders(BinaryReader reader)
throw new InvalidDataException(msg);
}

if (magic.Version < (ulong)LSFVersion.VerInitial || magic.Version > (ulong)LSFVersion.MaxVersion)
if (magic.Version < (ulong)LSFVersion.VerInitial || magic.Version > (ulong)LSFVersion.MaxReadVersion)
{
var msg = String.Format("LSF version {0} is not supported", magic.Version);
throw new InvalidDataException(msg);
Expand Down
84 changes: 62 additions & 22 deletions LSLib/LS/Resources/LSF/LSFWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class LSFWriter
private List<List<string>> StringHashMap;
private List<int> NextSiblingIndices;

public LSFVersion Version = LSFVersion.MaxVersion;
public LSFVersion Version = LSFVersion.MaxWriteVersion;
public bool EncodeSiblingData = false;
public CompressionMethod Compression = CompressionMethod.LZ4;
public CompressionLevel CompressionLevel = CompressionLevel.DefaultCompression;
Expand All @@ -40,6 +40,12 @@ public LSFWriter(Stream stream)

public void Write(Resource resource)
{
if (Version > LSFVersion.MaxWriteVersion)
{
var msg = String.Format("Writing LSF version {0} is not supported (highest is {1})", Version, LSFVersion.MaxWriteVersion);
throw new InvalidDataException(msg);
}

using (this.Writer = new BinaryWriter(Stream, Encoding.Default, true))
using (this.NodeStream = new MemoryStream())
using (this.NodeWriter = new BinaryWriter(NodeStream))
Expand Down Expand Up @@ -109,33 +115,67 @@ public void Write(Resource resource)
byte[] attributesCompressed = BinUtils.Compress(attributeBuffer, Compression, CompressionLevel, chunked);
byte[] valuesCompressed = BinUtils.Compress(valueBuffer, Compression, CompressionLevel, chunked);

var meta = new LSFMetadataV5();
meta.StringsUncompressedSize = (UInt32)stringBuffer.Length;
meta.NodesUncompressedSize = (UInt32)nodeBuffer.Length;
meta.AttributesUncompressedSize = (UInt32)attributeBuffer.Length;
meta.ValuesUncompressedSize = (UInt32)valueBuffer.Length;

if (Compression == CompressionMethod.None)
if (Version < LSFVersion.VerBG3AdditionalBlob)
{
meta.StringsSizeOnDisk = 0;
meta.NodesSizeOnDisk = 0;
meta.AttributesSizeOnDisk = 0;
meta.ValuesSizeOnDisk = 0;
var meta = new LSFMetadataV5();
meta.StringsUncompressedSize = (UInt32)stringBuffer.Length;
meta.NodesUncompressedSize = (UInt32)nodeBuffer.Length;
meta.AttributesUncompressedSize = (UInt32)attributeBuffer.Length;
meta.ValuesUncompressedSize = (UInt32)valueBuffer.Length;

if (Compression == CompressionMethod.None)
{
meta.StringsSizeOnDisk = 0;
meta.NodesSizeOnDisk = 0;
meta.AttributesSizeOnDisk = 0;
meta.ValuesSizeOnDisk = 0;
}
else
{
meta.StringsSizeOnDisk = (UInt32)stringsCompressed.Length;
meta.NodesSizeOnDisk = (UInt32)nodesCompressed.Length;
meta.AttributesSizeOnDisk = (UInt32)attributesCompressed.Length;
meta.ValuesSizeOnDisk = (UInt32)valuesCompressed.Length;
}

meta.CompressionFlags = BinUtils.MakeCompressionFlags(Compression, CompressionLevel);
meta.Unknown2 = 0;
meta.Unknown3 = 0;
meta.HasSiblingData = EncodeSiblingData ? 1u : 0u;

BinUtils.WriteStruct<LSFMetadataV5>(Writer, ref meta);
}
else
{
meta.StringsSizeOnDisk = (UInt32)stringsCompressed.Length;
meta.NodesSizeOnDisk = (UInt32)nodesCompressed.Length;
meta.AttributesSizeOnDisk = (UInt32)attributesCompressed.Length;
meta.ValuesSizeOnDisk = (UInt32)valuesCompressed.Length;
}
var meta = new LSFMetadataV6();
meta.StringsUncompressedSize = (UInt32)stringBuffer.Length;
meta.NodesUncompressedSize = (UInt32)nodeBuffer.Length;
meta.AttributesUncompressedSize = (UInt32)attributeBuffer.Length;
meta.ValuesUncompressedSize = (UInt32)valueBuffer.Length;

if (Compression == CompressionMethod.None)
{
meta.StringsSizeOnDisk = 0;
meta.NodesSizeOnDisk = 0;
meta.AttributesSizeOnDisk = 0;
meta.ValuesSizeOnDisk = 0;
}
else
{
meta.StringsSizeOnDisk = (UInt32)stringsCompressed.Length;
meta.NodesSizeOnDisk = (UInt32)nodesCompressed.Length;
meta.AttributesSizeOnDisk = (UInt32)attributesCompressed.Length;
meta.ValuesSizeOnDisk = (UInt32)valuesCompressed.Length;
}

meta.CompressionFlags = BinUtils.MakeCompressionFlags(Compression, CompressionLevel);
meta.Unknown2 = 0;
meta.Unknown3 = 0;
meta.HasSiblingData = EncodeSiblingData ? 1u : 0u;
meta.Unknown = 0;
meta.CompressionFlags = BinUtils.MakeCompressionFlags(Compression, CompressionLevel);
meta.Unknown2 = 0;
meta.Unknown3 = 0;
meta.HasSiblingData = EncodeSiblingData ? 1u : 0u;

BinUtils.WriteStruct<LSFMetadataV5>(Writer, ref meta);
BinUtils.WriteStruct<LSFMetadataV6>(Writer, ref meta);
}

Writer.Write(stringsCompressed, 0, stringsCompressed.Length);
Writer.Write(nodesCompressed, 0, nodesCompressed.Length);
Expand Down

0 comments on commit fb0ca06

Please sign in to comment.