diff --git a/lib/AuroraLip/Archives/Formats/PAK_TM2.cs b/lib/AuroraLip/Archives/Formats/PAK_TM2.cs new file mode 100644 index 00000000..ac9ab784 --- /dev/null +++ b/lib/AuroraLip/Archives/Formats/PAK_TM2.cs @@ -0,0 +1,53 @@ +using AuroraLib.Archives; +using AuroraLib.Common; + +namespace AuroraLip.Archives.Formats +{ + public class PAK_TM2 : Archive, IFileAccess + { + public bool CanRead => true; + + public bool CanWrite => false; + + public const string Extension = ".pak"; + + public bool IsMatch(Stream stream, in string extension = "") + => Matcher(stream, extension); + + public static bool Matcher(Stream stream, in string extension = "") + { + if (extension == Extension && stream.Length > 0x20) + { + uint entryCount = stream.ReadUInt32(Endian.Big); + if (entryCount != 0 && entryCount < 1024 && stream.Position + entryCount * 8 < stream.Length) + { + stream.Seek((entryCount - 1) * 8, SeekOrigin.Current); + Entry lastEntry = stream.Read(Endian.Big); + return lastEntry.Offset + lastEntry.Size == stream.Length; + } + } + return false; + } + + protected override void Read(Stream stream) + { + uint entryCount = stream.ReadUInt32(Endian.Big); + Entry[] entrys = stream.For((int)entryCount, s => s.Read(Endian.Big)); + + + Root = new ArchiveDirectory() { OwnerArchive = this }; + for (int i = 0; i < entrys.Length; i++) + { + Root.AddArchiveFile(stream, entrys[i].Size, entrys[i].Offset, $"Entry_{i}"); + } + } + + protected override void Write(Stream stream) => throw new NotImplementedException(); + + private struct Entry + { + public uint Offset; + public uint Size; + } + } +} diff --git a/lib/AuroraLip/Common/FormatDictionary_List.cs b/lib/AuroraLip/Common/FormatDictionary_List.cs index 626a1d28..e6aef764 100644 --- a/lib/AuroraLip/Common/FormatDictionary_List.cs +++ b/lib/AuroraLip/Common/FormatDictionary_List.cs @@ -431,6 +431,10 @@ public static partial class FormatDictionary new FormatInfo(".loc","LOCH", FormatType.Unknown,"","EA"), new FormatInfo(".pfd","PFDx", FormatType.Unknown,"","EA"), + //Red Entertainment + new FormatInfo(".pak", FormatType.Archive, "Tengai Makyō II Archive", "Red Entertainment"){ Class = typeof(PAK_TM2), IsMatch = PAK_TM2.Matcher }, + new FormatInfo(".cns","@CNS", FormatType.Archive, "CNS Compressed", "Red Entertainment"), + //mix //new FormatInfo(".cmpr","CMPR", FormatType.Archive, "compressed Data"), new FormatInfo(".ash","ASH0", FormatType.Archive, comp_), //https://github.com/trapexit/wiiqt/blob/master/WiiQt/ash.cpp