diff --git a/ArcFormats/Triangle/ArcBMX.cs b/ArcFormats/Triangle/ArcBMX.cs index d5d142da..1c4d82c3 100644 --- a/ArcFormats/Triangle/ArcBMX.cs +++ b/ArcFormats/Triangle/ArcBMX.cs @@ -41,7 +41,7 @@ namespace GameRes.Formats.Triangle public BmxOpener () { - Extensions = new string[] { "bmx", "wax" }; + Extensions = new string[] { "bmx", "wax", "fx", "gx" }; } public override ArcFile TryOpen (ArcView file) @@ -59,13 +59,19 @@ namespace GameRes.Formats.Triangle uint last_offset = file.View.ReadUInt32 (index_size - 4); if (last_offset != file.MaxOffset) return null; + string default_type = ""; + if (file.Name.HasExtension ("fx")) + default_type = "audio"; + else if (file.Name.HasExtension ("gx")) + default_type = "image"; var base_name = Path.GetFileNameWithoutExtension (file.Name); var dir = new List (count); for (int i = 0; i < count; ++i) { index_offset += 4; - var entry = new Entry { + var entry = new PackedEntry { Name = string.Format ("{0}#{1:D4}", base_name, i), + Type = default_type, Offset = offset, }; offset = file.View.ReadUInt32 (index_offset); @@ -74,12 +80,35 @@ namespace GameRes.Formats.Triangle return null; dir.Add (entry); } - foreach (var entry in dir) + if (string.IsNullOrEmpty (default_type)) { - uint signature = file.View.ReadUInt32 (entry.Offset); - entry.ChangeType (AutoEntry.DetectFileType (signature)); + foreach (var entry in dir) + { + uint signature = file.View.ReadUInt32 (entry.Offset); + entry.ChangeType (AutoEntry.DetectFileType (signature)); + } } return new ArcFile (file, this, dir); } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var pent = entry as PackedEntry; + if (null == pent) + return base.OpenEntry (arc, entry); + if (!pent.IsPacked) + { + if (!arc.File.View.AsciiEqual (entry.Offset, "fACE")) + return base.OpenEntry (arc, entry); + pent.IsPacked = true; + pent.UnpackedSize = arc.File.View.ReadUInt32 (entry.Offset+4) ^ 0x65641538; + } + using (var input = arc.File.CreateStream (entry.Offset+8, entry.Size-8)) + { + var data = new byte[pent.UnpackedSize]; + TriFormat.Unpack (input, data); + return new BinMemoryStream (data, entry.Name); + } + } } } diff --git a/ArcFormats/Triangle/ImageTRI.cs b/ArcFormats/Triangle/ImageTRI.cs index f323b80b..8177ac40 100644 --- a/ArcFormats/Triangle/ImageTRI.cs +++ b/ArcFormats/Triangle/ImageTRI.cs @@ -83,7 +83,7 @@ namespace GameRes.Formats.Triangle throw new System.NotImplementedException ("TriFormat.Write not implemented"); } - void Unpack (IBinaryStream input, byte[] output) + internal static void Unpack (IBinaryStream input, byte[] output) { int dst = 0; byte key = 0x7F;