diff --git a/ArcFormats/ArcGSP.cs b/ArcFormats/ArcGSP.cs index f87e0457..d490935e 100644 --- a/ArcFormats/ArcGSP.cs +++ b/ArcFormats/ArcGSP.cs @@ -65,4 +65,53 @@ namespace GameRes.Formats.BlackRainbow return new ArcFile (file, this, dir); } } + + [Export(typeof(ArchiveFormat))] + public class DatOpener : ArchiveFormat + { + public override string Tag { get { return "BR/DAT"; } } + public override string Description { get { return "BlackRainbow resource archive"; } } + public override uint Signature { get { return 0; } } + public override bool IsHierarchic { get { return false; } } + public override bool CanCreate { get { return false; } } + + public DatOpener () + { + Extensions = new string[] { "dat", "pak" }; + } + + public override ArcFile TryOpen (ArcView file) + { + uint sig = file.View.ReadUInt32 (0); + if (sig != 2 && sig != 4 && sig != 5) + return null; + int count = file.View.ReadInt32 (8); + if (count <= 0 || count > 0x1ffff) + return null; + uint base_offset = file.View.ReadUInt32 (0x0c); + uint index_offset = 0x10; + uint index_size = 4u * (uint)count; + if (index_size > file.View.Reserve (index_offset, index_size)) + return null; + var index = new List (count); + for (int i = 0; i < count; ++i) + { + uint offset = file.View.ReadUInt32 (index_offset); + if (offset != 0xffffffff) + index.Add (base_offset + offset); + index_offset += 4; + } + var dir = new List (index.Count); + for (int i = 0; i < index.Count; ++i) + { + long offset = index[i]; + string name = file.View.ReadString (offset, 0x20); + var entry = FormatCatalog.Instance.CreateEntry (name); + entry.Offset = offset + 0x24; + entry.Size = file.View.ReadUInt32 (offset+0x20); + dir.Add (entry); + } + return new ArcFile (file, this, dir); + } + } }