diff --git a/SabreTools.Serialization/Deserializers/BSP.cs b/SabreTools.Serialization/Deserializers/BSP.cs index 5a60912d..59958322 100644 --- a/SabreTools.Serialization/Deserializers/BSP.cs +++ b/SabreTools.Serialization/Deserializers/BSP.cs @@ -66,8 +66,7 @@ namespace SabreTools.Serialization.Deserializers file.VerticesLump = ParseVerticesLump(data, lumpEntry.Offset, lumpEntry.Length); break; case LumpType.LUMP_VISIBILITY: - // TODO: Assign when Models supports it - _ = ParseVisibilityLump(data, lumpEntry.Offset, lumpEntry.Length); + file.VisibilityLump = ParseVisibilityLump(data, lumpEntry.Offset, lumpEntry.Length); break; case LumpType.LUMP_NODES: file.NodesLump = ParseNodesLump(data, lumpEntry.Offset, lumpEntry.Length); @@ -118,19 +117,13 @@ namespace SabreTools.Serialization.Deserializers /// Only recognized versions are 29 and 30 private static BspHeader? ParseHeader(Stream data) { - // TODO: Use marshalling here later - var header = new BspHeader(); - - header.Version = data.ReadInt32(); + var header = data.ReadType(); + + if (header == null) + return null; if (header.Version < 29 || header.Version > 30) return null; - header.Lumps = new BspLumpEntry[BSP_HEADER_LUMPS]; - for (int i = 0; i < BSP_HEADER_LUMPS; i++) - { - header.Lumps[i] = data.ReadType()!; - } - return header; } @@ -223,7 +216,6 @@ namespace SabreTools.Serialization.Deserializers /// Filled Half-Life Level texture header on success, null on error private static TextureHeader ParseTextureHeader(Stream data) { - // TODO: Use marshalling here instead of building var textureHeader = new TextureHeader(); textureHeader.MipTextureCount = data.ReadUInt32(); diff --git a/SabreTools.Serialization/Deserializers/CFB.cs b/SabreTools.Serialization/Deserializers/CFB.cs index cc92efd4..0d352eae 100644 --- a/SabreTools.Serialization/Deserializers/CFB.cs +++ b/SabreTools.Serialization/Deserializers/CFB.cs @@ -260,7 +260,6 @@ namespace SabreTools.Serialization.Deserializers /// Filled sector full of sector numbers on success, null on error private static SectorNumber[] ParseSectorNumbers(Stream data, ushort sectorShift) { - // TODO: Use marshalling here instead of building int sectorCount = (int)(Math.Pow(2, sectorShift) / sizeof(uint)); var sectorNumbers = new SectorNumber[sectorCount]; @@ -281,7 +280,7 @@ namespace SabreTools.Serialization.Deserializers /// Filled sector full of directory entries on success, null on error private static DirectoryEntry[]? ParseDirectoryEntries(Stream data, ushort sectorShift, ushort majorVersion) { - // TODO: Use marshalling here instead of building + // TODO: Fix the directory entry size const const int directoryEntrySize = 64 + 2 + 1 + 1 + 4 + 4 + 4 + 16 + 4 + 8 + 8 + 4 + 8; int sectorCount = (int)(Math.Pow(2, sectorShift) / directoryEntrySize); var directoryEntries = new DirectoryEntry[sectorCount]; diff --git a/SabreTools.Serialization/Deserializers/CIA.cs b/SabreTools.Serialization/Deserializers/CIA.cs index 96add723..25174c5b 100644 --- a/SabreTools.Serialization/Deserializers/CIA.cs +++ b/SabreTools.Serialization/Deserializers/CIA.cs @@ -154,8 +154,7 @@ namespace SabreTools.Serialization.Deserializers /// Filled certificate on success, null on error public static Certificate? ParseCertificate(Stream data) { - // TODO: Use marshalling here instead of building - Certificate certificate = new Certificate(); + var certificate = new Certificate(); certificate.SignatureType = (SignatureType)data.ReadUInt32(); switch (certificate.SignatureType) @@ -230,8 +229,7 @@ namespace SabreTools.Serialization.Deserializers /// Filled ticket on success, null on error public static Ticket? ParseTicket(Stream data, bool fromCdn = false) { - // TODO: Use marshalling here instead of building - Ticket ticket = new Ticket(); + var ticket = new Ticket(); ticket.SignatureType = (SignatureType)data.ReadUInt32(); switch (ticket.SignatureType) @@ -335,7 +333,6 @@ namespace SabreTools.Serialization.Deserializers /// Filled title metadata on success, null on error public static TitleMetadata? ParseTitleMetadata(Stream data, bool fromCdn = false) { - // TODO: Use marshalling here instead of building var titleMetadata = new TitleMetadata(); titleMetadata.SignatureType = (SignatureType)data.ReadUInt32(); diff --git a/SabreTools.Serialization/Deserializers/GCF.cs b/SabreTools.Serialization/Deserializers/GCF.cs index 895f6bf4..684643d6 100644 --- a/SabreTools.Serialization/Deserializers/GCF.cs +++ b/SabreTools.Serialization/Deserializers/GCF.cs @@ -608,7 +608,6 @@ namespace SabreTools.Serialization.Deserializers /// Filled Half-Life Game Cache data block header on success, null on error private static DataBlockHeader? ParseDataBlockHeader(Stream data, uint minorVersion) { - // TODO: Use marshalling here instead of building var dataBlockHeader = new DataBlockHeader(); // In version 3 the DataBlockHeader is missing the LastVersionPlayed field. diff --git a/SabreTools.Serialization/Deserializers/LinearExecutable.cs b/SabreTools.Serialization/Deserializers/LinearExecutable.cs index 3968de39..f3efffeb 100644 --- a/SabreTools.Serialization/Deserializers/LinearExecutable.cs +++ b/SabreTools.Serialization/Deserializers/LinearExecutable.cs @@ -470,15 +470,13 @@ namespace SabreTools.Serialization.Deserializers /// Filled resident names table entry on success, null on error public static ResidentNamesTableEntry ParseResidentNamesTableEntry(Stream data) { - // TODO: Use marshalling here instead of building var entry = new ResidentNamesTableEntry(); entry.Length = data.ReadByteValue(); if (entry.Length > 0 && data.Position + entry.Length <= data.Length) { - byte[]? name = data.ReadBytes(entry.Length); - if (name != null) - entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); + byte[] name = data.ReadBytes(entry.Length); + entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0'); } entry.OrdinalNumber = data.ReadUInt16(); diff --git a/SabreTools.Serialization/Deserializers/N3DS.cs b/SabreTools.Serialization/Deserializers/N3DS.cs index d9455fe9..4d9f95f9 100644 --- a/SabreTools.Serialization/Deserializers/N3DS.cs +++ b/SabreTools.Serialization/Deserializers/N3DS.cs @@ -141,14 +141,10 @@ namespace SabreTools.Serialization.Deserializers /// Filled NCSD header on success, null on error public static NCSDHeader? ParseNCSDHeader(Stream data) { - // TODO: Use marshalling here instead of building var header = new NCSDHeader(); header.RSA2048Signature = data.ReadBytes(0x100); - byte[]? magicNumber = data.ReadBytes(4); - if (magicNumber == null) - return null; - + byte[] magicNumber = data.ReadBytes(4); header.MagicNumber = Encoding.ASCII.GetString(magicNumber).TrimEnd('\0'); ; if (header.MagicNumber != NCSDMagicNumber) return null; diff --git a/SabreTools.Serialization/Deserializers/VBSP.cs b/SabreTools.Serialization/Deserializers/VBSP.cs index 71c433b6..59db4029 100644 --- a/SabreTools.Serialization/Deserializers/VBSP.cs +++ b/SabreTools.Serialization/Deserializers/VBSP.cs @@ -84,7 +84,7 @@ namespace SabreTools.Serialization.Deserializers file.OcclusionLump = ParseOcclusionLump(data, lumpEntry.Offset, lumpEntry.Length); break; case LumpType.LUMP_LEAVES: - file.LeavesLump = ParseLeavesLump(data, lumpEntry.Offset, lumpEntry.Length); + file.LeavesLump = ParseLeavesLump(data, lumpEntry.Version, lumpEntry.Offset, lumpEntry.Length); break; case LumpType.LUMP_MARKSURFACES: file.MarksurfacesLump = ParseMarksurfacesLump(data, lumpEntry.Offset, lumpEntry.Length); @@ -561,13 +561,12 @@ namespace SabreTools.Serialization.Deserializers /// /// Stream to parse /// Filled LUMP_LEAVES on success, null on error - private static VbspLeavesLump? ParseLeavesLump(Stream data, int offset, int length) + private static VbspLeavesLump? ParseLeavesLump(Stream data, uint version, int offset, int length) { var leaves = new List(); while (data.Position < offset + length) { - // TODO: Fix parsing between V0 and V1+ - var leaf = data.ReadType(); + var leaf = ParseVbspLeaf(data, version); if (leaf != null) leaves.Add(leaf); } @@ -575,6 +574,42 @@ namespace SabreTools.Serialization.Deserializers return new VbspLeavesLump { Leaves = [.. leaves] }; } + /// + /// Parse a Stream into VbspLeaf + /// + /// Stream to parse + /// Filled VbspLeaf on success, null on error + private static VbspLeaf? ParseVbspLeaf(Stream data, uint version) + { + var leaf = new VbspLeaf(); + + leaf.Contents = (VbspContents)data.ReadUInt32(); + leaf.Cluster = data.ReadInt16(); + leaf.AreaFlags = data.ReadInt16(); + leaf.Mins = new short[3]; + for (int i = 0; i < leaf.Mins.Length; i++) + { + leaf.Mins[i] = data.ReadInt16(); + } + leaf.Maxs = new short[3]; + for (int i = 0; i < leaf.Maxs.Length; i++) + { + leaf.Maxs[i] = data.ReadInt16(); + } + leaf.FirstLeafFace = data.ReadUInt16(); + leaf.NumLeafFaces = data.ReadUInt16(); + leaf.FirstLeafBrush = data.ReadUInt16(); + leaf.NumLeafBrushes = data.ReadUInt16(); + leaf.LeafWaterDataID = data.ReadInt16(); + + if (version == 1) + leaf.AmbientLighting = data.ReadType(); + else + leaf.Padding = data.ReadInt16(); + + return leaf; + } + /// /// Parse a Stream into LUMP_FACEIDS /// diff --git a/SabreTools.Serialization/Printers/BSP.cs b/SabreTools.Serialization/Printers/BSP.cs index 977a27bd..86dd74c4 100644 --- a/SabreTools.Serialization/Printers/BSP.cs +++ b/SabreTools.Serialization/Printers/BSP.cs @@ -75,8 +75,7 @@ namespace SabreTools.Serialization.Printers Print(builder, model.VerticesLump); break; case LumpType.LUMP_VISIBILITY: - // TODO: Implement when added to Models - // Print(builder, model.VisibilityLump); + Print(builder, model.VisibilityLump); break; case LumpType.LUMP_NODES: Print(builder, model.NodesLump); diff --git a/SabreTools.Serialization/Printers/VBSP.cs b/SabreTools.Serialization/Printers/VBSP.cs index 36c15496..49803677 100644 --- a/SabreTools.Serialization/Printers/VBSP.cs +++ b/SabreTools.Serialization/Printers/VBSP.cs @@ -635,10 +635,10 @@ namespace SabreTools.Serialization.Printers return; } - for (int j = 0; j < lump.Leaves.Length; j++) + for (int i = 0; i < lump.Leaves.Length; i++) { - var leaf = lump.Leaves[j]; - builder.AppendLine($" Leaf {j}"); + var leaf = lump.Leaves[i]; + builder.AppendLine($" Leaf {i}"); builder.AppendLine($" Contents: {leaf.Contents} (0x{leaf.Contents:X})"); builder.AppendLine(leaf.Cluster, " Cluster"); builder.AppendLine(leaf.AreaFlags, " AreaFlags"); @@ -651,8 +651,22 @@ namespace SabreTools.Serialization.Printers builder.AppendLine(leaf.LeafWaterDataID, " Leaf water data ID"); if (version == 0) { - // TODO: Figure out how to print the colors array - builder.AppendLine(" Colors array skipped..."); + if (leaf.AmbientLighting.Colors == null || leaf.AmbientLighting.Colors.Length == 0) + { + builder.AppendLine(" No ambient lighting colors"); + } + else + { + for (int j = 0; j < leaf.AmbientLighting.Colors.Length; j++) + { + var color = leaf.AmbientLighting.Colors[j]; + builder.AppendLine($" Ambient Lighting Color {j}"); + builder.AppendLine(color.Red, " Red"); + builder.AppendLine(color.Green, " Green"); + builder.AppendLine(color.Blue, " Blue"); + builder.AppendLine(color.Exponent, " Exponent"); + } + } } else { diff --git a/SabreTools.Serialization/Wrappers/MoPaQ.cs b/SabreTools.Serialization/Wrappers/MoPaQ.cs index 57659de2..dafcf65e 100644 --- a/SabreTools.Serialization/Wrappers/MoPaQ.cs +++ b/SabreTools.Serialization/Wrappers/MoPaQ.cs @@ -2,7 +2,6 @@ namespace SabreTools.Serialization.Wrappers { - // TODO: Figure out extension properties public partial class MoPaQ : WrapperBase { #region Descriptive Properties diff --git a/SabreTools.Serialization/Wrappers/PIC.cs b/SabreTools.Serialization/Wrappers/PIC.cs index ea59ce5d..e207dc6a 100644 --- a/SabreTools.Serialization/Wrappers/PIC.cs +++ b/SabreTools.Serialization/Wrappers/PIC.cs @@ -2,7 +2,6 @@ using System.IO; namespace SabreTools.Serialization.Wrappers { - // TODO: Figure out extension properties public class PIC : WrapperBase { #region Descriptive Properties