From 7213e8d61e2f428e4a59db3240af4fd5a40bbb29 Mon Sep 17 00:00:00 2001 From: morkt Date: Fri, 21 Aug 2015 02:22:29 +0400 Subject: [PATCH] (PacOpener): decompress CMP1-compressed scripts. --- ArcFormats/Properties/AssemblyInfo.cs | 4 +-- ArcFormats/RiddleSoft/ArcPAC.cs | 38 ++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/ArcFormats/Properties/AssemblyInfo.cs b/ArcFormats/Properties/AssemblyInfo.cs index 50e45c8e..d01fe814 100644 --- a/ArcFormats/Properties/AssemblyInfo.cs +++ b/ArcFormats/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion ("1.1.9.400")] -[assembly: AssemblyFileVersion ("1.1.9.400")] +[assembly: AssemblyVersion ("1.1.9.401")] +[assembly: AssemblyFileVersion ("1.1.9.401")] diff --git a/ArcFormats/RiddleSoft/ArcPAC.cs b/ArcFormats/RiddleSoft/ArcPAC.cs index eb8fac9e..32b09b98 100644 --- a/ArcFormats/RiddleSoft/ArcPAC.cs +++ b/ArcFormats/RiddleSoft/ArcPAC.cs @@ -29,6 +29,7 @@ using System.Text; using System.Collections.Generic; using System.ComponentModel.Composition; using GameRes.Formats.Strings; +using System; namespace GameRes.Formats.Riddle { @@ -49,16 +50,30 @@ namespace GameRes.Formats.Riddle public override ArcFile TryOpen (ArcView file) { int count = file.View.ReadInt32 (4); - if (count <= 0 || count > 0xfffff) + if (!IsSaneCount (count)) return null; - long index_offset = 8; - uint base_offset = (uint)(count*0x20 + 8); + uint index_offset = 8; + long base_offset = count*0x20 + 8; var dir = new List (count); for (int i = 0; i < count; ++i) { string name = file.View.ReadString (index_offset, 0x10); - var entry = FormatCatalog.Instance.CreateEntry (name); uint size = file.View.ReadUInt32 (index_offset+0x10); + var entry = new PackedEntry { Name = name }; + if (name.EndsWith (".scp", StringComparison.InvariantCultureIgnoreCase)) + { + entry.Type = "script"; + entry.IsPacked = size > 12 && file.View.AsciiEqual (index_offset+0x14, "CMP1"); + } + else + { + entry.Type = FormatCatalog.Instance.GetTypeFromName (name); + entry.IsPacked = false; + } + if (entry.IsPacked) + entry.UnpackedSize = file.View.ReadUInt32 (index_offset+0x18); + else + entry.UnpackedSize = size; entry.Offset = base_offset; entry.Size = size; if (!entry.CheckPlacement (file.MaxOffset)) @@ -69,5 +84,20 @@ namespace GameRes.Formats.Riddle } return new ArcFile (file, this, dir); } + + public override Stream OpenEntry (ArcFile arc, Entry entry) + { + var pentry = entry as PackedEntry; + if (null == pentry || !pentry.IsPacked + || !arc.File.View.AsciiEqual (entry.Offset, "CMP1")) + return arc.File.CreateStream (entry.Offset, entry.Size); + int unpacked_size = arc.File.View.ReadInt32 (entry.Offset+4); + using (var input = arc.File.CreateStream (entry.Offset+12, entry.Size-12)) + { + var reader = new CmpReader (input, (int)entry.Size, unpacked_size); + reader.Unpack(); + return new MemoryStream (reader.Data); + } + } } }